OAuthConsumer - 使用 OMutableURLRequest 将图像发送到服务器

发布于 2024-12-08 10:55:27 字数 2682 浏览 0 评论 0原文

我正在使用 Jon Crosby 的 OAuthConsumer 库 (Google 代码链接)

我已成功设置我的项目有一个访问&请求令牌/秘密以向服务器发出基本的授权 http 请求 (GET)。但是现在我需要创建一个将图像上传到服务器的调用...(POST)

据我所知,我需要自己定义整个 httpBody (如果我错了,请纠正我)。我在某处找到了一些示例代码,将数据附加到 httpBody,但我完全不知道我在做什么。我是这样做的:

// create url request
urlRequest = [[[OAMutableURLRequest alloc]  initWithURL:urlToServerGoesHere 
                                            consumer:authentication.consumer
                                            token:authentication.token
                                            realm:nil
                                            signatureProvider:nil] autorelease];
// apply http method on request
[urlRequest setHTTPMethod:@"POST"];

// define boundary and content-type of file in header of request
NSString* boundary = @"----IMAGE_UPLOAD";
NSString* contentType = [NSString stringWithFormat:@"multipart/form-data; boundary=%@",boundary];
[urlRequest setValue:contentType forHTTPHeaderField:@"Content-Type"];

// Create entire body
NSMutableData* body = [NSMutableData data];

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

[urlRequest setHTTPBody:body];

在上面的代码末尾应用 httpBody 时,OAMutableRequest 内部会引发异常。我想我做错了什么或者没有设置。它似乎与我没有使用的参数数组有关......?

*** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[NSArray objectAtIndex:]: index 1 beyond bounds [0 .. 0]' *** Call stack at first throw:(0   CoreFoundation                      0x00ddc5a9 __exceptionPreprocess + 185
1   libobjc.A.dylib                     0x00f30313 objc_exception_throw + 44
2   CoreFoundation                      0x00dd21cc -[__NSArrayI objectAtIndex:] + 236
3   TwooWrapper                         0x0000d310 -[OAMutableURLRequest parameters] + 610
4   TwooWrapper                         0x0000d45d -[OAMutableURLRequest _signatureBaseString] + 39
5   TwooWrapper                         0x0000c619 -[OAMutableURLRequest prepare] + 213
6   TwooWrapper                         0x0000c17c -[OADataFetcher 

有谁知道如何使用我正在使用的这个库通过 Oauth 上传文件的信息,或者有任何建议吗?将是一个很大的帮助!谢谢

I'm using the OAuthConsumer library by Jon Crosby (google code link)

I have successfully set up my project with a access & request token/secret to make basic authorized http requests with the server (GET). However now I need to create a call that uploads an image to the server...(POST)

As far as i've found out, i need to define the entire httpBody myself (correct me if i'm wrong). I found some sample code somewhere that appends data to the httpBody but I have absolutely no idea what i'm doing. I have done so like this:

// create url request
urlRequest = [[[OAMutableURLRequest alloc]  initWithURL:urlToServerGoesHere 
                                            consumer:authentication.consumer
                                            token:authentication.token
                                            realm:nil
                                            signatureProvider:nil] autorelease];
// apply http method on request
[urlRequest setHTTPMethod:@"POST"];

// define boundary and content-type of file in header of request
NSString* boundary = @"----IMAGE_UPLOAD";
NSString* contentType = [NSString stringWithFormat:@"multipart/form-data; boundary=%@",boundary];
[urlRequest setValue:contentType forHTTPHeaderField:@"Content-Type"];

// Create entire body
NSMutableData* body = [NSMutableData data];

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

[urlRequest setHTTPBody:body];

When applying the httpBody at the end of the code above, an exception is thrown inside the OAMutableRequest. I'm thinking there's something i'm doing wrong or haven't set. It seems to be related with the parameters array which i'm not using...?

*** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[NSArray objectAtIndex:]: index 1 beyond bounds [0 .. 0]' *** Call stack at first throw:(0   CoreFoundation                      0x00ddc5a9 __exceptionPreprocess + 185
1   libobjc.A.dylib                     0x00f30313 objc_exception_throw + 44
2   CoreFoundation                      0x00dd21cc -[__NSArrayI objectAtIndex:] + 236
3   TwooWrapper                         0x0000d310 -[OAMutableURLRequest parameters] + 610
4   TwooWrapper                         0x0000d45d -[OAMutableURLRequest _signatureBaseString] + 39
5   TwooWrapper                         0x0000c619 -[OAMutableURLRequest prepare] + 213
6   TwooWrapper                         0x0000c17c -[OADataFetcher 

Does anyone have some information on how to upload a file through Oauth with this library that i'm using, or any suggestions? would be a big help! thx

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

贵在坚持 2024-12-15 10:55:27

在摆弄代码的排序顺序和http请求的正文之后,我设法让它工作。
它是这样的:

// create URL from string
NSURL* url = [[NSURL alloc] initWithString:path];

// create url request
urlRequest = [[[OAMutableURLRequest alloc]  initWithURL:url 
                                            consumer:authentication.consumer
                                            token:authentication.token
                                            realm:nil
                                            signatureProvider:nil] autorelease];
[urlRequest prepare];
[urlRequest setHTTPMethod:@"POST"];

// define boundary and content-type of file in header of request
NSString* boundary = @"----IMAGE_UPLOAD";
NSString* contentType = [NSString stringWithFormat:@"multipart/form-data; boundary=%@",boundary];
[urlRequest setValue:contentType forHTTPHeaderField:@"Content-Type"];

// Create entire body
NSMutableData* dataRequestBody = [NSMutableData data];

[dataRequestBody appendData:[[NSString stringWithFormat:@"--%@\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[dataRequestBody appendData:[@"Content-Disposition: form-data; name=\"image\"; filename=\"upload.jpg\"\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
[dataRequestBody appendData:[@"Content-Type: image/jpg\r\n\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
[dataRequestBody appendData:[NSData dataWithData:imageData]];
[dataRequestBody appendData:[@"\r\n" dataUsingEncoding:NSUTF8StringEncoding]];

// add 'type' parameter to request body
[dataRequestBody appendData:[[NSString stringWithFormat:@"--%@\r\nContent-Disposition: form-data; name=\"type\"\r\n\r\npublic\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];

// Write end-boundary!
[dataRequestBody appendData:[[NSString stringWithFormat:@"--%@--\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];

[urlRequest setHTTPBody:dataRequestBody];

// write content length of body in header!
[urlRequest setValue:[[NSNumber numberWithInt:[dataRequestBody length]] stringValue] forHTTPHeaderField:@"Content-Length"];

// do call
dataFetcher = [[OADataFetcher alloc]init];
[dataFetcher fetchDataWithRequest:urlRequest delegate:self didFinishSelector:@selector(onApiSuccess:rawData:) didFailSelector:@selector(onApiFail:rawData:)];

我还添加了 2 行代码,以向名为“type”、值为“public”的 httpbody 添加一个额外参数。如果您查看正在添加的数据,首先插入边界,然后插入一些 http 协议胡言乱语(不要忘记 \n\r,这很重要)并以边界结束以标记参数的结尾。

同样重要的是,将正文内容的长度写入 http 标头“Content-Length”,否则请求将不会发送任何数据。

希望这对某人有帮助!

After fiddling around with sort order of the code and the body of the http request I managed to make it work.
Here's what it looks like:

// create URL from string
NSURL* url = [[NSURL alloc] initWithString:path];

// create url request
urlRequest = [[[OAMutableURLRequest alloc]  initWithURL:url 
                                            consumer:authentication.consumer
                                            token:authentication.token
                                            realm:nil
                                            signatureProvider:nil] autorelease];
[urlRequest prepare];
[urlRequest setHTTPMethod:@"POST"];

// define boundary and content-type of file in header of request
NSString* boundary = @"----IMAGE_UPLOAD";
NSString* contentType = [NSString stringWithFormat:@"multipart/form-data; boundary=%@",boundary];
[urlRequest setValue:contentType forHTTPHeaderField:@"Content-Type"];

// Create entire body
NSMutableData* dataRequestBody = [NSMutableData data];

[dataRequestBody appendData:[[NSString stringWithFormat:@"--%@\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[dataRequestBody appendData:[@"Content-Disposition: form-data; name=\"image\"; filename=\"upload.jpg\"\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
[dataRequestBody appendData:[@"Content-Type: image/jpg\r\n\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
[dataRequestBody appendData:[NSData dataWithData:imageData]];
[dataRequestBody appendData:[@"\r\n" dataUsingEncoding:NSUTF8StringEncoding]];

// add 'type' parameter to request body
[dataRequestBody appendData:[[NSString stringWithFormat:@"--%@\r\nContent-Disposition: form-data; name=\"type\"\r\n\r\npublic\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];

// Write end-boundary!
[dataRequestBody appendData:[[NSString stringWithFormat:@"--%@--\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];

[urlRequest setHTTPBody:dataRequestBody];

// write content length of body in header!
[urlRequest setValue:[[NSNumber numberWithInt:[dataRequestBody length]] stringValue] forHTTPHeaderField:@"Content-Length"];

// do call
dataFetcher = [[OADataFetcher alloc]init];
[dataFetcher fetchDataWithRequest:urlRequest delegate:self didFinishSelector:@selector(onApiSuccess:rawData:) didFailSelector:@selector(onApiFail:rawData:)];

I also added 2 lines of code to add an extra parameter to the httpbody named 'type' with value 'public'. If you look at the data that's being added, fist the boundary is inserted, then some http protocol mumbo jumbo (don't forget the \n\r which are important) and finish with the boundary to mark the end of the parameter.

Also important is to write the length of the content of your body to the http header 'Content-Length', otherwise the request won't send any data.

Hope this helps someone!

趁微风不噪 2024-12-15 10:55:27

您在设置正文后调用 [urlRequestprepare] 吗?

在设置主体之前调用prepare。这是库中的一个错误/错误功能,因为它期望主体具有 foo=bar&firble=mumble 这样的参数,所以如果你的主体看起来不像那样,它就会崩溃。

Are you calling [urlRequest prepare] after setting the body?

Call prepare before setting the body. It's a bug/misfeature in the library, in that it is expecting the body to have parameters like foo=bar&firble=mumble, so if your body doesn't look like that it will crash.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文