2009-09-17 2 views
5

Я пытаюсь отправить файл на torrage.com из приложения в GAE. файл сохраняется в памяти после получения из пользовательской загрузки.Google App Engine urlfetch для POST-файлов

Я хотел бы, чтобы иметь возможность размещать этот файл, используя API доступные здесь: http://torrage.com/automation.php, но я имею некоторые проблемы доперли, как должно быть закодировано тело поста, самое я получил от API является «файл пустое "сообщение.

ответ

0

Почему бы не просто использовать модуль PPython для создания запроса POST, как показано в примере для PHP. Было бы что-то вроде этого:

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

Там нет файлов в App Engine, мне нужно использовать то, что я имею в памяти для отправки есть файл. – medecau

+0

Поскольку PHP-пример использует некоторые PHP-функции, которые строят запрос multipart/form-data, _not_ запрошенный формой запрос, созданный вашим примером. –

2

Я нахожу API Docs torrage на интерфейсе POST (в отличие от SOAP один) довольно запутанной и противоречивой с примерами кода C они также питания. Мне кажется, что в своем онлайн-примере PHP-сообщения они не отправляют содержимое файла (так же, как ответ kender не выше), а они отправляют его в примерах SOAP и в примере кода C.

Соответствующая часть образца C (как они вычислят заголовки, которые вы бы переходя к urlfetch.fetch) является:

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); 

«применение/х-битторрент» является HTTP_UPLOAD_CONTENT_TYPE. st.st_size - это количество байтов в буфере памяти со всеми данными файла (образец C читает эти данные из файла, но не имеет значения, как вы его получили в память, если знаете свой размер). content_boundary - это строка, которая НЕ присутствует в содержимом файла, они строят ее как "---------------------------%u%uLT" с каждым %u, замененным случайным числом (повторяющимся до тех пор, пока эта строка не ударит по двум случайным числам, которые не приводят его в файл). И, наконец, после тела (после открытия сокета HTTP и отправки других заголовков) они пишут следующее:

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; 

где filebuf является буфером с содержимым файла.

Едва остры и просто, но я надеюсь, что есть достаточно информации здесь, чтобы выработать способ построить аргументы в пользу более urlfetch.fetch (строит их для urllib.urlopen будет столь же трудно, поскольку эта проблема является нехватка документации именно о том, какие заголовки и какой контент и как закодировать вам нужно - и что не-документально оформленная информация нуждается в обратном проектировании из того, что я здесь представляю, я думаю).

В качестве альтернативы, может быть возможно взломать запрос SOAP через urlfetch; см. here для длинного поста Карсона о его попытках, трудностях и успехе в этом вопросе. И удачи!

0

Судя по коду C, он использует формат «multipart/form-data», который очень сложный, и очень легко получить что-то неправильно. Я бы не назвал это тело пост-кодом.

Я использовал функцию из этого блога, и это сработало для меня из автономной программы. Вы можете дать ему попробовать в приложении двигателя,

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

Смежные вопросы