Форум АНТИЧАТ

Форум АНТИЧАТ (https://forum.antichat.xyz/index.php)
-   PHP, PERL, MySQL, JavaScript (https://forum.antichat.xyz/forumdisplay.php?f=37)
-   -   POST и headers (https://forum.antichat.xyz/showthread.php?t=123374)

alex.k12 03.06.2009 04:23

POST и headers
 
Нужно сформировать правильный POST запрос в CURL. Сначала я делаю обычный запрос через браузер и ловлю отправленные и полученные хедеры и содержимое запроса (с помощью аддона firebug на файрфоксе), потом воспроизвожу это в своем запросе с помощью curl. Так вот, firebug выдает мне среди прочих хедеров следующие:

Content-Type:multipart/form-data; boundary=---------------------------14162188131998
Content-Length:118018

Другой перехватчик хедеров, HttpAnalyzer, их не видит

1. Важны ли эти заголовки при запросе, можно ли их опустить?
2. Как правильно сформировать запрос с телом (картинкой) и параметрами?
3. Как узнать Content-Length картинки перед отправкой? В гугле по этой теме есть очень много, но ничего по делу.

NaX[no]rT 03.06.2009 04:33

читаем и учимся http://ru.php.net/manual/de/function.curl-setopt.php

Dr.TRO 03.06.2009 09:33

1. Длина контента не оч вроде как ( если скачивал файлы думаю видел что иногдауказываеться какого он размера а иногда нет вот от указания или неуказания заголовка этого и зависит )
2. http://ru.php.net/manual/ru/function.curl-setopt.php тонко намекну ( http://curl.haxx.se/libcurl/php/examples/httpfileupload.html )
3. Ты картинку все равно

d_x 03.06.2009 09:44

1. нельзя опускать
2.
Код:

POST адрес HTTP/1.0
Content-Type: multipart/form-data; boundary=некоторое_достаточно_уникальное_значение [boundary]
Host: хост
Content-Length: длина_содержимого
[boundary]
Content-Disposition: form-data; name="file"; filename="имя_файла"
Content-Type: image/jpeg (тип)

[содержимое картинки]
[boundary]

3. В content-length записывается длина всего отправляемого содержимого без заголовков. Определить можно strlen.

alex.k12 03.06.2009 10:14

Цитата:

Сообщение от d_x
2.
Код:

POST адрес HTTP/1.0
Content-Type: multipart/form-data; boundary=некоторое_достаточно_уникальное_значение [boundary]
Host: хост
Content-Length: длина_содержимого
[boundary]
Content-Disposition: form-data; name="file"; filename="имя_файла"
Content-Type: image/jpeg (тип)

[содержимое картинки]
[boundary]


Вот-вот. Это то самое, что возвращает мне перехватчик при отправке моего сообщения. Я только не пойму, где это настраивается. Или достаточно просто указать вот эти хедеры

Content-Type: multipart/form-data; boundary=некоторое_достаточно_ никальное_значение
Host: хост
Content-Length: длина_содержимого
Content-Disposition: form-data; name="file"; filename="имя_файла"
Content-Type: image/jpeg (тип)

в CURLOPT_HTTPHEADER и параметры в CURLOPT_POSTFIELDS, а всё остальное курл сформирует сам?

Content-length узнал с помощью strlen(file_get_contents('имя_файла'));

Цитата:

Сообщение от NaX[no
rT]читаем и учимся http://ru.php.net/manual/de/function.curl-setopt.php

Заинтересовался вот этим:
1. CURLOPT_INFILESIZE : при закачке файла на удаленный сервер, следует использовать этот параметр для указания ожидаемого размера файла. (указать вместо Content-Length хедера?)
2. CURLOPT_UPLOAD : Установка этого параметра в ненулевое значение означает, что будет производиться закачка файла на удаленный сервер.(похоже тоже надо указать, поскольку я отправляю файл)
3. CURLOPT_INFILE : Файл, содержащий данные для передачи. (может, надо использовать это вместо указания имени файла среди параметров CURLOPT_POSTFIELDS?)

И еще, какая разница между указанием user-agent в хедерах CURLOPT_HTTPHEADER и в CURLOPT_USERAGENT?

Dr.TRO 03.06.2009 11:52

Код:

function post_file ($url, $avars) {               
        $parsed_url = parse_url($url);               
        $host = $parsed_url['host'];
        $path = $parsed_url['path'];       
                if($avars['type'] == 'content'){
                $file .= "filename=".$avars['filename']."&content=".$avars['value'];
        }
        if($avars['type'] == 'link'){
                $filetemp = file_get_contents($avars['value']);
                $filetopost = base64_encode($filetemp);
                $file .= "filename=".$avars['filename']."&content=".$filetopost;
        }
        if(isset($parsed_url['query'])) {                       
                $query = $parsed_url['query'];                       
        }                                       
        $socket = @fsockopen($host, 80, $errno, $errstr, $this->timeout) or die ("Не могу открыть сокет :".$errstr."(".$errno.")");       
        if ( isset($query) ) {                               
                $out = "POST ".$path."?".$query." HTTP/1.1\r\n";                               
        } else {                               
                $out = "POST ".$path." HTTP/1.1\r\n";                               
        }                       
        $out .= "Host: ".$host."\r\n";                       
        $out .= "User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; YPC 3.0.1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)\r\n";
        $out .= "Content-Type: application/x-www-form-urlencoded\r\n";
        $out .= "Content-Length: ".strlen($file)."\r\n";
        if(!isset($headers['Connection'])) {                                               
                $out .= "Connection: Close\r\n";                               
        }                       
        $out .= "\r\n";       
        $out .= $file;
        fwrite($socket, $out);               
        while (!feof($socket)) {
                $in .= fgets($socket, 128);
        }                 
        fclose($socket);       
        return $in;                                               
}

post_file ($url ( string ), $avars ( array ), $headers ( array )) - запрос типа POST который в себе еще передает файл, $avars - данные запроса ( без них функция не выполниться ) ( должны идти массивом следущего типа :
$avars['type'] => 'link' ( тип - ссылка на локальный файл для загрузки ( так как реализованно посредством функции file_get_contents можно попробовать и удаленные файлы)) || 'content' ( тип - содержимое )
$avars['value'] => 'value' ( если тип - ссылка тогда здесь должна быть ссылка на файл, если же content то содержимое файла закодированое посредством функции base64_encode )
$avars['filename'] => 'filename' ( имя файла в запросе )
), возвращает ответ сервера на запрос.

попугай 03.06.2009 11:55

Самая известная статья для новичков.
http://www.phpclub.ru/detail/article/http_request


Цитата:

Content-length узнал с помощью strlen(file_get_contents('имя_файла'));
проще filesize('имя файла');

.:EnoT:. 03.06.2009 12:09

Ему кажется пример с курлом был нужен..
Простой POST передаётся строкой в CURLOPT_POSTFIELDS.
POST с boundary передаётся туда же, только массивом. Всё, что в boundary передаётся с добавлением собачки @

а вы тут намутили )

Dr.TRO 03.06.2009 12:15

смотри мой третий пост =\

http://curl.haxx.se/libcurl/php/examples/httpfileupload.html

alex.k12 03.06.2009 14:24

Мне нужно абсолютно точно воспроизвести запрос из браузера в своей программе с помощью курла. Вот что надо отправить в хедерах:

Код:

(Request-Line)        POST /site.php?par=1 HTTP/1.1
Host: www.anysite.ru
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.0; ru; rv:1.9.0.10) Gecko/2009042316 Firefox/3.0.10
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-LanguageL: ru,en-us;q=0.7,en;q=0.3
Accept-Encoding: gzip,deflate
Accept-Charset: windows-1251,utf-8;q=0.7,*;q=0.7
Keep-Alive: 43200
Connection: keep-alive
Referer: http://www.anysite.ru/fol/
Cookie: PHPSESSID=2lpliicfgkjfnmjhbkm6dbn4t1
Content-Type: multipart/form-data; boundary=---------------------------21718375316139
Content-Length: 48176

В самом POST-запросе надо отправить следующее:

Код:

Content-Type: multipart/form-data; boundary=---------------------------21718375316139
Content-Length: 48176

-----------------------------21718375316139
Content-Disposition: form-data; name="param1"

123
-----------------------------21718375316139
Content-Disposition: form-data; name="param2"

123
-----------------------------21718375316139
Content-Disposition: form-data; name="email"


-----------------------------21718375316139
Content-Disposition: form-data; name="imagefile"; filename="pic.jpeg"
Content-Type: image/jpeg

ÿØÿà�JFIF��H�H��ÿþ�;CREATOR: gd-jpeg v1.0 (using IJG JPEG v62), quality = 80
ÿÛ�C�

(дальше пошло содержимое картинки)

Для этого я пишу следующий запрос:

PHP код:

$postdata = array( 'param1' => '123',
                   
'param2' => '123',
                   
'email' => '',
                   
'imagefile' => "@".'c:\www\pic.jpg');

    
$ch curl_init();

    
$headers[] = 'Host:www.anysite.ru';    
    
$headers[] = 'User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.0; ru; rv:1.9.0.10) Gecko/2009042316 Firefox/3.0.10';
    
$headers[] = 'Accept:text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8';
    
$headers[] = 'Accept-Language:ru,en-us;q=0.7,en;q=0.3';
    
$headers[] = 'Accept-Encoding:gzip,deflate';
    
$headers[] = 'Accept-Charset:windows-1251,utf-8;q=0.7,*;q=0.7';
    
$headers[] = 'Keep-Alive:43200';
    
$headers[] = 'Connection:keep-alive';
    
$headers[] = 'Referer:http://www.anysite.ru/fol/';
    
$headers[] = 'Cookie:PHPSESSID=2lpliicfgkjfnmjhbkm6dbn4t1';
    
$headers[] = 'Content-Type:multipart/form-data; boundary=---------------------------21718375316139';
    
$headers[] = 'Content-Length:48176';

    
curl_setopt($chCURLOPT_HTTPHEADER$headers);
    
curl_setopt($chCURLOPT_PROXY$proxy);
    
curl_setopt($chCURLOPT_URL"http://www.anysite.ru/site.php?par=1");
    
curl_setopt($chCURLOPT_RETURNTRANSFER1);
     
curl_setopt($chCURLOPT_POST1);
    
curl_setopt($chCURLOPT_HEADER0);
    
curl_setopt($chCURLOPT_POSTFIELDS$postdata);
    
    
$resultcurl_exec ($ch);
    
curl_close ($ch); 

На сервере, куда я отправляю POST, стоит проверка на корректность запросов и не пропускает вот этот вот мой curl-запрос, значит что-то в нём не хватет или наоборот лишнее. Что?

mailbrush 03.06.2009 14:30

Ну ты и намутил тут...
PHP код:

$headers[] = "Cookie:PHPSESSID='2lpliicfgkjfnmjhbkm6dbn4t1'; 

Закрывающую кавычку не поставил... И вообще - это быдлокод, почитай гугл, php.net.

.:EnoT:. 03.06.2009 14:40

Ужос..

PHP код:

$postdata = array( 'param1' => '123',
                   
'param2' => '123',
                   
'email'  => '',
                   
'imagefile' => '@' realpath('pic.jpg')
                 );

$ch curl_init('http://www.anysite.ru/site.php?par=1');
curl_setopt($chCURLOPT_HEADER0);
curl_setopt($chCURLOPT_RETURNTRANSFER1);
curl_setopt($chCURLOPT_POST1);
curl_setopt($chCURLOPT_POSTFIELDS$postdata);
$resultcurl_exec ($ch);
curl_close ($ch); 



ВСЁ! Больше тебе не нужны никакие заголовки!

alex.k12 03.06.2009 14:40

mailbrush, это я всё упростил. на самом деле я беру id php-сессии из пришедших ранее set-cookie заголовков. Если ты думаешь, что проблема в id сессии, это 100% не так, тут всё правильно.

Цитата:

ВСЁ! Больше тебе не нужны никакие заголовки!
Это как же, они не рассматриваются при проверке правильности запросов на сервере?

alex.k12 03.06.2009 19:10

Есть еще одна проблема, ошибка 417 Expectation Failed. Это баг сервера lighttpd, связанный с автоматической отправкой курлом хедера Expect: 100-continue.
http://www.astahost.com/Help-Removing-Specific-Header-cURL-t14787.html
Кто-нибудь сталкивался с этим?

m0Hze 03.06.2009 19:35

Может стоит поставить xampp/wampp?

Dr.TRO 03.06.2009 21:17

Блин отправляй все сокетом и не парь всем мозги

mailbrush 03.06.2009 21:40

Какими сокетами??? Только курл!

alex.k12 04.06.2009 18:18

Почему же, можно и сокетами, только я с ними никогда не работал. Искал, но так и не понял алгоритма передачи параметров. Вот это возвращает Bad request (и понятно, нагородил тут)

PHP код:

    $body = Array(
    
'-----------------------------23683118578968',
    
'Content-Disposition: form-data; name="param1"',
    
'\r\n',
    
'123',
    
'-----------------------------23683118578968',
    
'Content-Disposition: form-data; name="param2"',
    
'\r\n',
    
'123',
    
'-----------------------------23683118578968',
    
'Content-Disposition: form-data; name="email"',
    
'\r\n',
    
'\r\n',
    
'-----------------------------23683118578968',
    
'Content-Disposition: form-data; name="imagefile"; filename="pic.jpg"',
    
'Content-Type: image/jpeg',
    
'\r\n',
    
file_get_contents(realpath('pic.jpg')),
    
'-----------------------------23683118578968',
    
'Content-Disposition: form-data; name="param3"',
    
'\r\n',
    
'123');

    
$clenght=strlen(implode("\r\n",$body));
    
    
$a = array("POST http://www.anysite.ru/site.php?par=1 HTTP/1.1"
    
"Host: www.anysite.ru"
    
"User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.0; ru; rv:1.9.0.10) Gecko/2009042316 Firefox/3.0.10"
    
"Accept:text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"
    
"Accept-Language:ru,en-us;q=0.7,en;q=0.3"
    
"Accept-Encoding:gzip,deflate"
    
"Accept-Charset:windows-1251,utf-8;q=0.7,*;q=0.7"
    
"Keep-Alive:43200"
    
"Connection:keep-alive"
    
"Referer:http://www.anysite.ru/site/"
    
"Cookie:PHPSESSID=$sessid"
    
"Content-Type:multipart/form-data; boundary=---------------------------23683118578968",
    
"Content-Length:$clenght",
    
"\r\n"); 
    
    
$post = array();
    
$post $a $body;

    
$f fsockopen('64.46.248.204','8080') or die('Can\'t connect'); 
    
fwrite($f,implode("\r\n",$post)); 
    
$in fread($f1048576);
    if (
$in) {list(,$result) = explode("\r\n\r\n"$in2);}
    else 
$result NULL;
    
fclose($f); 


.:EnoT:. 04.06.2009 20:37

PHP код:

$post $a $body

Это какбэ операция сложения, а не конкатенации.
Замени хотя бы на:

PHP код:

$post $a "\r\n" $body

ну и это:
PHP код:

fwrite($f,implode("\r\n",$post)); 

на

PHP код:

fwrite($f$post); 


alex.k12 05.06.2009 00:59

Цитата:

Сообщение от .:EnoT:.
[php]
ну и это:
PHP код:

fwrite($f,implode("\r\n",$post)); 

на

PHP код:

fwrite($f$post); 


Ну да, и затереть разделитель между хедерами и содержимым. Вообще я правильно мыслю? Или всё вот это
PHP код:

 $body = Array( 
    
'-----------------------------23683118578968'
    
'Content-Disposition: form-data; name="param1"'
    
'\r\n'
    
'123'
    
'-----------------------------23683118578968'
    
'Content-Disposition: form-data; name="param2"'
    
'\r\n'
    
'123'
    
'-----------------------------23683118578968'
    
'Content-Disposition: form-data; name="email"'
    
'\r\n'
    
'\r\n'
    
'-----------------------------23683118578968'
    
'Content-Disposition: form-data; name="imagefile"; filename="pic.jpg"'
    
'Content-Type: image/jpeg'
    
'\r\n'
    
file_get_contents(realpath('pic.jpg')), 
    
'-----------------------------23683118578968'
    
'Content-Disposition: form-data; name="param3"'
    
'\r\n'
    
'123'); 

можно заменить на это?

PHP код:

$body "param1=123&param2=123&email=&imagefile=pic.jpg&param3=123"



Время: 12:49