[C] Envió de archivo binario por HTTP

Iniciado por yeikos, 4 Mayo 2010, 20:09 PM

0 Miembros y 1 Visitante están viendo este tema.

yeikos

Buenas, llevo ya un par de años sin programar en c y ahora resulta que necesito realizar un trabajo y estoy desde ayer con el mismo problema :(

La funcion que estoy desarrollando es sencilla en si, su misión es enviar un archivo cualquiera en forma de peticion, así un script en PHP alojado en el servidor, podrá coger el archivo.


El problema lo tengo con los null bytes, al tratarse de archivos binarios (imagenes, ejecutables, etc) estos contienen nullbytes y me cortan la cadena, como primera solución opte por leer el archivo binario poco a poco e id enviandolo por partes, pero el problema, es que send, por lo que estoy observando, realiza tantas peticiones como envios se hagan, entonces, si corto el header para enviar luego el archivo, el servidor no entendera ninguna peticion, ya que estaran todas incompletas.


¿Alguna solucion/alternativa?


"POST %s HTTP/1.1\r\n"
"Host: %s\r\n"
"Content-Type: multipart/form-data; boundary=---------------------------%s\r\n"
"Content-Length: %i\r\n\r\n"
"-----------------------------%s\r\n"
"Content-Disposition: form-data; name=\"%s\"; filename=\"%s\"\r\n"
"Content-Type: %s\r\n\r\n"
"%s"
"\r\n-----------------------------%s\r\n"



Gracias y saludos!


biribau

Para esto está la codificación Base64, te deja todo el rango de bytes en un rango de carácteres ASCII, y lo mandas de una petición. Y sino mira como lo hace(con un sniffer por ejemplo) cualquier web de internet, debe de ser parecido

yeikos

jaja, resulta que hará cosa de 1 año hice una funcion para codificar en base64, y adivinas que problema tuve? los null byte me cortaban la cadena -_- aunque solucionar eso es tan facil como buscar una libreria o funcion ya depurada. Pero se que esa no es la solucion correcta, ya que enviarlo en base64 es opcional, no obligatorio. De todas maneras gracias por la idea =)

a ver si se encuentra otra solucion :s

biribau

De todas formas send y fread no cortan las cadenas, porque les tienes que indicar el tamaño. No sé cual es tu problema, no usarás alguna función de string.h? (strXXX)


yeikos

 Es sprintf quien me corta la cadena, ahora solo he utilizado sprintf hasta antes de concatenar el archivo binario, ahora jugare con los punteros y cuento mis resultados.

yeikos

He aqui la solución, gracias biribau por ayudarme :D


// create header var
char *header = (char *)malloc(header_size+1);
memset(header, 0x00, header_size+1);
sprintf(header,
  "POST %s HTTP/1.1\r\n"
"Host: %s\r\n"
"Content-Type: multipart/form-data; boundary=---------------------------%s\r\n"
"Content-Length: %i\r\n\r\n"
"-----------------------------%s\r\n"
"Content-Disposition: form-data; name=\"%s\"; filename=\"%s\"\r\n"
"Content-Type: %s\r\n\r\n",
path, host, boundary, content_size, boundary, varname, filename, type
);


// concat file content and rest
x = strlen(header);
memcpy (header+x, file,filesize);
sprintf(header+x+filesize, "\r\n-----------------------------%s\r\n", boundary);