Urlfetch Google App Engine в POST-файлы - PullRequest
       15

Urlfetch Google App Engine в POST-файлы

5 голосов
/ 17 сентября 2009

Я пытаюсь отправить файл на torrage.com из приложения в GAE. файл сохраняется в памяти после получения от пользователя.

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

Ответы [ 3 ]

2 голосов
/ 17 сентября 2009

Я нахожу документы API 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);

"application / x-bittorrent" - это 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; см. здесь для длинного поста Карсона о его попытках, трудностях и успехах в этом вопросе. И, удачи!

0 голосов
/ 17 сентября 2009

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

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

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

0 голосов
/ 17 сентября 2009

Почему бы просто не использовать модуль Python urllib2 для создания запроса 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))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...