2010-12-08 10 views
5

Estoy usando NSURLConnection para hacer un POST asíncrono HTTPS a nuestro servicio web para cargar un archivo jpg. Funciona bien la mayor parte del tiempo.HTTPS POST desde iPhone usando NSURLConnection se bloquea para cierto rango de tamaño de archivo

Pero cuando el cuerpo del mensaje está entre 196609 y 196868 bytes (inclusive), la conexión se cuelga después de que el archivo se haya cargado al 100% (didSendBodyData me dice que es 100% enviado). Luego, después de 5 minutos, la conexión expira con el mensaje "La conexión de red se perdió". Los tamaños de archivos más grandes y más pequeños funcionan. Probé esto al limitar el tamaño del archivo que agregué al cuerpo de la publicación.

La longitud del contenido se está configurando correctamente. Vea el código a continuación.

La carga se ve bien cuando cargo en netcat a través de HTTP. Todo el cuerpo del mensaje se transmite. Pero sospecho que algo va mal debido al cifrado SSL, como el almacenamiento en búfer de un marco de bloque cifrado SSL.

¿Hay algún error en el código SSL del iPhone que haga que no se cargue todo el cuerpo de la publicación aunque esté informando de que sí o de algo más?

Aquí está la sección donde establezco la longitud del contenido y anexo el archivo al cuerpo POST de varias partes. Puedes ver que estoy limitando el tamaño del archivo manualmente, para probar.

NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:nsurl]; 
[request setHTTPMethod:@"POST"]; 
[request setTimeoutInterval:1]; 
[request addValue:@"close" forHTTPHeaderField: @"Connection"]; 

// Add headers and POST information 
NSLog(@"Posting file."); 
NSString *stringBoundary = [NSString stringWithString:@"0xKhTmLbOuNdArY"]; 
NSString *contentType = [NSString stringWithFormat:@"multipart/form-data; boundary=%@",stringBoundary]; 
[request addValue:contentType forHTTPHeaderField: @"Content-Type"]; 
NSMutableData *postBody = [NSMutableData data]; 

...

[postBody appendData:[[NSString stringWithFormat:@"--%@\r\n",stringBoundary] dataUsingEncoding:NSUTF8StringEncoding]]; 
[postBody appendData:[[NSString stringWithString:@"Content-Disposition: form-data; name=\"uploadFile\"; filename=\"upload.jpg\"\r\n"] dataUsingEncoding:NSUTF8StringEncoding]]; 
[postBody appendData:[[NSString stringWithString:@"Content-Type: image/jpg\r\n\r\n"] dataUsingEncoding:NSUTF8StringEncoding]]; 
NSLog(@"file size...%d", [uploadFile length]); 
//[postBody appendData:uploadFile]; 
[postBody appendData:[NSData dataWithBytes: [uploadFile bytes] length: 196099]]; 
[postBody appendData:[[NSString stringWithFormat:@"\r\n--%@--\r\n",stringBoundary] dataUsingEncoding:NSUTF8StringEncoding]]; 
[request setHTTPBody:postBody]; 
[request setValue:[NSString stringWithFormat:@"%d", [postBody length]] forHTTPHeaderField:@"Content-Length"]; 
NSLog(@"Uploaded POST size: %d", [postBody length]); 

Respuesta

1

he siguiente código que se prueba el 30-40 MB de archivos, y nunca se cuelga. Se ve casi similar a su código, sin embargo, ¿está seguro de que no es su scrip del lado del servidor que puede estar esperando algo?

url = [NSURL URLWithString:u]; 

NSData* d = [self data]; 

request = [NSMutableURLRequest requestWithURL:url]; 
[request setTimeoutInterval: 2000 ]; 
[request setHTTPMethod:@"POST"]; 
[request setValue: 
[NSString stringWithFormat:@"multipart/form-data; boundary=%@", BOUNDRY] 
forHTTPHeaderField:@"Content-Type"]; 

NSMutableData *postData = 
[NSMutableData dataWithCapacity:[d length] + 512]; 
[postData appendData: 
[[NSString stringWithFormat:@"--%@\r\n", BOUNDRY] dataUsingEncoding:NSUTF8StringEncoding]]; 
[postData appendData: 
[[NSString stringWithFormat: 
    @"Content-Disposition: form-data; name=\"%@\"; filename=\"file.bin\"\r\n\r\n", FORM_FLE_INPUT] 
    dataUsingEncoding:NSUTF8StringEncoding]]; 
[postData appendData:d]; 
[postData appendData: 
[[NSString stringWithFormat:@"\r\n--%@--\r\n", BOUNDRY] dataUsingEncoding:NSUTF8StringEncoding]]; 

[request setHTTPBody:postData]; 
+0

Pensé que mi código nunca se colgó tampoco. La mayoría de las fotos funcionan. Pero luego tomé una foto que se quedó atascada. Descubrí que nunca obtuvo una respuesta cuando la foto era de ese tamaño. Entonces probé el tamaño hacia arriba y hacia abajo, y encontré esos límites. No he encontrado ninguna otra región que cause este problema. Sí, parece que nuestro servidor está esperando la solicitud completa antes de devolver algo, y piensa que no recibe la solicitud completa. Es realmente extraño. – tom

+0

Bueno, una condición es que Boundry, incluidos los guiones (-) y los nuevos caracteres de línea, deben ser únicos y no deben aparecer dentro de los datos. –

1

Creo que puede intentar eliminar esta línea de códigos.

[request addValue:@"close" forHTTPHeaderField: @"Connection"]; 

Le indicará al servidor http que cierre esta conexión. Mediante el RFC 2616 (HTTP/1.1), los servidores y clientes deben mantener una conexión constante.

+2

En realidad, resulta que ese es el problema exacto. el iPhone está ignorando ese encabezado cercano y configurándolo para mantenerse vivo. con keep-alive, rompe nuestro servidor. con cerca, funciona. ¿Cómo puedo anular la conexión nsurl para aceptar mi param cercano? – tom

+0

Estoy leyendo el rfc2616 recientemente. Y el documento dijo que este campo de encabezado "Conexión" con "cerrar" cerrará la conexión. Tal vez pueda enviar una solicitud solo con este encabezado "cerrar" cuando termine de cargar. – AechoLiu

+0

Recuerdo algunas publicaciones en SO que dicen que setHTTPBody modificará algunos parámetros de conexión. Por ejemplo, después de setHTTPBody, el tiempo de espera será de 75 segundos. Tal vez pueda establecer este headerField después de llamar a setHTTPBody. – AechoLiu

3

Ah, he encontrado cuál es el problema. Conexión: Keep-alive se está configurando, aunque configuré la conexión: cerrar. ¿Cómo anulo esto? ¡Parece que no puedes!

Cuestiones relacionadas