Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ASIHTTPRequest: a (potentially) carrier-specific issue whilst uploading data / server receives blank POST

Very strange (to me) problem when uploading files to a server using ASIFormDataRequest.

When uploading over WiFi, there's no problem, I can upload just fine. When uploading over 3G using O2 UK as the carrier, there's no problem either. When I upload using the exact same code the same server using Vodafone UK, the HTTP request arrives at the server with the POST content stripped out. If I try the same request but without uploading an image (just add test=>yes as some POST data), then this will work, but if I have test=>yes and attach a file, it arrives at the server with the POST data stripped out.

NB I'm using the latest version of ASIHTTPRequest on an iPhone 4S, and it's reproducible on several other phones using Vodafone UK and O2 UK variously.

So, I'm pointing my objc code at the following PHP script, which just prints out what it's received:

<?php
error_reporting(E_ALL);
ini_set("display_startup_errors","1");
ini_set("display_errors","1");

echo "FILES: ".print_r($_FILES,true);
echo "POST: ".print_r($_POST,true);
echo "GET: ".print_r($_GET,true);

die('done.');

The obj-c code I'm using is:

- (void)viewDidLoad
{
    [super viewDidLoad];

    NSURL *url = [NSURL URLWithString: @"http://myserver.com/debugger.php"];
    ASIFormDataRequest *request = [[ASIFormDataRequest alloc] initWithURL:url];

    [request setDelegate:self];
    [request setDidFinishSelector:@selector(networkRequestSuccess:)];
    [request setDidFailSelector:@selector(networkRequestFailure:)];
    [request setTimeOutSeconds:120];

    NSString *filePath = [[NSBundle mainBundle] pathForResource:@"smalltestimage" ofType:@"png"];  
    NSData *myData = [NSData dataWithContentsOfFile:filePath];  
    if (myData) {  
        [request addPostValue:@"Yes" forKey:@"Test"];
        [request addData:myData withFileName:@"smalltestimage.png" andContentType:@"image/png" forKey:@"photos"];
        [request startSynchronous];
    } 
    else{
        NSLog(@"File not found..");
    }

    [request autorelease];
}

- (void)networkRequestSuccess:(ASIHTTPRequest *)request{

    NSLog(@"Success Response: %@", [request responseString]);

}

- (void)networkRequestFailure:(ASIHTTPRequest *)request{
    NSLog(@"Fail Response: %@", [request responseString]);
}

If I run the app with WiFi enabled, or on O2 UK, I get the following response:

Success Response: FILES: Array
(
    [photos] => Array
        (
            [name] => smalltestimage.png
            [type] => image/png
            [tmp_name] => /tmp/phpYTdw4g
            [error] => 0
            [size] => 13211
        )

)
POST: Array
(
    [Test] => Yes
)
GET: Array
(
)
done.

So far so good!

If I retry with WiFi disabled, but with near-full 3G signal on Vodafone UK:

Success Response: FILES: Array
(
)
POST: Array
(
)
GET: Array
(
)
done.

Very odd: not only is the file now missing, but the 'test' POST value is also missing. However, no errors from either PHP or ASIHTTPRequest.

Can anyone shed any light for me? If Vodafone are manipulating stuff like this, why is it not more well known? The only other person I can find reporting a similar problem posted a year ago.

If I comment out the [request addData] line, then it works perfectly:

Success Response: FILES: Array
(
)
POST: Array
(
    [Test] => Yes
)
GET: Array
(
)
done.

Very strange. I've been trying to get this working all day but no luck so far. I'd be very grateful if anyone could shed any light, or even is just having the same issue.

like image 703
Ian Dundas Avatar asked Nov 19 '11 15:11

Ian Dundas


2 Answers

Wow. That's crazy. It sounds like a broken HTTP proxy to me. Any chance you could use HTTPS to try and prevent the proxy from messing with your data?

You might also try defining DEBUG_REQUEST_STATUS (used in ASIHTTPRequest.m) to see if, for example, you're getting a redirect which is dropping your POST body or something.

like image 161
Jesse Rusak Avatar answered Nov 15 '22 06:11

Jesse Rusak


It's known that a number of mobile carriers have proxies that break things in certain situations.

In the old days (say, circa 2002), almost every carrier had a proxy that would apply very severe lossy compression to most images and sometimes also compress javascript/html/css - the idea was to try and make the web usable on GPRS connections. This was almost always implemented as a transparent http proxy.

In the case of vodafone UK (and I believe most carriers that do this) they generally have one APN that has this behaviour, and one that doesn't. On Vodafone I believe the 'wap' VPN has the compressing behaviour, but the 'web' one doesn't - but it's been a while since I had to deal with this so I may be misremember and/or it may have changed since. Sometimes they also behave differently on a 3G connections vs a GPRS one.

Of course, none of this explains why it's dropping the image you're uploading, that doesn't make any sense at all as it won't save any bandwidth on the GPRS/3G side. It could be you're somehow triggering a bug in the proxy. Uploading pngs from a mobile phone is probably a bit unusual, which may explain why there aren't more reports of problems - I would bet that 99.9% of image uploads from a mobile phone are jpegs.

Using https, as Jesse already suggested, is a good workaround. As images are one of the things the proxies tend to trigger off, not tagging the content type as image/png might help, but I'm not sure that can really be recommended.

like image 2
JosephH Avatar answered Nov 15 '22 05:11

JosephH