Python 服务器在超时后收到来自 iOS 的 POST 请求数据

Python server receives POST request data from iOS after it has timed out

我有一个 iOS 应用程序,可以像这样发出 POST 请求和上传文件。在另一边,我有一个 Python 服务器在等待。

我面临的问题是,当 iOS 应用程序到达它应该发送请求的部分时,它会停止。据我所知,请求发送方法的某些部分有效,因为服务器收到 POST 调用,但随后停在那里。在请求超时或我停止执行应用程序之前,它不会继续。之后服务器正常运行,奇怪的是它以某种方式获取了所有数据并可以按设计运行。同步和异步都是一样的,无论是模拟器还是真机。

这是 Objective-C 处理请求的部分

// Get the image before we start building the request
    UIImage *image = [[PageViewControllerData sharedInstance] photoAtIndex:self.startingIndex];
    NSData *temp = UIImageJPEGRepresentation(image, 0.8);

    // The request with URL
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"address-to-the-server"]];
    request.HTTPMethod = @"POST";

    // Boundary generation
    NSString *boundary = @"----block-end";

    // Data size
    //NSString *postLength = [NSString stringWithFormat:@"%d", [temp length]];
    //NSLog(@"%@", postLength);

    // Content type
    NSString *contentType = [NSString stringWithFormat:@"multipart/form-data; boundary=%@", boundary];
    //[request setValue:postLength forHTTPHeaderField:@"Content-Length"]; // not necessary as it's done automatically
    [request addValue:contentType forHTTPHeaderField:@"Content-Type"];

    // Request's body building
    NSMutableData *body = [NSMutableData data];

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

    // Attach the body to the request
    [request setHTTPBody:body];

    NSLog(@"Sending data.");

    // Create request parameters
    NSURLResponse *response = nil;
    NSError *error = nil;

    // and fire the request
    NSData *returnData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];

这是 python 服务器代码的一部分:

def do_POST(self):

    print("POST method called")

    form = cgi.FieldStorage(fp=self.rfile, headers=self.headers,environ=
    {'REQUEST_METHOD':'POST','CONTENT_TYPE':self.headers['Content-Type'],})

    print("Form read")
    ....

我使用的设备是iPhone 4 (7.1.2)。在模拟器上,我尝试了 iPhone 4s 和 iPhone 6。服务器位于 VirtualBox 的 Ubuntu 环境中。

在服务器端,显示第一个打印消息,第二个不显示。第二个在请求超时或我停止程序执行后出现。

如果你们中有人考虑过 Content-Length 问题,那么可能不是这样,因为如果我不考虑,它会自动应用。是的,我尝试自己应用它,它没有任何改变。

服务器已通过常规浏览器进行了无数次测试,因为它能够分发一种特殊的表单,可以上传图片并且运行良好。

有什么想法可能会使请求保持在 iOS 上吗?

好的,终于修好了。

很明显,最后一个边界线必须在边界字符串之后有一个额外的“--”,以向服务器发出信号,表明所有数据已发送完毕,没有其他数据了。

基本上是这样的:

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

必须这样

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

(注意最后一行在边界字符串之后有两个额外的“--”。

我在执行此操作时遵循了多个示例,其中 none 个示例都有。这是 example guide。 whosebug.com 上也有很多例子,至少我碰巧看到的都没有这个。我想随着时间的推移有些东西发生了变化(查看该指南的日期),现在这成为必需的部分。

感谢我的同学猜到了这个问题。