Http response header and body not correct as expected - php

I am working on proxy with PHP. In my php code I am sending proper required headers and expected to get response body and headers. However I am getting response body correctly as I want but not getting headers properly (supposed to get Status 200 but getting 401). When i traced with firefox I found that SAP URL itsself making 2 request internally by using data which I send. so with my first request it is not authenticated so SAP url itslef managining to send same request again and 2nd time it gives both proper response body with headers. Howevber I php code when I get it i get response body from 2nd response and headers from 1st response.
here is code.
$opts = array(
'http'=>array(
'method'=>"POST",
'content' => $xml_request,
'header'=>array("Host:" . $sap_url,
"Content-Type: text/xml; charset=UTF-8",
$authstring,$xml_request)
)
);
$context = stream_context_create($opts);
$result = file_get_contents($sap_url, false, $context);
$http_res_array = get_headers($sap_url);

You should probably use curl functions instead and do BOTH requests yourself. file_get_contents, does the second request for you, but takes away the possibility to fetch the second headers.

Maybe a little old but anyways:
You're using the get_headers()-function to get the headers. It's documentation states that:
Fetches all the headers sent by the server in response to a [new] HTTP request
It doesn't empathize that this function will actually send a new request to the server and return the response-header for that request. Therefor, the headers can be slightly different.
Since you're using file_get_contents() to load the content, you can use the global $http_response_header-variable right after your request, which will contain the response-header from the last executed request.

Related

Yii Header may not contain more than a single header

I have a problem when I am trying to POST data to third party API. I'm getting an error
yii\base\ErrorException: Header may not contain more than a single header, new line detected in /www/wwwroot/xxx/vendor/yiisoft/yii2/web/Response.php:382
As far as I know yii manages headers by itself and I added additional headers for auth purposes.
My additional headers:
protected function getHeaders($data = [])
{
ksort($data);
reset($data);
$ts = microtime().rand(0, 10000);
return [
'login: '.$this->login,
'ts: '.$ts,
'sig: '.md5($ts.$this->apiKey),
];
}
Code works in pure php tests, but not inside yii app.
I already tried to log response and request headers, didn't find any duplicated headers.
Only something like this one:
'CONTENT_TYPE' => 'application/json; charset=utf-8'
But I don't know if this counts for multiple headers.
The problem was on the API provider's side. My requests were not passing authentication, and I was getting back gibberish with incorrect headers.

How to send raw data with curl GET in PHP?

I am developing REST API and while it is easy to set raw JSON data for request in cURL for POST
$payload = json_encode(array("user" => $data));
//attach encoded JSON string to the POST fields
curl_setopt($ch, CURLOPT_POSTFIELDS, $payload);
I cannot figure out how to send such data with GET requests.
Is there something like CURLOPT_GETFIELDS or CURLOPT_RAWDATA? The purpose of sending JSON with GET request is to pass in some params.
I do not wish to add formdata to the request, I wish to post JSON so that it can be parsed on the receiver.
Thanks!
EDIT:
based on comments I want to avoid confusion, so the resulting request should look like:
GET / HTTP/1.1
Host: 127.0.0.1:3000
Content-Type: application/json
Accept: application/json
Host: 127.0.0.1:3000
content-length: 13
Connection: keep-alive
cache-control: no-cache
{
"a": "b"
}
as you can see, GET request here has data and it is parsed and works perfectly by web server. How do I achieve this with cURL?
GET requests do not have a body, that's the whole idea: you're just getting something from the server, as opposed to posting something to it. From RFC 7231:
A payload within a GET request message has no defined semantics;
sending a payload body on a GET request might cause some existing
implementations to reject the request.
In other words, a GET request can have data, but it should not. From earlier in the spec, where GET is defined as a safe method:
Request methods are considered "safe" if their defined semantics are
essentially read-only; i.e., the client does not request, and does
not expect, any state change on the origin server as a result of
applying a safe method to a target resource.
...
Of the request methods defined by this specification, the GET, HEAD,
OPTIONS, and TRACE methods are defined to be safe.
If you really want to have JSON in your GET request (and send it to a reasonably implemented server resource) the only place it can go is in the URI as part of the query string. For GET requests I find using file_get_contents to be much easier than dealing with cURL.
<?php
$payload = json_encode(["user" => $data]);
$url_data = http_build_query([
"json" => $payload
]);
$url = "https://some.example/endpoint.php?" . $url_data;
$result = file_get_contents($url);
If you want to send it to an unreasonably implemented server resource, and violate the spirit of the HTTP RFCs, you could do this:
<?php
$url = "https://some.example/endpoint.php";
$payload = json_encode(["user" => $data]);
$ctx = stream_context_create(["http" => [
"header"=>"Content-Type: application/json",
"content"=>$payload
]]);
$result = file_get_contents($url, false, $ctx);
If you're determined to do this specifically with cURL, you might have luck with the CURLOPT_CUSTOMREQUEST option set to "GET" and CURLOPT_POSTDATA with your data.

How to attach authorization header via PHP?

I am using PHP to get JSON from a remote server via file_get_contents command. Here is the piece of code I used:
$opts = array(
'https'=>array(
'method'=>'GET',
'header'=>'Accept-language: en\r\n' .
'Authorization: MAC ["3","ios2.5.0","123","123abc","123=","abc="]\r\n' .
'User-Agent: abc/1.1.1 iOS/10.0.2 iPhone/iPhone7,1\r\n'
)
);
$context = stream_context_create($opts);
$file = file_get_contents('https://www.google.com/v11/file?search=ios&with=users%2Cfiles%2Cquestions', false, $context);
echo $file;
I did a quick debugging:
Using Postman I was able to get the json file with the same header.
I tried a different json from a different url, it works.
I tried a local file, it works.
You have to understand what file_get_contents is. This command is a request to get the file on the server, in this case it is requesting to get https://www.google.com/v11/file/index.html on the server as in one single step. Since your url seems to use header to verify your origin, it might be an ajax request, meaning the server components didn't set up to allow an output from file_get_contents requests, instead they probably accept cURL requests.
So you can use:
curl_exec()

PHP NuSoap correct way of sending headers

I've been stuck with a HTTP 400 "Bad Request" issue when trying to connect to an API for some time now.
I have a feeling it's to do with the headers, but I'm not too sure.
My query is regarding the output of the SOAP Request and whether I'm correctly setting the headers.
So the code I have to set the header is
$proxy->setHeaders('<soap:Header><AuthenticationSoapHeader xmlns="https://www.xxxxx.com/ASPAPI"><Token>xxxxx-xxxxx-xxxx</Token></AuthenticationSoapHeader></soap:Header>');
I then make a call to an API function and pass over the XML string directly after setting the headers, like so:
$result = $proxy->call('ValidateService', array('serviceXML' => $xml));
However, the output when printing $proxy->request is like so:
[TOKEN VALUE FROM HEADER HERE][CONTENTS OF XML STRING HERE]
So the request string basically prints out the contents of inside the <token> tag in the header, directly followed by the XML string.
Is it right that the <token> value is printed out in the request alongside the XML string? I have a feeling I may be incorrectly setting the headers.
The problem lies in the headers.
The <soap:Header> opening & closing tags were causing the HTTP Error 400 "Bad Request"
$proxy->setHeaders('<soap:Header><AuthenticationSoapHeader xmlns="https://www.xxxxx.com/aspapi"><Token>xxxxx</Token></AuthenticationSoapHeader></soap:Header>');
Should be
$proxy->setHeaders('<AuthenticationSoapHeader xmlns="https://www.xxxxx.com/aspapi"><Token>xxxxx</Token></AuthenticationSoapHeader>');

Requesting JSON from PHP

I am trying to retrieve data from a server which usually returns it in XML, however I trying to request it in a JSON format (if requested correctly it will return the data in JSON).
$header = array(
'http' => array(
'header'=>"Content-type: application/json"
),
);
$response = file_get_contents($query, false, $header);
print_r($response);
This approach was taken from here. Currently the program does not return anything.
Does anyone spot any potential problems with this?
You need to set the HTTP Accept header to tell the server that you want it to give you JSON:
Accept: application/json
(assuming that the remote server is correctly implemented to read the header)
The Content-Type request header indicates the type of the payload that you are POSTing.
In your case, it does not apply, since you're sending a GET request.

Categories