2015-11-26 3 views
0

Я пытаюсь перевести команду curl, которую я получил в команде, которую я могу запустить через PHP.Webservice работает через командную строку curl, но не PHP

Команда:

curl -F customerid=902 -F username=API1 -F password=somepassword -F reportname=1002 http://somerandomurl.com/api/v1/getreportcsv 

Когда я пытаюсь запустить это через PHP (и в конечном итоге через C#), однако, веб-служба возвращает ошибку. Любая идея, что может быть неправильным с моим кодом, который делает ошибку? Я думаю, что веб-сервис должен быть очень конкретным о заголовках/запроса:

$url = "http://somerandomurl.com/api/v1/getreportcsv"; 
$fields = [ 
    "customerid" => "902", 
    "username" => "API1", 
    "password" => "somepassword", 
    "reportname" => "1002" 
]; 

$fields_string = ""; 
foreach($fields as $key=>$value) { $fields_string .= $key.'='.$value.'&'; } 
rtrim($fields_string,'&'); 

//open connection 
$ch = curl_init(); 

curl_setopt($ch,CURLOPT_URL,$url); 
curl_setopt($ch,CURLOPT_POST,count($fields)); 
curl_setopt($ch,CURLOPT_POSTFIELDS,$fields_string); 

//execute post 
$result = curl_exec($ch); 
print $result; 

Wireshark показывает следующие отличия:

В приведенной ниже есть один, который работает:

POST /somefolder/api/v1/getreportcsv HTTP/1.1 
Host: somehost 
Accept: */* 
Content-Length: 65 
Content-Type: application/x-www-form-urlencoded 

customerid=902&username=API1&password=somepassword&reportname=1002&HTTP/1.1 200 OK 
Server: GlassFish Server Open Source Edition 3.1.1 
Content-Type: text/html;charset=UTF-8 
Content-Length: 6 
Date: Thu, 26 Nov 2015 22:51:23 GMT 

ERROR 

В то время как этот работы:

POST /someurl/api/v1/getreportcsv HTTP/1.1 
User-Agent: curl/7.33.0 
Host: somehost 
Accept: */* 
Content-Length: 459 
Expect: 100-continue 
Content-Type: multipart/form-data; boundary=------------------------4b0d14cc31a40c5b 

HTTP/1.1 100 Continue 

--------------------------4b0d14cc31a40c5b 
Content-Disposition: form-data; name="customerid" 

902 
--------------------------4b0d14cc31a40c5b 
Content-Disposition: form-data; name="username" 

API1 
--------------------------4b0d14cc31a40c5b 
Content-Disposition: form-data; name="password" 

somepassword 
--------------------------4b0d14cc31a40c5b 
Content-Disposition: form-data; name="reportname" 

1002 
--------------------------4b0d14cc31a40c5b-- 
HTTP/1.1 200 OK 
Server: GlassFish Server Open Source Edition 3.1.1 
Content-Type: text/html;charset=UTF-8 
Transfer-Encoding: chunked 
Date: Thu, 26 Nov 2015 23:13:57 GMT 

2000 
...snip... the results of the api 

Очевидно, что это очень разные запросы, однако я бы не стал что-то такое конкретное?

+0

Какая ошибка возвращается? – Rasclatt

+0

Кроме того, вы должны изучить использование 'http_build_query()' вместо вашей петли/обрезки. Может быть более эффективным, так как это родная функция. – Rasclatt

+0

Просто говорит «ОШИБКА», однако это не имеет значения, поскольку это было закодировано другим концом. Они, очевидно, отличаются друг от друга, используя мой код выше, чем он был бы, если бы он выполнялся командой, которую они нам дали – Lock

ответ

1

Вопрос кажется очень специфичным для рассматриваемой услуги.

Однако проблема может быть связана с заголовками. По curl man page:

-F [...] вызывает скручивание в POST данных с использованием Content-Type multipart/form-data в соответствии с RFC 2388

Однако, по словам PHP manual, CURLOPT_POST опция будет посылать данные используя application/x-www-form-urlencoded.

В соответствии с тем же руководством, если значение CURLOPT_POSTFIELDS является массивом, заголовок Content-Type будет установлен в multipart/form-data. Вы также можете попытаться установить тип содержимого явно как заголовок.

установить следующие параметры Curl Try:

curl_setopt($ch, CURLOPT_URL, $url); 
curl_setopt($ch, CURLOPT_POST, count($fields)); 
curl_setopt($ch, CURLOPT_POSTFIELDS, $fields); 
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-type: multipart/form-data')); 

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

+0

Вы легенда .. это сработало! Теперь просто перевести это в «HttpClient» на C# – Lock

+0

Рад слышать, как это работает :) Боюсь, я не могу много помочь с C# tho ..удачи! – Janci