You are here

public function EasyRdf_Http_Client::request in Zircon Profile 8

Same name and namespace in other branches
  1. 8.0 vendor/easyrdf/easyrdf/lib/EasyRdf/Http/Client.php \EasyRdf_Http_Client::request()

Send the HTTP request and return an HTTP response object

Return value

EasyRdf_Http_Response

Throws

EasyRdf_Exception

File

vendor/easyrdf/easyrdf/lib/EasyRdf/Http/Client.php, line 371

Class

EasyRdf_Http_Client
This class is an implemetation of an HTTP client in PHP. It supports basic HTTP 1.0 and 1.1 requests. For a more complete implementation try Zend_Http_Client.

Code

public function request($method = null) {
  if (!$this->uri) {
    throw new EasyRdf_Exception("Set URI before calling EasyRdf_Http_Client->request()");
  }
  if ($method) {
    $this
      ->setMethod($method);
  }
  $this->redirectCounter = 0;
  $response = null;

  // Send the first request. If redirected, continue.
  do {

    // Clone the URI and add the additional GET parameters to it
    $uri = parse_url($this->uri);
    if ($uri['scheme'] === 'http') {
      $host = $uri['host'];
    }
    elseif ($uri['scheme'] === 'https') {
      $host = 'ssl://' . $uri['host'];
    }
    else {
      throw new EasyRdf_Exception("Unsupported URI scheme: " . $uri['scheme']);
    }
    if (isset($uri['port'])) {
      $port = $uri['port'];
    }
    else {
      if ($uri['scheme'] === 'https') {
        $port = 443;
      }
      else {
        $port = 80;
      }
    }
    if (!empty($this->paramsGet)) {
      if (!empty($uri['query'])) {
        $uri['query'] .= '&';
      }
      else {
        $uri['query'] = '';
      }
      $uri['query'] .= http_build_query($this->paramsGet, null, '&');
    }
    $headers = $this
      ->prepareHeaders($uri['host'], $port);

    // Open socket to remote server
    $socket = @fsockopen($host, $port, $errno, $errstr, $this->config['timeout']);
    if (!$socket) {
      throw new EasyRdf_Exception("Unable to connect to {$host}:{$port} ({$errstr})");
    }
    stream_set_timeout($socket, $this->config['timeout']);
    $info = stream_get_meta_data($socket);

    // Write the request
    $path = $uri['path'];
    if (empty($path)) {
      $path = '/';
    }
    if (isset($uri['query'])) {
      $path .= '?' . $uri['query'];
    }
    fwrite($socket, "{$this->method} {$path} HTTP/1.1\r\n");
    foreach ($headers as $k => $v) {
      if (is_string($k)) {
        $v = ucfirst($k) . ": {$v}";
      }
      fwrite($socket, "{$v}\r\n");
    }
    fwrite($socket, "\r\n");

    // Send the request body, if there is one set
    if (isset($this->rawPostData)) {
      fwrite($socket, $this->rawPostData);
    }

    // Read in the response
    $content = '';
    while (!feof($socket) && !$info['timed_out']) {
      $content .= fgets($socket);
      $info = stream_get_meta_data($socket);
    }
    if ($info['timed_out']) {
      throw new EasyRdf_Exception("Request to {$host}:{$port} timed out");
    }

    // FIXME: support HTTP/1.1 100 Continue
    // Close the socket
    @fclose($socket);

    // Parse the response string
    $response = EasyRdf_Http_Response::fromString($content);

    // If we got redirected, look for the Location header
    if ($response
      ->isRedirect() && ($location = $response
      ->getHeader('location'))) {

      // Avoid problems with buggy servers that add whitespace at the
      // end of some headers (See ZF-11283)
      $location = trim($location);

      // Some servers return relative URLs in the location header
      // resolve it in relation to previous request
      $baseUri = new EasyRdf_ParsedUri($this->uri);
      $location = $baseUri
        ->resolve($location)
        ->toString();

      // If it is a 303 then drop the parameters and send a GET request
      if ($response
        ->getStatus() == 303) {
        $this
          ->resetParameters();
        $this
          ->setMethod('GET');
      }

      // If we got a well formed absolute URI
      if (parse_url($location)) {
        $this
          ->setHeaders('host', null);
        $this
          ->setUri($location);
      }
      else {
        throw new EasyRdf_Exception("Failed to parse Location header returned by " . $this->uri);
      }
      ++$this->redirectCounter;
    }
    else {

      // If we didn't get any location, stop redirecting
      break;
    }
  } while ($this->redirectCounter < $this->config['maxredirects']);
  return $response;
}