I ran into a problem with my code after the company did a code scan.
The report showed that my code, where I try to do a web service POST request, has a vulnerability for XSS attacks.
I'm not very familiar with issues on security.
Can anyone point me at the right direction as to how to fix this security vulnerability?
Thanks alot.
My web service calls are to a CA trusted server, so I used:
- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge {
if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) {
SecTrustResultType result;
SecTrustEvaluate(challenge.protectionSpace.serverTrust, & result);
if(result == kSecTrustResultProceed || result == kSecTrustResultUnspecified) {
[challenge.sender useCredential:[NSURLCredential credentialForTrust: challenge.protectionSpace.serverTrust] forAuthenticationChallenge: challenge];
return;
to secure the connection.
The following code is where I compose my URL request.
Again, I don't have a lot of knowledge on the topic of security,
so any help would be appreciated!
- (BOOL)httpPostWithUrl:(NSString *)url headersAndValues:(NSDictionary *)headersAndValues delegate:(id)delegate
{
NSMutableString *bodyString = [[NSMutableString alloc] initWithString:#""];
for (NSString *key in [headersAndValues allKeys])
{
[bodyString appendString:[NSString stringWithFormat:#"%#=%#&", key, headersAndValues[key]]];
}
NSMutableURLRequest *urlRequest = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:url]
cachePolicy:NSURLRequestReloadIgnoringLocalCacheData
timeoutInterval:20.0f];
[urlRequest setHTTPMethod:#"POST"];
[urlRequest setValue:#"application/x-www-form-urlencoded" forHTTPHeaderField:#"content-type"];
if (bodyString.length)
{
NSString *requestBody = [bodyString substringToIndex:bodyString.length-1];
NSData *requestData = [requestBody dataUsingEncoding:NSUTF8StringEncoding allowLossyConversion:YES];
[urlRequest setHTTPBody:requestData];
if (!_connectionRunning)
{
NSURLConnection *connection =[[NSURLConnection alloc] initWithRequest:request delegate:self];
return YES;
}
else
{
// error
}
}
}
return NO;
}
I think that xss in this line:
[bodyString appendString:[NSString stringWithFormat:#"%#=%#&", key, headersAndValues[key]]];
You need to check key and headersAndValues[key] on invalid characters.
NSString *checkedKey = [self alphanumericStringFromString:checkedKey];
+ (NSString *)alphanumericString { // NSString category
NSCharacterSet *charactersToRemove = [[NSCharacterSet alphanumericCharacterSet] invertedSet];
NSString *trimmedReplacement = [[self componentsSeparatedByCharactersInSet:charactersToRemove] componentsJoinedByString:#""];
return trimmedReplacement;
}
Hope it helps you.
Related
I have a remote JavaScript file that I would like to load from WKWebView. The dev Website the JavaScript file is on requires Basic Auth in order to Access.
The JavaScript file needs needs to load as a result of a button.
In otherwords, I can't use the WKUserScript injectionTime options.
I have two code examples. Both of them only half work. I can't test if the auth works without the EvaluateJavascript working, and I can't test the EvaluateJavascript function without the Basic Auth working... so... using WKWebView * webView...
NSString *authStr = #"username:password";
NSData *authData = [authStr dataUsingEncoding:NSUTF8StringEncoding];
NSString *authValue = [NSString stringWithFormat: #"Basic %#",[authData base64EncodedStringWithOptions:0]];
NSURL* jsURL = [NSURL URLWithString:#"http://dev.xxxx.com/js/xxxxx.js"];
NSMutableURLRequest* request = [NSMutableURLRequest requestWithURL:jsURL];
[request setValue:authValue forHTTPHeaderField:#"Authorization"];
[_webView loadRequest:request];
I can see the javascript in the webView window, but it is not being evaluated.
Then I have this other strategy:
- (void)handleButton {
NSURL* jsURL = [NSURL URLWithString:#"http://dev.xxxx.com/js/xxxxx.js"];
_scriptString = [NSString stringWithContentsOfURL:jsURL usedEncoding:NSUTF8StringEncoding error:nil];
}
-(void)webView:(WKWebView *)webView didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition, NSURLCredential *))completionHandler{
if (challenge.previousFailureCount == 0){
NSURLCredentialPersistence persistence = NSURLCredentialPersistenceForSession;
NSURLCredential *credential = [NSURLCredential credentialWithUser:#"username" password:#"password" persistence:persistence];
completionHandler(NSURLSessionAuthChallengeUseCredential,credential);
NSLog(#"in Auth");
}
else{
NSLog(#"%s: challenge.error = %#", __FUNCTION__, challenge.error);
completionHandler(NSURLSessionAuthChallengeCancelAuthenticationChallenge, nil);
}
}
- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation {
NSLog(#"navigation complete");
NSLog(#"scriptString %#", _scriptString); //Says UNAUTHORIZED
if ([_scriptString length] > 0) {
[_webView evaluateJavaScript:_scriptString completionHandler:^(NSString *result, NSError *evaluateError) {
if (result == nil) {
NSLog(#"no go dude: %#", evaluateError);
return;
}
NSData *data = [result dataUsingEncoding:NSUTF8StringEncoding];
NSLog(#"i think it worked: #%", data);
}];
}
}
Any help would be greatly appreciated!!
I loaded the javascript URL in Safari on my iPhone, and entered the basic auth username and password into the popup.
Then, this is the code that worked:
NSURL *jsURL = [NSURL URLWithString:#"http://username:password#dev.xxxx.com/js/xxxxxx.js"];
NSString *injectedJS = [NSString stringWithContentsOfURL:jsURL encoding:NSUTF8StringEncoding error:nil];
[_webView evaluateJavaScript:injectedJS completionHandler:nil];
I am very new to IOS development, I wish to know if it possible to ignore ssl validation for "NSMutableURLRequest" class. If so please guide me. I have ignored the SLL validation through delegate by overriding
- (BOOL)connection:(NSURLConnection *)connection canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace;
I wish to ignore the SLL validation without Delegate.
my code snippet
NSString *username = _userName.text;
NSString *password = _password.text;
//HTTP Basic Authentication
NSString *authenticationString = [NSString stringWithFormat:#"%#:%#", username, password];
NSData *authenticationData = [authenticationString dataUsingEncoding:NSUTF8StringEncoding];
NSString *authenticationValue = [authenticationData base64Encoding];
//Set up your request
NSMutableURLRequest *request1 = [[NSMutableURLRequest alloc] initWithURL:url];
// Set your user login credentials
[request1 setValue:[NSString stringWithFormat:#"Basic %#", authenticationValue] forHTTPHeaderField:#"Authorization"];
// Send your request asynchronously
[NSURLConnection sendAsynchronousRequest:request1 queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *responseCode, NSData *responseData, NSError *responseError) {
if ([responseData length] > 0 && responseError == nil){
//logic here
NSString* newStr = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];
NSLog(#"RESPONSE WITHOUT DELEGATE: %#",newStr);
[[ApplicationStorage applicationStorage] setUserName:_userName.text];
[[ApplicationStorage applicationStorage] setUserName:_password.text];
[[ApplicationStorage applicationStorage] setUserName:_serverAdd.text];
}}];
Thanks
Amith
I think this has been answered before. You can try to add this to your AppDelegate.m, after #end
#if DEBUG
#implementation NSMutableURLRequest (NSURLRequestWithIgnoreSSL)
+ (BOOL)allowsAnyHTTPSCertificateForHost:(NSString *)host
{
return YES;
}
#end
#endif
My server provide several authentication methods: NTLM and digest.
My iOS client won't handle the NTLM authentication, so I implement the connection:willSendRequestForAuthenticationChallenge: delegate to reject the NTLM, then use correct credential only for the digest authentication challenge.
Everything works fine on iOS 7 so far.
But on iOS 8, I found a weird behavior:
the connection:willSendRequestForAuthenticationChallenge: delegate won't be called at most time (95%)!!
I got this error instead:
Error: Error Domain=NSPOSIXErrorDomain Code=54 "The operation couldn’t be completed. Connection reset by peer"
UserInfo=0x16520fb0 {_kCFStreamErrorCodeKey=54,
NSErrorPeerAddressKey=<CFData 0x16682e40 [0x2f752440]>{length = 16, capacity = 16, bytes = 0x10020d7eac12780b0000000000000000},
NSErrorFailingURLKey=http://SERVER_IP:SERVER_PORT/Tunnel/Message.aspx,
NSErrorFailingURLStringKey=http://SERVER_IP:SERVER_PORT/Tunnel/Message.aspx,
_kCFStreamErrorDomainKey=1}
Only 5% time the delegate is correctly called and work as usual.
Below shows how I send my request to server and handle the authentication challenge:
- (void)postRequest
{
NSString *IP = SERVER_IP;
int port = SERVER_PORT;
NSString *url = [NSString stringWithFormat:#"http://%#:%d/Tunnel/Message.aspx", IP, port];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:url]];
[request setHTTPMethod:#"POST"];
[request setValue:#"application/xml" forHTTPHeaderField:#"Content-Type"];
NSString *xml = [NSString stringWithFormat:#"<?xml version=\"1.0\" encoding=\"UTF-8\"?><GetServerInfo></GetServerInfo>"];
[request setHTTPBody: [xml dataUsingEncoding:NSUTF8StringEncoding]];
NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
}
- (void)connection:(NSURLConnection *)connection willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
{
NSLog(#"%#", challenge.protectionSpace);
if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodHTTPDigest])
{
if ([challenge previousFailureCount] == 0)
{
[[challenge sender] useCredential:[NSURLCredential credentialWithUser:USERNAME
password:PASSWORD
persistence:NSURLCredentialPersistenceNone]
forAuthenticationChallenge:challenge];
}
else
{
[[challenge sender] continueWithoutCredentialForAuthenticationChallenge:challenge];
}
}
else
{
[[challenge sender] rejectProtectionSpaceAndContinueWithChallenge:challenge];
}
}
Those code work on iOS 7, willSendRequestForAuthenticationChallenge get called several times during the authentication challenge, but not even called any once on iOS 8!
Could this be a bug of iOS 8 or something changed since iOS 8?
This happened to me when I was updating my iOS 7 app to iOS 8. We were using Oracle SOA as the middle ware and sunddenly it stopped calling the delegate methods. Below worked for me in both iOS8 and iOS7. (With Xcode 6.1)
- (void) addBasicHTTPAuthenticationHeaders
{
NSString * wsUserName = #"userNameForWebService";
NSString * wsPassword = #"passwordForWebService";
NSString *authStr = [NSString stringWithFormat:#"%#:%#", wsUserName, wsPassword];
NSData *authData = [authStr dataUsingEncoding:NSASCIIStringEncoding];
NSString *authValue = [NSString stringWithFormat:#"Basic %#", [authData base64EncodedStringWithOptions:NSDataBase64EncodingEndLineWithCarriageReturn]];
[urlRequest setValue:authValue forHTTPHeaderField:#"Authorization"];
}
I have a little problem with my app. I want to send some http request asynchronously to server. I create this method:
- (void)sendHTTPRequest:(NSString *)urlString type:(NSString *)type idNegozio:(NSNumber *)idNegozio {
self.negozi = [[NSMutableArray alloc] init];
NSData *jsonData;
NSString *jsonString;
if ([type isEqualToString:#"shops"]) {
self.reqNeg = YES;
self.reqApp = NO;
...
jsonData = [NSJSONSerialization dataWithJSONObject:jsonDictionary options:0 error:nil];
jsonString = [[NSString alloc]initWithData:jsonData encoding:NSUTF8StringEncoding];
else if ([type isEqualToString:#"appointments"])
{
[self.loadingIconApp startAnimating];
self.reqNeg = NO;
self.reqApp = YES;
...
jsonData = [NSJSONSerialization dataWithJSONObject:jsonDictionary options:0 error:nil];
jsonString = [[NSString alloc]initWithData:jsonData encoding:NSUTF8StringEncoding];
NSString *requestString = [NSString stringWithFormat:urlString];
NSURL *url = [NSURL URLWithString:requestString];
NSMutableURLRequest *urlRequest = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestReturnCacheDataElseLoad timeoutInterval:30];
[urlRequest setHTTPMethod:#"POST"];
[urlRequest setHTTPBody: jsonData];
NSURLConnection * conn = [[NSURLConnection alloc] initWithRequest:urlRequest delegate:self];
[conn start];
}
and I use this methods for connection:
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
self.responseData = [[NSMutableData alloc] init];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
[self.responseData appendData:data];
}
- (NSCachedURLResponse *)connection:(NSURLConnection *)connection
willCacheResponse:(NSCachedURLResponse*)cachedResponse {
return nil;
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
if (self.reqNeg == YES) {
//here use the responseData for my first http request
}
if (self.reqApp == YES) {
//here use the responseData for second http request
}
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
}
but in this way only the first connection works and I can use the responseData. While, If I try to send other http request the method connectionDidFinishLoading doesn't work and other methods too.
Anyone have an idea??
If you want to use the async request one by one you can do that:
- (void)request1 {
NSString *requestString = #"your url here";
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
[NSURLConnection sendAsynchronousRequest:[[NSURLRequest alloc]initWithURL:[NSURL URLWithString: requestString]]
queue:queue
completionHandler:
^(NSURLResponse *response, NSData *data, NSError *error) {
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;
if (!error && httpResponse.statusCode >= 200 && httpResponse.statusCode <300) {
// call the request2 here which is similar to request 1
// your request2 method here
}
}];
}
hope this help you~ thank you~
Your code looks good to me. Here are my ideas:
Are you sure your second NSURLConnection is being created and sent out?
Maybe it's never being sent.
Are you calling your sendHTTPRequest:type:idNegozio: method with a different type while your second connection is still sent out?
You don't have a check at the beginning of the send function to make sure you're not already sending out a connection. Maybe your flags are being switched mid-connection.
The if statements in your didFinish method should probably be combined with an else. Just in case you wanted to fire off an 'app' connection after handling a 'neg' connection you don't accidentally fall through and try to handle the response twice.
Also, you don't have to explicitly call 'start' on an NSURLConnection unless you pass NO to the startImmediately: parameter in the constructor. That shouldn't cause a problem though.
I need to invoke an initial GET HTTP request with Basic Authentication. This would be the first time the request is sent to the server and I already have the username & password so there's no need for a challenge from the server for authorization.
First question:
Does NSURLConnection have to be set as synchronous to do Basic Auth? According to the answer on this post, it seems that you can't do Basic Auth if you opt for the async route.
Anyone know of any some sample code that illustrates Basic Auth on a GET request without the need for a challenge response? Apple's documentation shows an example but only after the server has issued the challenge request to the client.
I'm kind of new the networking portion of the SDK and I'm not sure which of the other classes I should use to get this working. (I see the NSURLCredential class but it seems that it is used only with NSURLAuthenticationChallenge after the client has requested for an authorized resource from the server).
I'm using an asynchronous connection with MGTwitterEngine and it sets the authorization in the NSMutableURLRequest (theRequest) like so:
NSString *authStr = [NSString stringWithFormat:#"%#:%#", [self username], [self password]];
NSData *authData = [authStr dataUsingEncoding:NSASCIIStringEncoding];
NSString *authValue = [NSString stringWithFormat:#"Basic %#", [authData base64EncodingWithLineLength:80]];
[theRequest setValue:authValue forHTTPHeaderField:#"Authorization"];
I don't believe this method requires going through the challenge loop but I could be wrong
Even the question is answered, I want to present the solution, which doesn't require external libs, I found in another thread:
// Setup NSURLConnection
NSURL *URL = [NSURL URLWithString:url];
NSURLRequest *request = [NSURLRequest requestWithURL:URL
cachePolicy:NSURLRequestUseProtocolCachePolicy
timeoutInterval:30.0];
NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
[connection start];
[connection release];
// NSURLConnection Delegates
- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge {
if ([challenge previousFailureCount] == 0) {
NSLog(#"received authentication challenge");
NSURLCredential *newCredential = [NSURLCredential credentialWithUser:#"USER"
password:#"PASSWORD"
persistence:NSURLCredentialPersistenceForSession];
NSLog(#"credential created");
[[challenge sender] useCredential:newCredential forAuthenticationChallenge:challenge];
NSLog(#"responded to authentication challenge");
}
else {
NSLog(#"previous authentication failure");
}
}
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
...
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
...
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
...
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
...
}
Here is a detailed answer with no 3rd party involved:
Please check here:
//username and password value
NSString *username = #“your_username”;
NSString *password = #“your_password”;
//HTTP Basic Authentication
NSString *authenticationString = [NSString stringWithFormat:#"%#:%#", username, password]];
NSData *authenticationData = [authenticationString dataUsingEncoding:NSASCIIStringEncoding];
NSString *authenticationValue = [authenticationData base64Encoding];
//Set up your request
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:#"http://www.your-api.com/“]];
// Set your user login credentials
[request setValue:[NSString stringWithFormat:#"Basic %#", authenticationValue] forHTTPHeaderField:#"Authorization"];
// Send your request asynchronously
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *responseCode, NSData *responseData, NSError *responseError) {
if ([responseData length] > 0 && responseError == nil){
//logic here
}else if ([responseData length] == 0 && responseError == nil){
NSLog(#"data error: %#", responseError);
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:nil message:#"Error accessing the data" delegate:nil cancelButtonTitle:#"Close" otherButtonTitles:nil];
[alert show];
[alert release];
}else if (responseError != nil && responseError.code == NSURLErrorTimedOut){
NSLog(#"data timeout: %#”, NSURLErrorTimedOut);
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:nil message:#"connection timeout" delegate:nil cancelButtonTitle:#"Close" otherButtonTitles:nil];
[alert show];
[alert release];
}else if (responseError != nil){
NSLog(#"data download error: %#”,responseError);
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:nil message:#"data download error" delegate:nil cancelButtonTitle:#"Close" otherButtonTitles:nil];
[alert show];
[alert release];
}
}]
Kindly let me know your feedback on this.
Thanks
If you don't want to import the whole of MGTwitterEngine and you aren't doing an asynchronous request
Then you can use
http://www.chrisumbel.com/article/basic_authentication_iphone_cocoa_touch
To base64 encode the Username and password
So replace
NSString *authValue = [NSString stringWithFormat:#"Basic %#", [authData base64EncodingWithLineLength:80]];
with
NSString *encodedLoginData = [Base64 encode:[loginString dataUsingEncoding:NSUTF8StringEncoding]];
after
you will need to include the following file
static char *alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
#implementation Base64
+(NSString *)encode:(NSData *)plainText {
int encodedLength = (((([plainText length] % 3) + [plainText length]) / 3) * 4) + 1;
unsigned char *outputBuffer = malloc(encodedLength);
unsigned char *inputBuffer = (unsigned char *)[plainText bytes];
NSInteger i;
NSInteger j = 0;
int remain;
for(i = 0; i < [plainText length]; i += 3) {
remain = [plainText length] - i;
outputBuffer[j++] = alphabet[(inputBuffer[i] & 0xFC) >> 2];
outputBuffer[j++] = alphabet[((inputBuffer[i] & 0x03) << 4) |
((remain > 1) ? ((inputBuffer[i + 1] & 0xF0) >> 4): 0)];
if(remain > 1)
outputBuffer[j++] = alphabet[((inputBuffer[i + 1] & 0x0F) << 2)
| ((remain > 2) ? ((inputBuffer[i + 2] & 0xC0) >> 6) : 0)];
else
outputBuffer[j++] = '=';
if(remain > 2)
outputBuffer[j++] = alphabet[inputBuffer[i + 2] & 0x3F];
else
outputBuffer[j++] = '=';
}
outputBuffer[j] = 0;
NSString *result = [NSString stringWithCString:outputBuffer length:strlen(outputBuffer)];
free(outputBuffer);
return result;
}
#end
Since NSData::dataUsingEncoding is deprecated (ios 7.0), you could use this solution:
// Forming string with credentials 'myusername:mypassword'
NSString *authStr = [NSString stringWithFormat:#"%#:%#", username, password];
// Getting data from it
NSData *authData = [authStr dataUsingEncoding:NSASCIIStringEncoding];
// Encoding data with base64 and converting back to NSString
NSString* authStrData = [[NSString alloc] initWithData:[authData base64EncodedDataWithOptions:NSDataBase64EncodingEndLineWithLineFeed] encoding:NSASCIIStringEncoding];
// Forming Basic Authorization string Header
NSString *authValue = [NSString stringWithFormat:#"Basic %#", authStrData];
// Assigning it to request
[request setValue:authValue forHTTPHeaderField:#"Authorization"];
If you are using GTMHTTPFetcher for your connection, basic authentication is fairly easy as well. You simply need to provide the credential to the fetcher before beginning the fetch.
NSString * urlString = #"http://www.testurl.com/";
NSURL * url = [NSURL URLWithString:urlString];
NSMutableURLRequest * request = [NSMutableURLRequest requestWithURL:url];
NSURLCredential * credential = [NSURLCredential credentialWithUser:#"username" password:#"password" persistence:NSURLCredentialPersistenceForSession];
GTMHTTPFetcher * gFetcher = [GTMHTTPFetcher fetcherWithRequest:request];
gFetcher.credential = credential;
[gFetcher beginFetchWithDelegate:self didFinishSelector:#selector(fetchCompleted:withData:andError:)];
Can you tell me what's the reason behind limiting the encoding line length to 80 in your example code? I thought that HTTP headers have a max length of something like 4k (or maybe some servers don't take anything longer than that). – Justin Galzic Dec 29 '09 at 17:29
It is not limiting to 80, it is an option of the method base64EncodingWithLineLength in NSData+Base64.h/m, where you can split your encoded string into multiple lines, which is useful for other application, such as nntp transmission. I believe 80 is chosen by the twitter engine author to be a length big enough to accommodate most user/password encoded result to one line.
You can use AFNetworking (it is opensource), here is code that worked for me. This code sends file with basic authentication. Just change url, email and password.
NSString *serverUrl = [NSString stringWithFormat:#"http://www.yoursite.com/uploadlink", profile.host];
NSMutableURLRequest *request = [[AFHTTPRequestSerializer serializer] requestWithMethod:#"POST" URLString:serverUrl parameters:nil error:nil];
NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:configuration];
// Forming string with credentials 'myusername:mypassword'
NSString *authStr = [NSString stringWithFormat:#"%#:%#", email, emailPassword];
// Getting data from it
NSData *authData = [authStr dataUsingEncoding:NSASCIIStringEncoding];
// Encoding data with base64 and converting back to NSString
NSString* authStrData = [[NSString alloc] initWithData:[authData base64EncodedDataWithOptions:NSDataBase64EncodingEndLineWithLineFeed] encoding:NSASCIIStringEncoding];
// Forming Basic Authorization string Header
NSString *authValue = [NSString stringWithFormat:#"Basic %#", authStrData];
// Assigning it to request
[request setValue:authValue forHTTPHeaderField:#"Authorization"];
manager.responseSerializer = [AFHTTPResponseSerializer serializer];
NSURL *filePath = [NSURL fileURLWithPath:[url path]];
NSURLSessionUploadTask *uploadTask = [manager uploadTaskWithRequest:request fromFile:filePath progress:^(NSProgress * _Nonnull uploadProgress) {
// This is not called back on the main queue.
// You are responsible for dispatching to the main queue for UI updates
dispatch_async(dispatch_get_main_queue(), ^{
//Update the progress view
LLog(#"progres increase... %# , fraction: %f", uploadProgress.debugDescription, uploadProgress.fractionCompleted);
});
} completionHandler:^(NSURLResponse *response, id responseObject, NSError *error) {
if (error) {
NSLog(#"Error: %#", error);
} else {
NSLog(#"Success: %# %#", response, responseObject);
}
}];
[uploadTask resume];