Re: NSURLConnection upload to iDisk works with iPhone OS 2.x but fails on 3.x
Re: NSURLConnection upload to iDisk works with iPhone OS 2.x but fails on 3.x
- Subject: Re: NSURLConnection upload to iDisk works with iPhone OS 2.x but fails on 3.x
- From: Sergey Shapovalov <email@hidden>
- Date: Sun, 27 Sep 2009 13:25:34 +0400
Hello again.
It looks like I've got more info on the issue. I've performed some
additional investigation and figured out that if you substitute the
lines
NSInputStream* stream = [NSInputStream inputStreamWithFileAtPath:
filePath];
[request setHTTPBodyStream: stream];
with
NSData* outgoingData = [str dataUsingEncoding: NSUTF8StringEncoding];
[request setHTTPBody: outgoingData];
then the code works perfectly with both 2.2.1 and 3.0. However, the
original code works on 2.2.1 but fails on 3.0 and 3.1.
This makes me think that chunked upload from stream via
NSURLConnection has been broken in iPhone OS 3.x. Unfortunately, in
real life I can't upload my file by using setHTTPBody instead of
setHTTPBodyStream because it's too big to store in memory.
So, if anybody sees a mistake in what I'm doing, please tell me.
Otherwise, I'll post a bug to radar... However, that won't help me
much because this issue a stopper for the new version of my app which
I'm preparing for the App Store now.
Best regards,
Sergey.
On Sep 27, 2009, at 12:28 AM, Sergey Shapovalov wrote:
Hello.
I'm using a very simple code snippet to upload a small file to my
MobileMe iDisk. The problem is that it perfectly works with iPhone
OS 2.2.1, but fails on 3.0. Now I'm trying to figure out whether
that's a bug in iPhone OS 3.0, or I am doing something wrong and
2.2.1 is just more tolerant to my mistakes than 3.0.
Here is my code.
static NSString* kMobileMeUserName = ...;
static NSString* kMobileMePassword = ...;
- (void)upload
{
NSString* tmpFolderPath = [NSHomeDirectory()
stringByAppendingPathComponent: @"tmp"];
NSString* filePath = [tmpFolderPath stringByAppendingPathComponent:
@"test.txt"];
NSString* str = @"1234567890";
[str writeToFile: filePath atomically: NO encoding:
NSUTF8StringEncoding error: NULL];
NSURL* url = [NSURL URLWithString: [NSString stringWithFormat: @"https://idisk.me.com/
%@/Documents/test.txt", kMobileMeUserName]];
NSMutableURLRequest* request = [NSMutableURLRequest requestWithURL:
url];
[request setHTTPMethod: @"PUT"];
NSDictionary* fileAttr = [[NSFileManager defaultManager]
fileAttributesAtPath: filePath traverseLink: YES];
unsigned long long uploadSize = [fileAttr fileSize];
if ( uploadSize > 0 )
{
NSNumber* num = [NSNumber numberWithUnsignedLongLong: uploadSize];
[request setValue: [num stringValue] forHTTPHeaderField: @"Content-
Length"];
NSInputStream* stream = [NSInputStream inputStreamWithFileAtPath:
filePath];
[request setHTTPBodyStream: stream];
[NSURLConnection connectionWithRequest: request delegate: self];
}
}
In my controller (which is registered as NSURLConnection delegate) I
implement all of NSURLConnection delegate methods and just call
NSLog from them so that I can see in the log how the operation
performs. I return YES for canAuthenticateAgainstProtectionSpace and
from connectionShouldUseCredentialStorage. When I receive
authentication challenge, I act like this:
- (void)connection:(NSURLConnection*)connection
didReceiveAuthenticationChallenge:
(NSURLAuthenticationChallenge*)challenge
{
NSLog(@"didReceiveAuthenticationChallenge");
NSURLCredential* cred = [NSURLCredential credentialWithUser:
kMobileMeUserName
password: kMobileMePassword
persistence: NSURLCredentialPersistenceNone];
[challenge.sender useCredential: cred forAuthenticationChallenge:
challenge];
}
Now, here is what I see in console when I run this code with 2.2.1:
willSendRequest
connectionShouldUseCredentialStorage
didSendBodyData
didReceiveAuthenticationChallenge
didSendBodyData
didReceiveResponse
connectionDidFinishLoading
Everything works all right, and I can find the test.txt file (10
bytes in size) on my iDisk in the Documents folder.
And this is how the same code runs in 3.0:
willSendRequest
connectionShouldUseCredentialStorage
canAuthenticateAgainstProtectionSpace
didReceiveAuthenticationChallenge
didSendBodyData
canAuthenticateAgainstProtectionSpace
didReceiveAuthenticationChallenge
For some reason I receive authentication challenge for the second
time, and after that no more delegate methods are called. And the
test.txt file never appears on the iDisk. Moreover - I tried
deriving MyURLConnection from NSURLConnection and overriding init...
and dealloc in it; from there, I just call super methods and add
NSLog. This way I could see that the URL connection deallocs after
the second authentication challenge - without having called
connectionDidFinishLoading: or connection:didFailWithError: on the
delegate.
So, has anybody faced the same problem? Does anybody have an idea
concerning what may be going wrong? Should I post a bug report to
radar? Can anyone suggest a workaround?
Any ideas are very welcome! I can send a simple sample project
illustrating the problem on demand to anyone interested.
Best regards,
Sergey.
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden