2016-02-22 4 views
1

Я пытаюсь получить доступ к веб-сайту, используя libcurl, и отправьте сообщение в форму, включая загрузку файла. Я не уверен на 100%, что я делаю, так как я в основном обратный инжиниринг сайта с использованием инструментов для создания хрома &, анализирующих вызовы POST/GET, которые затем будут реплицироваться с использованием libcurl.Использование libcurl для загрузки файла

Так что я вхожу в какой-то форум, где можно публиковать сообщения, которые могут иметь вложение. Моя программа уже может входить в систему, читать сообщения и отправлять текстовые сообщения, используя POST, в эту форму. Единственное, что не работает, - это сообщение о прикреплении файла PLUS.

В соответствии с инструментами разработчика Chrome, я могу видеть POST в той же форме, включая еще несколько параметров (имя файла, флаг для загрузки файлов) при загрузке файла с помощью браузера. Тем не менее, я не вижу никаких указаний на загрузку файла в инструментах для создания хрома, поэтому я не знаю, как это сделать программно.

В общем, что я просто пытаюсь сделать, использует тот же POST с помощью libcurl, который я могу успешно использовать для отправки сообщений без вложений, но

  • Я буду включать дополнительные параметры пост-
  • поставить чтения-функцию libcurl
  • сказать libcurl для загрузки (CURLOPT_UPLOAD)
  • питания CURLOPT_INFILESIZE
  • Я также попытался дополнительно поставить CURLOPT_POST

Теперь, POST успешным (withouth вложения) всегда будут перенаправлять к просмотру, таким образом HTTP 302 указывает на успешную операцию.
Однако, как только я попытаюсь загрузить, используя вышеприведенный код, я получаю только HTTP 200, а сообщение не отправляется. Тем не менее, я вижу, что моя функция чтения вызывается и что все байты файла передаются.

Интересно, что когда я опускаю CURLOPT_UPLOAD, я вижу, что мое чтение функция не называется (таким образом, ни один файл не передается) и POST получит HTTP 302, как ответ, и сообщение фактически размещено , Однако, когда вы его просматриваете, он содержит подсказку «Вложение было удалено».

Я знаю, что все это очень особенное для веб-сайта, к которому я пытаюсь получить доступ, и, вероятно, никто не может точно знать, что ожидает сервер. Но может ли кто-нибудь дать мне какие-то намеки на то, что может пойти не так, или что может быть причиной этого?
Может кто-нибудь, возможно, знает какой-нибудь фиктивный сайт, который я мог бы хотя бы использовать для проверки моей общей функции POST/upload, чтобы проверить правильность моего использования libcurl?

Любые намеки/советы высоко оценили :)


- Обновление 12 марта:


Как было предложено Даниэлем Стенберг, я пытаюсь использовать многочастному/formpost загрузки сейчас, но все же без успеха.Это то, что подробный вывод дает мне:

16/03/12 23:21:04 [HTTP] POST http://www.some.url // printed by my lib 
* Found bundle for host www.some.url: 0x154f53460 
* Re-using existing connection! (#1) with host www.some.url 
* Connected to www.some.url (someipaddress) port 80 (#1) 
> POST /some/path/ HTTP/1.1 

Host: www.some.url 
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:22.0)   Gecko/20100101 Firefox/22.0 
Accept: */* 
Cookie: FUP_sid=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx;    FUP_vid=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx;  FUPautologin=cb8c3ef4fcdecc390f6eca3f37814f623431219 
Content-Length: 170627 
Expect: 100-continue 
Content-Type: multipart/form-data; boundary=------------------------1b0a4317b11b7518 

< HTTP/1.1 100 Continue 

несколько секунд паузы/загрузки здесь

< HTTP/1.1 302 Found 
< Date: Sat, 12 Mar 2016 22:21:04 GMT 
< Server: Apache 
< Cache-Control: private, proxy-revalidate, s-maxage=0, no-cache 
< X-XSS-Protection: 1; mode=block 
< X-Frame-Options: SAMEORIGIN 
< Location: http://www.some.url/some/path/redirect/ 
< Vary: Accept-Encoding 
< Transfer-Encoding: chunked 
< Content-Type: text/html; charset=UTF-8 
* HTTP error before end of send, stop sending 
< 
* Closing connection 1 
16/03/12 23:21:06 [HTTP] DONE (0/302) // printed by my lib, http code of last operation 

я могу использовать один и тот же код libcurl успешно загружать файлы posttestserver.com, так что я я не знаю, в чем проблема. Что меня больше смущает, так это заявление * HTTP error before end of send, stop sending. Кажется, что сервер каким-то образом прерывает/отказывается от загрузки. На веб-сайте я вижу свое отправленное сообщение с подсказкой о том, что загруженный файл был удален (или не был полностью загружен?).

Может быть, может быть, что libcurl смущен 302 ответа от сервера (который является нормальным ответа для новых представлений сообщений, так как он перенаправляет к просмотру сообщения), или то, что может быть проблемой?

Пожалуйста, помогите :(

Это мой код:

struct curl_httppost* postForm = NULL; 
struct curl_httppost* last = NULL; 

for (HtmlInput* param= form->getFirstParameter(); param; 
    param= form->getNextParameter()) 
{ 
    HtmlElement::Attribute* nameAtt= param->getAttribute("name"); 
    HtmlElement::Attribute* valueAtt= param->getAttribute("value"); 

    curl_formadd(&postForm, &last, 
       CURLFORM_COPYNAME,  notNull(nameAtt ? nameAtt->value.c_str() : 0), 
       CURLFORM_COPYCONTENTS, notNull(valueAtt ? valueAtt->value.c_str() : 0), 
       CURLFORM_END); 
} 

if (attachment) 
{ 
    curl_formadd(&postForm, &last, 
       CURLFORM_COPYNAME, "name", 
       CURLFORM_BUFFER, attachmentName ? attachmentName : "fileupload", 
       CURLFORM_BUFFERPTR, uploadBuffer.buffer, 
       CURLFORM_BUFFERLENGTH, uploadBuffer.size, 
       CURLFORM_CONTENTTYPE, contentType, 
       CURLFORM_END); 
} 

curl_easy_setopt(session, CURLOPT_URL, url); 
curl_easy_setopt(session, CURLOPT_HTTPPOST, formpost); 
curl_easy_setopt(session, CURLOPT_VERBOSE, 1L); 

CURLcode curlCode= curl_easy_perform(session); 
+0

Вам необходимо прочитать документацию. 'CURLOPT_UPLOAD' означает PUT. Вероятно, вы хотите создать многостраничную форму, например, с помощью 'CURLOPT_HTTPPOST'. –

+0

О, я вижу. В настоящее время я выполняю свой POST с помощью 'curl_easy_setopt (h, CURLOPT_URL, url);' и 'curl_easy_setopt (h, CURLOPT_POSTFIELDS, поля);' следует за curl_easy_perform (h); '. Значит, вы имеете в виду использование 'CURLOPT_HTTPPOST' с' struct curl_httppost' в целом (также для не-uploads) будет лучшим способом, а также в значительной степени решить проблему, которую я описал здесь? И будет ли это работать с 'CURLOPT_READFUNCTION'? Поскольку я фактически не загружаю файл, я загружаю двоичные данные из памяти. – user826955

+0

Вам нужно прочитать документы и мой комментарий с большим вниманием к деталям. Вероятно, вам нужно использовать точный метод почтовых сообщений и да libcurl может отправлять прямо из памяти в любом случае. –

ответ

0

Nevermind, я полагал, что я отправлял неверное содержание в многочастных данных формы После добавления отладочной информации с CURLOPT_DEBUGFUNCTION и двойной проверкой и сравнивая. вывод с выходом хрома, я обнаружил, что параметр имени файла имел неправильное имя по сравнению с вызовом браузера.
После того, как я установил это, моя загрузка работала. Поэтому моя реализация выше работает и исправлена ​​:)