2009-09-17 24 views
5

Estoy tratando de enviar un archivo a torrage.com desde una aplicación en GAE. el archivo se almacena en la memoria después de ser recibido de una carga del usuario.Google App Engine urlfetch para archivos POST

Me gustaría ser capaz de publicar este archivo usando la API disponible aquí: http://torrage.com/automation.php pero estoy teniendo algunos problemas undestanding cómo el cuerpo del mensaje debe ser codificada, la más conseguí de la API es un "archivo mensaje de "vacío".

Respuesta

0

¿Por qué no utilizar el módulo urllib2 de Python para crear una solicitud POST, como se muestra en un ejemplo para PHP. Sería algo así:

import urrlib, urllib2 
data = (
     ('name', 'torrent'), 
     ('type', 'application/x-bittorrent'), 
     ('file', '/path/to/your/file.torrent'), 
) 
request = urllib2.urlopen('http://torrage.com/autoupload.php', urllib.urlencode(data)) 
+0

No hay archivos en App Engine, i necesidad de usar lo que tengo en la memoria para enviar tiene un archivo. – medecau

+0

Como el ejemplo de PHP utiliza alguna funcionalidad de PHP que crea una solicitud multipart/form-data, _no_ la solicitud codificada en forma que su ejemplo construye. –

2

puedo encontrar documentación de la API de torrage en la interfaz de la POST (en contraposición a la de SOAP uno) bastante confusa y contradictoria con el código de ejemplo de C que también la oferta. Me parece que en su ejemplo en línea de post de PHP no envían el contenido del archivo (al igual que la respuesta de @Kender anterior no lo envía) mientras ESTÁN enviándolo en los ejemplos de SOAP y en el código de C de ejemplo.

La parte pertinente de la muestra C (cómo se calculan las cabeceras que usted estaría pasando a urlfetch.fetch) es:

snprintf(formdata_header, sizeof(formdata_header) - 1, 
    "Content-Disposition: form-data; name=\"torrent\"; filename=\"%s\"\n" 
    "Content-Type: " HTTP_UPLOAD_CONTENT_TYPE "\n" 
    "\n", 
    torrent_file); 
    http_content_len = 2 + strlen(content_boundary) + 1 + strlen(formdata_header) + st.st_size + 1 + 2 + strlen(content_boundary) + 3; 
    LTdebug("http content len %u\n", http_content_len); 
    snprintf(http_req, sizeof(http_req) - 1, 
    "POST /%s HTTP/1.1\n" 
    "Host: %s\n" 
    "User-Agent: libtorrage/" LTVERSION "\n" 
    "Connection: close\n" 
    "Content-Type: multipart/form-data; boundary=%s\n" 
    "Content-Length: %u\n" 
    "\n", 
    cache_uri, cache_host, content_boundary, http_content_len); 

"application/x-bittorrent" es el HTTP_UPLOAD_CONTENT_TYPE. st.st_size es el número de bytes en el búfer de memoria con todos los datos del archivo (el ejemplo C lee los datos del archivo, pero no importa cómo lo haya guardado en la memoria, siempre que sepa su tamaño). content_boundary es una cadena que NO está presente en el contenido del archivo, lo construyen como "---------------------------%u%uLT" con cada %u sustituido por un número aleatorio (repitiendo hasta que esa cadena acierte dos números aleatorios que la hacen que no esté presente en el archivo). Finalmente, el cuerpo posterior (después de abrir la toma de HTTP y el envío de las otras cabeceras) se escriben como sigue:

if (write_error == 0) if (write(sock, "--", 2) <= 0) write_error = 1; 
    if (write_error == 0) if (write(sock, content_boundary, strlen(content_boundary)) <= 0) write_error = 1; 
    if (write_error == 0) if (write(sock, "\n", 1) <= 0) write_error = 1; 
    if (write_error == 0) if (write(sock, formdata_header, strlen(formdata_header)) <= 0) write_error = 1; 
    if (write_error == 0) if (write(sock, filebuf, st.st_size) <= 0) write_error = 1; 
    if (write_error == 0) if (write(sock, "\n--", 3) <= 0) write_error = 1; 
    if (write_error == 0) if (write(sock, content_boundary, strlen(content_boundary)) <= 0) write_error = 1; 
    if (write_error == 0) if (write(sock, "--\n", 3) <= 0) write_error = 1; 

donde filebuf es el buffer con el contenido del archivo.

Apenas aguda y simple, pero espero que hay suficiente información para encontrar una forma de construir los argumentos a favor de una urlfetch.fetch (construcción de ellos para un urllib.urlopen sería tan difícil, ya que el problema es la escasez de documentación sobre exactamente qué encabezados y qué contenido y qué codificación necesita, y esa información no bien documentada necesita ingeniería inversa a partir de lo que estoy presentando aquí, creo).

Alternativamente, es posible piratear una solicitud SOAP a través de urlfetch; ver here para el largo post de Carson de sus intentos, dificultades y éxito en el asunto. ¡Y buena suerte!

0

A juzgar por el código C, está utilizando el formato "multipart/form-data", que es muy complejo y es muy fácil obtener algo mal. No codificaría manualmente el cuerpo del mensaje así.

Utilicé la función de este blog y funcionó para mí desde un programa independiente. Es posible que desee darle una oportunidad en el motor de aplicación,

http://peerit.blogspot.com/2007/07/multipartposthandler-doesnt-work-for.html