You are here

function httprl_handle_data in HTTP Parallel Request & Threading Library 7

Same name and namespace in other branches
  1. 6 httprl.module \httprl_handle_data()

If data is being sent out in this request, handle it correctly.

If $options['data'] is not a string, convert it to a string using http_build_query(). Set the Content-Length header correctly. Set the Content-Type to application/x-www-form-urlencoded if not already set and using method is POST.

@todo Proper mime support.

Parameters

array &$options: Array containing options.

2 calls to httprl_handle_data()
httprl_install_http_test in ./httprl.install
Issue a HTTP request to admin/httprl-test, verifying that the server got it.
httprl_request in ./httprl.module
Queue up a HTTP request in httprl_send_request.

File

./httprl.module, line 753
HTTP Parallel Request Library module.

Code

function httprl_handle_data(&$options) {

  // Encode data if not already done.
  if (isset($options['data']) && !is_string($options['data'])) {

    // Record raw data before it gets processed.
    $options['data-input'] = $options['data'];
    if (!empty($options['headers']['Content-Type']) && strpos($options['headers']['Content-Type'], 'multipart/related') === 0 && !empty($options['data'])) {

      // Trim semicolon from Content-Type header if needed.
      $options['headers']['Content-Type'] = trim($options['headers']['Content-Type']);
      if (substr_compare($options['headers']['Content-Type'], ';', -1, 1) === 0) {
        $options['headers']['Content-Type'] = substr($options['headers']['Content-Type'], -1);
      }

      // Add in boundary.
      $options['headers']['Content-Type'] .= '; boundary=' . HTTPRL_MULTIPART_BOUNDARY;
      $data_stream = '';
      foreach ($options['data'] as $part) {
        $data_stream .= '--' . HTTPRL_MULTIPART_BOUNDARY . "\r\n";
        foreach ($part['headers'] as $key => $value) {
          $data_stream .= $key . ': ' . $value . "\r\n";
        }
        $data_stream .= "\r\n";
        if (isset($part['file'])) {
          $data_stream .= file_get_contents($part['file']) . "\r\n";
        }
        elseif (isset($part['string'])) {
          $data_stream .= $part['string'] . "\r\n";
        }
      }

      // Signal end of request (note the trailing "--").
      $data_stream .= '--' . HTTPRL_MULTIPART_BOUNDARY . "--\r\n";
      $options['data'] = $data_stream;
    }
    elseif (!empty($options['data']['file']) || !empty($options['data']['files'])) {
      $data_stream = '';
      $data_array = $options['data'];

      // Add files to the request.
      if (isset($options['data']['files'])) {
        foreach ($options['data']['files'] as $field_name => $info) {
          $multi_field = '[]';

          // Convert $info into an array if it's a string.
          // This makes for one code path (the foreach loop).
          if (is_string($info)) {
            $multi_field = '';
            $temp = $info;
            unset($info);
            $info[] = $temp;
          }
          foreach ($info as $fullpath) {

            // Strip '@' from the start of the path (cURL requirement).
            if (substr($fullpath, 0, 1) == "@") {
              $fullpath = substr($fullpath, 1);
            }
            $filename = basename($fullpath);

            // TODO: mime detection.
            $mimetype = 'application/octet-stream';

            // Build the data-stream for this file.
            $data_stream .= '--' . HTTPRL_MULTIPART_BOUNDARY . "\r\n";
            $data_stream .= 'Content-Disposition: form-data; name="files[' . $field_name . ']' . $multi_field . '"; filename="' . $filename . "\"\r\n";
            $data_stream .= 'Content-Transfer-Encoding: binary' . "\r\n";
            $data_stream .= 'Content-Type: ' . $mimetype . "\r\n\r\n";
            $data_stream .= file_get_contents($fullpath) . "\r\n";
          }
        }

        // Remove files from the data array as they have already been added.
        unset($data_array['files']);
      }
      elseif (isset($options['data']['file'])) {
        $fullpath = $options['data']['file'];

        // Strip '@' from the start of the path (cURL requirement).
        if (substr($fullpath, 0, 1) == "@") {
          $fullpath = substr($fullpath, 1);
        }
        $filename = basename($fullpath);

        // TODO: mime detection.
        $mimetype = 'application/octet-stream';

        // Build the data-stream for this file.
        $data_stream .= '--' . HTTPRL_MULTIPART_BOUNDARY . "\r\n";
        $data_stream .= 'Content-Disposition: form-data; name="file"; filename="' . $filename . "\"\r\n";
        $data_stream .= 'Content-Transfer-Encoding: binary' . "\r\n";
        $data_stream .= 'Content-Type: ' . $mimetype . "\r\n\r\n";
        $data_stream .= file_get_contents($fullpath) . "\r\n";
        unset($data_array['file']);
      }

      // Add fields to the request too: $_POST['foo'] = 'bar'.
      httprl_multipart_encoder($data_stream, $data_array);

      // Signal end of request (note the trailing "--").
      $data_stream .= '--' . HTTPRL_MULTIPART_BOUNDARY . "--\r\n";
      $options['data'] = $data_stream;

      // Set the Content-Type to multipart/form-data if the data is not empty,
      // the Content-Type is not set, and the method is POST or PUT.
      if (!empty($options['data']) && !isset($options['headers']['Content-Type']) && ($options['method'] == 'POST' || $options['method'] == 'PUT')) {
        $options['headers']['Content-Type'] = 'multipart/form-data; boundary=' . HTTPRL_MULTIPART_BOUNDARY;
      }
    }
    else {
      $options['data'] = http_build_query($options['data'], '', '&');

      // Set the Content-Type to application/x-www-form-urlencoded if the data
      // is not empty, the Content-Type is not set, and the method is POST or
      // PUT.
      if (!empty($options['data']) && !isset($options['headers']['Content-Type']) && ($options['method'] == 'POST' || $options['method'] == 'PUT')) {
        $options['headers']['Content-Type'] = 'application/x-www-form-urlencoded';
      }
    }
  }

  // Only add Content-Length if we actually have any content or if it is a POST
  // or PUT request. Some non-standard servers get confused by Content-Length in
  // at least HEAD/GET requests, and Squid always requires Content-Length in
  // POST/PUT requests.
  if (strlen($options['data']) > 0 || $options['method'] == 'POST' || $options['method'] == 'PUT') {
    $options['headers']['Content-Length'] = httprl_strlen($options['data']);
  }
}