Andrey Chernukha
Andrey Chernukha

Reputation: 21808

Trying to upload a file to OneDrive from iOS. What's wrong with my request?

I'm trying to upload a file to OneDrive using BITS protocol. The documentation describes a request to be like this:

enter image description here

The complete documentation page is here:OneDrive Large File Uploads

Actually it deals with uploading files by chunks but since a size of chunk must be not greater than 60 MB I'm trying to upload a small file as a single chunck. Here's my code:

    NSString *path = [[NSBundle mainBundle] pathForResource:@"download" ofType:@"jpeg"];
    self.data      = [NSData dataWithContentsOfFile:path];

    NSString *boundary  = @"---------------------------14737809831466499882746641449";
    NSMutableData *body = [NSMutableData data];

    [body appendData:[[NSString stringWithFormat:@"--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
    [body appendData:[[NSString stringWithFormat:@"Content-Disposition: attachment; name=\"image\"; filename=\"image.jpg\"\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
    [body appendData:[@"Content-Type: application/octet-stream\r\n\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
    [body appendData:[NSData dataWithData:self.data]];
    [body appendData:[@"\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
    [body appendData:[[NSString stringWithFormat:@"--%@--\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];

    length = body.length;

    NSMutableURLRequest *urlRequest = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:self.urlString]];
    urlRequest.HTTPMethod           = @"POST";

    [urlRequest setValue:@"BITS_POST" forHTTPHeaderField:@"X-Http-Method-Override"];
    [urlRequest setValue:self.accessToken forHTTPHeaderField:@"Authorization"];
    [urlRequest setValue:self.sessionId forHTTPHeaderField:@"BITS-Session-Id"];
    [urlRequest setValue:@"Fragment" forHTTPHeaderField:@"BITS-Packet-Type"];
    [urlRequest setValue:[NSString stringWithFormat:@"%d", length] forHTTPHeaderField:@"Content-Length"];
    [urlRequest setValue:[NSString stringWithFormat:@"0-%d/%d", length - 1, length] forHTTPHeaderField:@"Content-Range"];

    urlRequest.HTTPBody = body;

    self.uploadConnection = [[NSURLConnection alloc] initWithRequest:urlRequest delegate:self startImmediately:YES];

Whatever I try I receive 400 error and BadArgument as X-ClientErrorCode. Parameters self.accessToken and self.sessionId are valid, they are just received from the SDK. I have no idea what's wrong there. Can anyone please help me? What might I be doing wrong?

Upvotes: 0

Views: 826

Answers (1)

Brad
Brad

Reputation: 4192

The issue was the "Content-Range" was incorrect - it needed to include "bytes" in front of the range.

Original Answer

It doesn't look like you're sending either the Create-Session request before the Fragment, nor the Close-Session request after the Fragment. You'll need to create the session before sending fragments even if you're only planning on sending a single one. If you know you'll only be sending a single fragment it's better to use a direct upload to avoid unnecessary round trips:

http://msdn.microsoft.com/en-US/library/dn659726.aspx#upload_a_file

Upvotes: 2

Related Questions