By default curl sends Accept: */* header for all requests. How do I stop sending of the default header?
Accept: */*
Pass in "Accept:" (ie a header with no contents to the right of the colon) with CURLOPT_HTTPHEADER. Like:
$headers = array( "Accept:" );
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
The equivalent using the curl command line tool is:
curl -H 'Accept:' http://example.com/
This will make curl remove the header, not just send a header with a blank value. You can also send a header with a blank value if you want, but then you need to use a semicolon instead of colon!
Make sure your array item is set up with the colon immediately following the header name, like this:
array( "Accept: yourAcceptValue" )
Not with spaces, like this:
array( "Accept : yourAcceptValue" )
If there is a space between the header name and the colon, curl will add the default */* into your headers.
(Works in PHP 5.5.9-1ubuntu4.7)
Related
I have come around a strange issue that when I am passing authorization header like below,
CURLOPT_HTTPHEADER => array(
"Authorization: Basic XXXXXXXXXX",
"Content-Type: application/json",
),
If I send like this then Authorization is not showing in request header.
But If I have Auth details like below,
CURLOPT_USERPWD=>"xxxxx:xxxxxx",
it will adding required Authorization header as I needed in htpp request.
So what is the issue in this? why it is not simply work as given in first code snippet? Also I am not able to send custom header, custom headers are also not available in request body.
I was wondering what is the default Content-Type header option when requesting a json string from an API.
I've noticed even if the requested Content-Type is application/json the response header Content-Type will be text/html
Does file_get_contents set the headers automatically based on what it is requesting or does it have a default one that is used always?
Does file_get_contents set the headers automatically based on what it is requesting or does it have a default one that is used always?
I think no defaults. For the context parameter you read below and see the 4-th example in docs:
A valid context resource created with stream_context_create(). If you don't need to use a custom context, you can skip this parameter by NULL.
Tested with Wireshark.
PHP 5.5.8 sends:
POST /path HTTP/1.0
Host: example.com
Content-Length: [appropriate number]
Content-Type: application/x-www-form-urlencoded
For the following context:
$options = array(
'http' => array(
'method' => 'POST',
'content' => $content
)
);
$context = stream_context_create($options);
Is there any way to retrieve a request body when a content-length header is not included in the request?
for example, I have this in /var/www/test.php:
print_r(apache_request_headers());
$data = file_get_contents('php://input');
var_dump($data);
And run this command:
curl -X POST -d test --header 'Content-Length: ' localhost/test.php
I see that there is no content-length header, and $data is empty. If I specify, for instance, a content-length of '3', I get an output for $data of 'tes'.
Is there any way to make php retrieve the request body, irrespective of the content-length header?
Is there any way to retrieve a request body when a content-length
header is not included in the request?
Yes. But you are including it in the request.
curl -d test localhost/test.php should return:
Array
(
[User-Agent] => curl/7.xx.x
[Host] => localhost
[Accept] => */*
[Content-Length] => 4
[Content-Type] => application/x-www-form-urlencoded
)
string(4) "test"
You can just omit sending the header.
I am trying to make a CURL request with some basic authentication (through sending an encrypted header). However, when I try to set the "Host: _" header, the remote server responds with:
Bad Request: Your browser sent a request that this server could not understand.
Here's the code that makes the CURL call. Note that it works as soon as I comment out the "Host: url" header in the $http_header variable. However, it is used on the target server as part of the authentication procedure, so I can not simply remove it.
$curl = curl_init();
$opt = array(
CURLOPT_URL=>$url,
CURLOPT_RETURNTRANSFER=>1,
CURLOPT_HTTPHEADER=>$http_header,
CURLOPT_POST=>1,
CURLOPT_POSTFIELDS=>$data_params,
CURLOPT_CONNECTTIMEOUT=>5, // Timeout to 5 seconds
);
curl_setopt_array($curl, $opt);
// $output contains the output string
$output = curl_exec($curl);
// it closes the session
curl_close($curl);
The contents of $http_header (an associative array):
array
0 => string 'Host: http://localhost/work/myproject'
1 => string 'Content-Type: multipart/form-data'
2 => string 'X-Authorization: Basicauth Z2xZjA2YzJhMzIxYTI1ZmIzZTgxYQ=='
The Host header doesn't accept a full URL, but only a hostname.
In this case the solution is to replace this header:
"Host: $url"
with:
"Host: ". parse_url($url, PHP_URL_HOST) ."
The Host header takes a hostname, not a URL. i.e. localhost, not http://localhost/work/myproject.
cURL should be generating it automatically from CURLOPT_URL though.
The Host header should not contain the protocol, only the host's name. So in this case all you need is localhost:
'Host: localhost'
I don't think either answer answers the asker's question. I've ran into the same problem. From looking at what cURL is sending, it is sending it's own Host header. This means that when you add one you now have two. All servers MUST respond with a 400 error when they see more than one host header.
The trick is get cURL not to generate it's own header (which I haven't figured out how to do yet) or don't send yours. In your case it seems not sending yours is fine. But, for what I'm doing, I have to send mine.
We're using Commission Junction's REST service, which requires we sent an API key in the Authorization header.
We set the header like this:
$ch = curl_init();
curl_setopt_array($ch, array(
// set url, timeouts, encoding headers etc.
CURLOPT_URL => 'https://....',
// ...
));
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Authorization: ' . CJ_API_KEY,
'User-Agent: ' . OUR_USER_AGENT
));
$response = curl_exec($ch);
$info = curl_getinfo($ch);
The problem is that the Authorization header isn't sent (we debugged this by using a local url and doing a var_export($_SERVER) which shows a User-Agent header is set, but not the Authorization header.)
If we change the header name to X-Authorization, it gets sent - but this hasn't helped us as the service specifically requires the Authorization header.
How do we get PHP + cURL to send an arbitrary Authorization header?
The Authorization header isn't included in PHP's $_SERVER variable. To properly debug a request you should use apache_request_headers() which shows we were sending the Authorization header exactly as we wanted.
The problem then moved on to figuring out exactly what to put in the Authorization header given some pretty bad documentation.
When the header is set by the client, then the Authorization-header from the request is included in $_SERVER — not sure if this is something new, but it is now. HTTP-headers get prefixed in the $_SERVER array with HTTP_ which may be something you previously overlooked.
Also, apache_request_headers() is a function which is only defined when you use Apache as a web server. So everyone with nginx etc. is left out.
Demo
On the server-side:
<?php
// server.php
var_dump($_SERVER['HTTP_AUTHORIZATION']);
Test
Start a webserver (requires PHP 5.4):
$ php -S 0.0.0.0:31337 -t .
Make sure server.php is in the current directory.
Use cURL to test:
$ curl -H 'Authorization: FOO' http://0.0.0.0:31337/server.php
string(3) "FOO"
Works. :)