tôi tìm tài liệu API torrage của trên giao diện POST (như trái ngược với SOAP một) khá khó hiểu và mâu thuẫn với C mẫu mã họ cũng cung ứng. Dường như với tôi rằng trong ví dụ trực tuyến của họ về PHP, họ không gửi nội dung của tập tin (giống như câu trả lời của kender @ ở trên là không gửi nó) trong khi họ gửi nó trong các ví dụ SOAP và trong ví dụ mã C.
Phần liên quan của mẫu C (làm thế nào họ tính toán các tiêu đề mà bạn muốn được đi qua để urlfetch.fetch
) là:
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" là HTTP_UPLOAD_CONTENT_TYPE
. st.st_size
là số byte trong bộ nhớ đệm với tất cả dữ liệu của tệp (mẫu C đọc dữ liệu đó từ tệp, nhưng không quan trọng bạn đã nhập nó vào bộ nhớ như thế nào, miễn là bạn biết kích thước của nó). content_boundary
là một chuỗi KHÔNG có trong nội dung của tệp, chúng tạo thành "---------------------------%u%uLT"
với mỗi số %u
được thay thế bằng một số ngẫu nhiên (lặp lại cho đến khi chuỗi đó xuất hiện trên hai số ngẫu nhiên khiến nó không có trong tệp). Cuối cùng, cơ thể bài (sau khi mở ổ cắm HTTP và gửi các tiêu đề khác) họ viết như sau:
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;
nơi filebuf
là đệm với nội dung của tập tin.
Khó và đơn giản, nhưng tôi hy vọng có đủ thông tin ở đây để tìm cách xây dựng các đối số cho một urlfetch.fetch
(xây dựng chúng cho một urllib.urlopen
sẽ khó khăn, vì vấn đề là sự khan hiếm tài liệu về chính xác tiêu đề và nội dung nào và cách mã hóa bạn cần - và thông tin không được tài liệu đó cần phải được thiết kế ngược từ những gì tôi trình bày ở đây, tôi nghĩ).
Ngoài ra, bạn có thể hack yêu cầu SOAP thông qua urlfetch; xem here cho bài đăng dài về những nỗ lực, khó khăn và thành công của Carson trong vấn đề này. Và chúc may mắn!
Không có tập tin trong App Engine, tôi cần phải sử dụng những gì tôi có trong bộ nhớ để gửi có một tập tin. – medecau
Vì ví dụ PHP sử dụng một số chức năng PHP để xây dựng một yêu cầu nhiều dữ liệu/biểu mẫu, _not_ yêu cầu mã hóa biểu mẫu mà ví dụ của bạn xây dựng. –