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