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 (Cocoa-dev@lists.apple.com)

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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Reply via email to