You are here

function HTTP_Request::sendRequest in Flickr API 5

Sends the request

@access public

Parameters

bool Whether to store response body in Response object property,: set this to false if downloading a LARGE file and using a Listener

Return value

mixed PEAR error on error, true otherwise

File

phpFlickr/PEAR/HTTP/Request.php, line 675

Class

HTTP_Request
Class for performing HTTP requests

Code

function sendRequest($saveBody = true) {
  if (!is_a($this->_url, 'Net_URL')) {
    return PEAR::raiseError('No URL given', HTTP_REQUEST_ERROR_URL);
  }
  $host = isset($this->_proxy_host) ? $this->_proxy_host : $this->_url->host;
  $port = isset($this->_proxy_port) ? $this->_proxy_port : $this->_url->port;

  // 4.3.0 supports SSL connections using OpenSSL. The function test determines
  // we running on at least 4.3.0
  if (strcasecmp($this->_url->protocol, 'https') == 0 and function_exists('file_get_contents') and extension_loaded('openssl')) {
    if (isset($this->_proxy_host)) {
      return PEAR::raiseError('HTTPS proxies are not supported', HTTP_REQUEST_ERROR_PROXY);
    }
    $host = 'ssl://' . $host;
  }

  // magic quotes may fuck up file uploads and chunked response processing
  $magicQuotes = ini_get('magic_quotes_runtime');
  ini_set('magic_quotes_runtime', false);

  // RFC 2068, section 19.7.1: A client MUST NOT send the Keep-Alive
  // connection token to a proxy server...
  if (isset($this->_proxy_host) && !empty($this->_requestHeaders['connection']) && 'Keep-Alive' == $this->_requestHeaders['connection']) {
    $this
      ->removeHeader('connection');
  }
  $keepAlive = HTTP_REQUEST_HTTP_VER_1_1 == $this->_http && empty($this->_requestHeaders['connection']) || !empty($this->_requestHeaders['connection']) && 'Keep-Alive' == $this->_requestHeaders['connection'];
  $sockets =& PEAR::getStaticProperty('HTTP_Request', 'sockets');
  $sockKey = $host . ':' . $port;
  unset($this->_sock);

  // There is a connected socket in the "static" property?
  if ($keepAlive && !empty($sockets[$sockKey]) && !empty($sockets[$sockKey]->fp)) {
    $this->_sock =& $sockets[$sockKey];
    $err = null;
  }
  else {
    $this
      ->_notify('connect');
    $this->_sock =& new Net_Socket();
    $err = $this->_sock
      ->connect($host, $port, null, $this->_timeout, $this->_socketOptions);
  }
  PEAR::isError($err) or $err = $this->_sock
    ->write($this
    ->_buildRequest());
  if (!PEAR::isError($err)) {
    if (!empty($this->_readTimeout)) {
      $this->_sock
        ->setTimeout($this->_readTimeout[0], $this->_readTimeout[1]);
    }
    $this
      ->_notify('sentRequest');

    // Read the response
    $this->_response =& new HTTP_Response($this->_sock, $this->_listeners);
    $err = $this->_response
      ->process($this->_saveBody && $saveBody, HTTP_REQUEST_METHOD_HEAD != $this->_method);
    if ($keepAlive) {
      $keepAlive = isset($this->_response->_headers['content-length']) || isset($this->_response->_headers['transfer-encoding']) && strtolower($this->_response->_headers['transfer-encoding']) == 'chunked';
      if ($keepAlive) {
        if (isset($this->_response->_headers['connection'])) {
          $keepAlive = strtolower($this->_response->_headers['connection']) == 'keep-alive';
        }
        else {
          $keepAlive = 'HTTP/' . HTTP_REQUEST_HTTP_VER_1_1 == $this->_response->_protocol;
        }
      }
    }
  }
  ini_set('magic_quotes_runtime', $magicQuotes);
  if (PEAR::isError($err)) {
    return $err;
  }
  if (!$keepAlive) {
    $this
      ->disconnect();

    // Store the connected socket in "static" property
  }
  elseif (empty($sockets[$sockKey]) || empty($sockets[$sockKey]->fp)) {
    $sockets[$sockKey] =& $this->_sock;
  }

  // Check for redirection
  if ($this->_allowRedirects and $this->_redirects <= $this->_maxRedirects and $this
    ->getResponseCode() > 300 and $this
    ->getResponseCode() < 399 and !empty($this->_response->_headers['location'])) {
    $redirect = $this->_response->_headers['location'];

    // Absolute URL
    if (preg_match('/^https?:\\/\\//i', $redirect)) {
      $this->_url =& new Net_URL($redirect);
      $this
        ->addHeader('Host', $this
        ->_generateHostHeader());

      // Absolute path
    }
    elseif ($redirect[0] == '/') {
      $this->_url->path = $redirect;

      // Relative path
    }
    elseif (substr($redirect, 0, 3) == '../' or substr($redirect, 0, 2) == './') {
      if (substr($this->_url->path, -1) == '/') {
        $redirect = $this->_url->path . $redirect;
      }
      else {
        $redirect = dirname($this->_url->path) . '/' . $redirect;
      }
      $redirect = Net_URL::resolvePath($redirect);
      $this->_url->path = $redirect;

      // Filename, no path
    }
    else {
      if (substr($this->_url->path, -1) == '/') {
        $redirect = $this->_url->path . $redirect;
      }
      else {
        $redirect = dirname($this->_url->path) . '/' . $redirect;
      }
      $this->_url->path = $redirect;
    }
    $this->_redirects++;
    return $this
      ->sendRequest($saveBody);

    // Too many redirects
  }
  elseif ($this->_allowRedirects and $this->_redirects > $this->_maxRedirects) {
    return PEAR::raiseError('Too many redirects', HTTP_REQUEST_ERROR_REDIRECTS);
  }
  return true;
}