Я нахожу 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 для длинного поста Карсона о его попытках, трудностях и успехе в этом вопросе. И удачи!
Там нет файлов в App Engine, мне нужно использовать то, что я имею в памяти для отправки есть файл. – medecau
Поскольку PHP-пример использует некоторые PHP-функции, которые строят запрос multipart/form-data, _not_ запрошенный формой запрос, созданный вашим примером. –