PDA

Просмотр полной версии : CURL POST отправка файла


slva2000
26.11.2009, 08:27
Есть форма на сайта:


бла бла

<form method="post" action="/profileedit/" enctype="multipart/form-data">
<input name="avatar" type="file" size="22" />

бла бла


Пытаюсь методом CURL отправить данные, в т.ч. файл. Данные улетают, сохраняются, как положено, а файл нет.

Вот результат снифера если отправлять форму браузером:


icq=748852941
бла, бла
skype=...
avatar=filename="photo.jpg" Content-Type: image/jpeg

Вот код php отправки:



function post($url,$data, $refer='') {

$process = curl_init($url);
if (!$refer=='') curl_setopt($process, CURLOPT_REFERER, $refer);
curl_setopt($process, CURLOPT_HTTPHEADER, $this->headers);
curl_setopt($process, CURLOPT_HEADER, 1);
curl_setopt($process, CURLOPT_USERAGENT, $this->user_agent);
if ($this->cookies == TRUE) curl_setopt($process, CURLOPT_COOKIEFILE, $this->cookie_file);
if ($this->cookies == TRUE) curl_setopt($process, CURLOPT_COOKIEJAR, $this->cookie_file);
curl_setopt($process, CURLOPT_ENCODING , $this->compression);
curl_setopt($process, CURLOPT_TIMEOUT, 30);
if ($this->proxy) curl_setopt($process, CURLOPT_PROXY, $this->proxy);
curl_setopt($process, CURLOPT_POSTFIELDS, $data);
curl_setopt($process, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($process, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($process, CURLOPT_POST, 1);
$return = curl_exec($process);
curl_close($process);
return $return;
}


$avatar = 'filename="c://photo.jpg" Content-Type: image/jpeg';
$post_data = "icq=".mt_rand(587964257, 797964257)."&skype=&avatar=".$avatar;

echo post ("http://site.com/profile/", $post_data, "http://site.com/profileediter/");


Данные в форме сохраняются (редактирование профиля), а аватор нет!

Помогите разобратся в том, где ошибка

slva2000
26.11.2009, 15:00
Уф, ну и не разбериха с этим курлом... Нашёл две детали (только с отладочными скриптами):

1. CURLOPT_POST должна идти обязательно перед CURLOPT_POSTFIELDS (иначе не принимает файл)
2. Заголовки я формировал для своей функции классические:


$this->headers[] = 'Accept: image/gif, image/x-bitmap, image/jpeg, image/pjpeg';
$this->headers[] = 'Connection: Keep-Alive';
$this->headers[] = 'Content-type: application/x-www-form-urlencoded;charset=UTF-8';
$this->user_agent = 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; .NET CLR 1.0.3705; .NET CLR 1.1.4322; Media Center PC 4.0)';


С ними отправить файл не удавалось. Что ж, решил скопировать заголовки со снифера (реальный пост на сайте):


$head[] = "Content-Type: image/gif";

$head[] = "User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; ru; rv:1.9.0.10) Gecko/2009042316 Firefox/3.0.10";
$head[] = "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8";
$head[] = "Accept-Language: ru,en-us;q=0.7,en;q=0.3";
$head[] = "Accept-Encoding: gzip,deflate";
$head[] = "Accept-Charset: windows-1251,utf-8;q=0.7,*;q=0.7";
$head[] = "Keep-Alive: 300";
$head[] = "Connection: keep-alive";
$head[] = "Referer: http:/xxx.ru/";
$head[] = "Content-Type: multipart/form-data";


Тоже не принимал такие. Удалил CURLOPT_HTTPHEADER с функции, всё заработало. Файл был принят сервером.
В голове не осталось ничего полезного :wacko

slva2000
26.11.2009, 15:07
Забыл добавить:

CURLOPT_POSTFIELDS должен быть массивом:

array("name_input" => "value");

m0Hze
26.11.2009, 15:17
Уф, ну и не разбериха с этим курлом... Нашёл две детали (только с отладочными скриптами):

1. CURLOPT_POST должна идти обязательно перед CURLOPT_POSTFIELDS (иначе не принимает файл)
2. Заголовки я формировал для своей функции классические:


$this->headers[] = 'Accept: image/gif, image/x-bitmap, image/jpeg, image/pjpeg';
$this->headers[] = 'Connection: Keep-Alive';
$this->headers[] = 'Content-type: application/x-www-form-urlencoded;charset=UTF-8';
$this->user_agent = 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; .NET CLR 1.0.3705; .NET CLR 1.1.4322; Media Center PC 4.0)';


С ними отправить файл не удавалось. Что ж, решил скопировать заголовки со снифера (реальный пост на сайте):


$head[] = "Content-Type: image/gif";

$head[] = "User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; ru; rv:1.9.0.10) Gecko/2009042316 Firefox/3.0.10";
$head[] = "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8";
$head[] = "Accept-Language: ru,en-us;q=0.7,en;q=0.3";
$head[] = "Accept-Encoding: gzip,deflate";
$head[] = "Accept-Charset: windows-1251,utf-8;q=0.7,*;q=0.7";
$head[] = "Keep-Alive: 300";
$head[] = "Connection: keep-alive";
$head[] = "Referer: http:/xxx.ru/";
$head[] = "Content-Type: multipart/form-data";


Тоже не принимал такие. Удалил CURLOPT_HTTPHEADER с функции, всё заработало. Файл был принят сервером.
В голове не осталось ничего полезного :wacko
Это какие то бредни.Ве отлично работает,при любом раскладе.Просто руки нужно воткнуть в туловище,ога.
POSTFIELDS не обязательно должен быть массив,проходит обычная строка:

$post = 'text=34234&log=2442';

svesve
26.11.2009, 15:19
поидеи поститься файл так


<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_VERBOSE, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/4.0 (compatible;)");
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, true);
// same as <input type="file" name="file_box">
$post = array(
"file_box"=>"@/path/to/myfile.jpg",
);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
$response = curl_exec($ch);
?>

b3
26.11.2009, 15:35
Уф, ну и не разбериха с этим курлом... Нашёл две детали (только с отладочными скриптами):

1. CURLOPT_POST должна идти обязательно перед CURLOPT_POSTFIELDS (иначе не принимает файл)
2. Заголовки я формировал для своей функции классические:


$this->headers[] = 'Accept: image/gif, image/x-bitmap, image/jpeg, image/pjpeg';
$this->headers[] = 'Connection: Keep-Alive';
$this->headers[] = 'Content-type: application/x-www-form-urlencoded;charset=UTF-8';
$this->user_agent = 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; .NET CLR 1.0.3705; .NET CLR 1.1.4322; Media Center PC 4.0)';


С ними отправить файл не удавалось. Что ж, решил скопировать заголовки со снифера (реальный пост на сайте):


$head[] = "Content-Type: image/gif";

$head[] = "User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; ru; rv:1.9.0.10) Gecko/2009042316 Firefox/3.0.10";
$head[] = "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8";
$head[] = "Accept-Language: ru,en-us;q=0.7,en;q=0.3";
$head[] = "Accept-Encoding: gzip,deflate";
$head[] = "Accept-Charset: windows-1251,utf-8;q=0.7,*;q=0.7";
$head[] = "Keep-Alive: 300";
$head[] = "Connection: keep-alive";
$head[] = "Referer: http:/xxx.ru/";
$head[] = "Content-Type: multipart/form-data";


Тоже не принимал такие. Удалил CURLOPT_HTTPHEADER с функции, всё заработало. Файл был принят сервером.
В голове не осталось ничего полезного :wacko
Объясни одну вещь, нафига слать все эти заголовки если ты используеш cURL ? Разве не для этого был создан cURL, что б те кто поленился изучать протоколы мог юзать Константы?

Вот пример загрузки изображения, когда-то давно писал, возможно код не очень красивый но понятен:


<?php
/************************************************** ************************************************** *******************
* Скрипт предназначен для автоматической смены аватарки на сайте vkontakte.ru. Замена аватарки происходит 1 раз в 24 часа.
* Имена аватарок:
* ponedelnik,
* vtornik,
* sreda,
* chetverg,
* pjatniza,
* subbota,
* woskresenje
* Формат файлов .png
* Запускать скрипт можно с сайта CronJob.ru рекомендую ставить промежуток 12 часов. Запуск производится по ссылке:
* http://www.example.com/SCRIPT_FILENAME.php?start
************************************************** ************************************************** ********************/
if(!@function_exists(curl_init))
{
echo '<center><b>cURL not Supported</b></center><br>';
exit;
}
###
if(file_exists('ponedelnik.png') && file_exists('vtornik.png') && file_exists('sreda.png') && file_exists('chetverg.png') && file_exists('pjatniza.png') && file_exists('subbota.png') && file_exists('woskresenje.png'))
{
echo '<a href="?start">START</a>';
}
else
{
echo '<b>Нехватает файлов изображений</b>';
###
}
if(!isset($_GET['start']))
{
exit;
}
###########################################
###########################################
##############[CONFIG]#####################
$id = '123'; ### <=== Your ID
$login = '123@rambler.ru'; ### <=== Your email for login
$pass = '123'; ### <=== Your password
###########################################
###########################################
$pass = md5($pass);
$login = str_replace('@','%40',$login);
$cookie = "remixmid=$id; remixemail=$login; remixpass=$pass";
################################################## #############################################
$date = date('w');
$arr = array(
'1' => 'ponedelnik',
'2' => 'vtornik',
'3' => 'sreda',
'4' => 'chetverg',
'5' => 'pjatniza',
'6' => 'subbota',
'0' => 'woskresenje'
);
$foto = $arr[$date].'.png';
################################################## #############################################
$ch = curl_init('http://vkontakte.ru/profileEdit.php?page=photo');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_TIMEOUT, 60);
curl_setopt($ch, CURLOPT_USERAGENT, 'Opera/9.62 (Windows NT 6.0; U; ru) Presto/2.1.1');
curl_setopt($ch, CURLOPT_COOKIE, $cookie);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
$res = curl_exec($ch);
curl_close($ch);
################################################## #############################################
if(preg_match_all('#action="(.*?)"#',$res, $url2))
{
$action_url = $url2[1][1];
$data = array(
'photo' => "@".$_SERVER['DOCUMENT_ROOT'].$foto,
'subm' => '1'
);
################################################## #############################################
$ch = curl_init($action_url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_TIMEOUT, 60);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_USERAGENT, 'Opera/9.62 (Windows NT 6.0; U; ru) Presto/2.1.1');
curl_setopt($ch, CURLOPT_COOKIE, $cookie);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
$res = curl_exec($ch);
curl_close($ch);
################################################## #############################################
}
?>

slva2000
26.11.2009, 15:58
Это какие то бредни.Ве отлично работает,при любом раскладе.Просто руки нужно воткнуть в туловище,ога.
POSTFIELDS не обязательно должен быть массив,проходит обычная строка:

$post = 'text=34234&log=2442';


Да, я часто вижу таких, которым лиш бы брякнуть. Открывай нотепад и вперёд:


upload.php:

<?
print_r($_POST);
echo "<br><br>";
print_r($_FILES);
?>


(не забудь положить 0.gif в ./home/localhost/)

Варинат 1. (единственный рабочий из предложеных)

index.php:

<?php
$ch = curl_init();
$data = array('name' => 'Foo', 'file' => '@'.$_SERVER['DOCUMENT_ROOT'].'/0.gif');

curl_setopt($ch, CURLOPT_URL, 'http://localhost/upload.php');
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_exec($ch);
?>


Варинат 2. (Стройка вместо массива. НЕ рабочий)

index.php:

<?php
$ch = curl_init();
$data = "name=Foo&file=@".$_SERVER['DOCUMENT_ROOT']."/0.gif";

curl_setopt($ch, CURLOPT_URL, 'http://localhost/upload.php');
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_POST, 1);
curl_exec($ch);
?>


Варинат 3. (CURLOPT_POST после CURLOPT_POSTFIELDS. НЕ рабочий)

index.php:

<?php
$ch = curl_init();
$data = array('name' => 'Foo', 'file' => '@'.$_SERVER['DOCUMENT_ROOT'].'/0.gif');

curl_setopt($ch, CURLOPT_URL, 'http://localhost/upload.php');
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_POST, 1);
curl_exec($ch);
?>


попрошу прокоментировать знатоков.

slva2000
26.11.2009, 16:03
cURL Information: libcurl/7.16.0 OpenSSL/0.9.8d zlib/1.2.3

b3 заголовки я отправлял с целью, что сервер принимает еменно "то, что нужно", т.е. рефер, например ему нужен правильный, и т.д. Оказалос, безусловно, что своими заголовками, я только напортачил. :) КУРЛ без этого сам правильно их сформировал.

Кста, а что ты скажешь про юзер-Агента? То, где я постю, это НЕОБХОДИМАЯ деталь. Причём, рандомные.

Но основная то беда не в нём. См мой ответ.

b3
26.11.2009, 17:08
Кста, а что ты скажешь про юзер-Агента?
curl_setopt($ch, CURLOPT_USERAGENT, 'Opera/9.62 (Windows NT 6.0; U; ru) Presto/2.1.1');
Причём, рандомные.
Загнал в файл список агентов и вытягивай рандомно.

slva2000
26.11.2009, 17:21
b3 это был риторический вопрос. Я к тому, что хеадреы часто приходится модифицировать. А при моей задаче (постинг ПОСТом с файлом), хеадеры воообще никикие не катят, если их указывать явно. Убрал полностью - пожалуйста. Добавил хотя бы Юзер-Агента - уже никак.

b3
26.11.2009, 19:13
что хеадреы часто приходится модифицировать.
Помоему ето бред сивой кабылы. Приводи примеры, посмотрим.

slva2000
27.11.2009, 10:42
Пример простой. Идёт пост на один какой либо ресурс. Было бы логично для каждого поста брять один из (положим) 5-ти разных заголовков Юзер_Агента. Это обеспечит анонимность, если использовать прокси.

b3
27.11.2009, 13:41
Пример простой. Идёт пост на один какой либо ресурс. Было бы логично для каждого поста брять один из (положим) 5-ти разных заголовков Юзер_Агента. Это обеспечит анонимность, если использовать прокси.
Ты по сколько раз будеш один и тот же вопрос задавать? Я на него ответил пару постов назад. Вопрос заключается в другом, зачем слать Заголовки как в сокетах, если можно по человечески отослать:
curl_setopt($ch, CURLOPT_USERAGENT, 'Opera/9.62 (Windows NT 6.0; U; ru) Presto/2.1.1');
Если нужен рандомный, что тебе мешает загнать в массив и выводить рандомно?
ТЫ вообщем действительно несеш чтото)) Если любиш слать Хедеры как в сокетах, так уже и писал бы на них, помоему для етого и есть курла предназначение, работать с протоколом не зная его, юзая константы, а у тебя каша выходит, пишеш на курле, не юзая константы, полукурл-полусокет))) и кстати полусокет явно кривой, заголовки с ошибками, но то пох, ога!!11админ

Luck3r
27.11.2009, 14:04
slva2000
Почитай: http://ru.wikipedia.org/wiki/HTTP

slva2000
27.11.2009, 14:05
b3,

Вообще то, это всё были не вопросы а ответы на один твой:

Объясни одну вещь, нафига слать все эти заголовки если ты используеш cURL ? Разве не для этого был создан cURL, что б те кто поленился изучать протоколы мог юзать Константы?


Я и обяснил, нафига их слать и какими. Какого тут демогогию то разводить...? Вопросы были в моём посту Вчера 14:58.

На него кто нить внятно может ответить..? Посылать РТФМы я бы не рекомендовал, ибо, противоречат они действительности.

zEr0r
28.11.2009, 01:39
Делай как я: составляй хедеры в ручную и отправляй через сокеты и не будет никаких проблем

структура хедера проста:
$header = "данное1\r\n";
$header .= "данное2\r\n";
$header .= "данное3\r\n";
$header .= "последнееданное\r\n\r\n"


данное это например Location: http://ya.ru
или Cookie...