\drupal_http_request
function
Perform an HTTP request.

Perform an HTTP request.

This is a flexible and powerful HTTP client implementation. Correctly handles GET, POST, PUT or any other HTTP requests. Handles redirects.

Comments

alberto56’s picture

I was having trouble using this with the POST method and found this post that worked for me: Solution for $_POST empty after drupal_http_request.

mugginsoft.net’s picture

Note that feof() will return true if the socket times out.

The docs for fsockopen state() that you have to call stream_set_timeout() to set timeouts for reading and writing but the feof() timeout behaviour seems on by default.

The default feof() timeout is 60 seconds but it can be hard to detect on processes that become incrementally longer that feof() timing out is an issue.

The default socket time-out can be overridden like so:

ini_set('default_socket_timeout','1200');

Also note that the timeout used to open the socket is of no relevance here.

Drupal 6 users should note that http_request() uses feof() and is therefore susceptible to timing out.

Amarjit’s picture

If you are posting data, ensure you set your header and data like so:

// Set some parameters for sending request.
$request_url = 'http://your-url.com';
$request_headers = array('Content-Type' => 'application/x-www-form-urlencoded');
$request_method = 'POST';
$request_retry = 3;
$data = 'name=Amarjit&status=1';
  
// Send the request.
$result = drupal_http_request($request_url, $request_headers, $request_method, $data, $request_retry);
hargobind’s picture

A note about the format of posted variables (i.e. $data).

The format of the $data string should be as follows:

name1=val1&name2=val2&name3=val3

A very quick way to build that string from an array is to use http_build_query().
Example:

$fruits = array('apple' => 'red', 'banana' => 'yellow', 'pear' => 'green');
$data = http_build_query($fruits, '', '&');

This will yield:
apple=red&banana=yellow&pear=green

When calling http_build_query(), make sure the third argument is "&". Otherwise, your system may default to "&" which means something completely different to the server processing the request (i.e. apple=red&banana=yellow&pear=green).

vmi’s picture

letapjar’s picture

Does anyone have any info on the speed of drupal_http_request vs. using a cURL call? I am thinking that since drupal_http_request requires a drupal bootstrap it should be a bit slower - but would appreciate any info on this.

EvanDonovan’s picture

The patch in [#82410] made it possible to use HTTP Basic Authentication with drupal_http_request(). This is especially useful when making calls to a REST API, or other web service.

The function leverages PHP's native parse_url() function in order to get the user & pass parameters needed for authentication. They are simply extracted from the URL, which should be in the format http://user:pass@example.com/end/point.php, or https://user:pass@example.com/end/point.php. If necessary, you can also append a query string to the URL.

Do not try doing the authentication adding user & pass as query string parameters because that will not work, and it will be unclear why not.

Example code for doing HTTP Basic Authentication (somewhat simplified from its original context):

function get_embed_code($media_id, $width = '', $height = '') {
    $scheme =  'https';
    $user = 'api';
    $pass = variable_get('api_key', '');
    $host = 'api.example.com';
    $path = '/v1/medias/' . $media_id . '/embed'; 
    if(isset($width)) { $query['width'] = 'width=' . $width; }
    if(isset($height)) { $query['height'] = 'height=' . $height; }
    // Implodes the query string options with an '&'
    $query = implode($query, '&');
    // Builds the URL for drupal_http_request to use in REST API call
    /* Expected format: https://api:@api.example.com/v1/medias//embed?width=&height= */
    $embed_url = $scheme . '://' . $user . ':' . $pass . '@' . $host . $path . '?' . $query;
    $result = drupal_http_request($embed_url);
    if(isset($result) && in_array($result->code, array('200', '302', '307')) && $result->data != '') {
      $embed_code = $result->data;
    }
    if(isset($embed_code) && $embed_code != '') {
      return $embed_code;
    }
}
takinola’s picture

In case the example above was not clear, in order to do basic auth using drupal_http_request simply enter the username and password into the url in the format below. Drupal_http_request will extract the username and password, base64 encode them and pass them along in the header appropriately

$url = 'http://username:password@target_url.com';
reign85’s picture

Thanks for this clear answer that really help me a lot !

Trejkaz’s picture

Actually, this is a trap.

Because of a bug in PHP, coupled with PHP not unescaping the values either, if the username or password contain %-escaped characters, putting the username and password in the URL does not work.

The workaround is to build the Authorization header yourself.

For an example of why this solution does not work, consider what happens if there is an @ in the user's email address or password.

takinola’s picture

For GET requests, the query has to be appended to the URL and not entered as the $data parameter i.e.

$target_url = 'http://your-url.com';
$request_method = 'GET';
$request_retry = 3;
$query = 'name=Amarjit&status=1';
$data ='';  // not required for GET
$request_headers='';  // not required for GET
  
$request_url = $target_url.'?'.$query;

// Send the request.
$result = drupal_http_request($request_url, $request_headers, $request_method, $data, $request_retry);