示例#1
0
 /**
  * Parse the header content and return a new instance of the HTTPHeader class.
  *
  * @param string|array $content The raw header content
  * @param bool $lowerCase Whether cookies and headers should be referenced using a lower case key
  *
  * @return HTTPHeader[] An array of HTTPHeader instances containing the parsed data (One instance per header part)
  */
 public static function parseHeader($content, $lowerCase = false)
 {
     $data = array();
     if (!is_array($content)) {
         $content = explode("\r\n\r\n", $content);
     }
     foreach ($content as $header) {
         $header = trim($header);
         if (!$header) {
             continue;
         }
         $header = explode("\r\n", $header);
         $headerInstance = new HTTPHeader();
         foreach ($header as $lineIndex => $line) {
             if ($lineIndex == 0) {
                 if (preg_match("/^HTTP\\/([0-9\\.]+) ([0-9]+) (.*)/", $line, $matches)) {
                     $headerInstance->version = $matches[1];
                     $headerInstance->statusCode = (int) $matches[2];
                     $headerInstance->statusText = $matches[3];
                 }
                 continue;
             }
             $headerLine = explode(":", trim($line), 2);
             if (count($headerLine) < 2) {
                 continue;
             }
             list($headerKey, $headerValue) = $headerLine;
             $headerKey = trim($headerKey);
             if (strtolower($headerKey) == "set-cookie") {
                 $cookie = new HTTPCookie();
                 $cookie->parse($headerValue);
                 if ($lowerCase) {
                     $key = strtolower($cookie->name);
                 } else {
                     $key = $cookie->name;
                 }
                 $headerInstance->cookies[$key] = $cookie;
             } else {
                 if ($lowerCase) {
                     $headerKey = strtolower($headerKey);
                 }
                 $headerInstance->headers[$headerKey] = trim($headerValue);
             }
         }
         $data[] = $headerInstance;
     }
     return $data;
 }
 /**
  * Set cookie for the application's client.
  * @param HTTPCookie $cookie
  */
 public function set_cookie(HTTPCookie $cookie)
 {
     setcookie($cookie->get_name(), $cookie->get_value(), $cookie->get_expiration_date(), $cookie->get_path(), $cookie->get_domain(), $cookie->get_secure(), $cookie->get_httponly());
 }
示例#3
0
文件: net.php 项目: poppa/PLib
 /**
  * Do an arbitrary HTTP action
  *
  * @throws HTTPMaxRedirectException
  * @throws HTTPRequestException
  * @throws HTTPResponseException
  *
  * @param string $method
  *  What method to use: `GET`, `POST`, `PROPPATCH`...
  * @param string $url
  *  Where to send the request. A full URI: http://server.com/path/
  * @param array $vars
  *  Query variables to send. An associative array with key/value pairs
  * @param array $headers
  *  Additional request headers
  * @param string $data
  *  Data to send as raw data in a SOAP call for instance
  *
  * @return HTTPResponse
  */
 public function do_method($method, $uri, $vars = array(), $headers = array(), $data = null)
 {
     $host = null;
     $port = null;
     $path = null;
     $query = null;
     $body = null;
     $sock = null;
     $method = strtoupper($method);
     if ($this->recursions >= $this->max_redirects) {
         throw new HTTPMaxRedirectException("Redirect limit ({$this->max_redirects}) exceeded!");
     }
     $request = array();
     // It's an assignment
     if (!($request = parse_url($uri))) {
         throw new HTTPRequestException("Bad URL ({$uri}) as argument");
     }
     if (!isset($request['host'])) {
         throw new HTTPRequestException("Missing host in URL ({$uri}) argument");
     }
     $port = 0;
     $protocol = isset($request['scheme']) ? $request['scheme'] : false;
     if ($protocol != 'http') {
         switch ($protocol) {
             case 'https':
                 if (!isset($request['port'])) {
                     $port = 443;
                 }
                 break;
         }
     }
     $host = $request['host'];
     $query = isset($request['query']) ? $request['query'] : null;
     if (!$port) {
         $port = isset($request['port']) ? (int) $request['port'] : 80;
     }
     if (isset($request['user'])) {
         $this->username = $request['user'];
     }
     if (isset($request['pass'])) {
         $this->password = $request['pass'];
     }
     if (!empty($vars)) {
         $query = http_build_query($vars);
     }
     //! Default the request path to root
     $path = isset($request['path']) ? $request['path'] : '/';
     $add_header = "";
     if (!empty($headers)) {
         $this->request_headers = $headers + $this->request_headers;
     }
     foreach ($this->request_headers as $key => $val) {
         if (!is_string($key)) {
             throw new HTTPRequestException("Malformed header, missing key.");
         }
         if (empty($val)) {
             throw new HTTPRequestException("Malformed header, missing value " . "for key \"{$key}\"");
         }
         //! Due to a bug in PHP5.2?
         if ($key == 'Accept-Encoding') {
             continue;
         }
         $add_header .= "{$key}: {$val}\r\n";
     }
     if ($this->username && $this->password) {
         $add_header .= "Authorization: Basic " . base64_encode($this->username . ':' . $this->password);
     }
     if ($this->cookie) {
         $c = $this->cookie->create_header($port == 443, $host, $path);
         if ($c !== false) {
             $add_header .= $c;
         }
     }
     switch ($method) {
         case 'GET':
             $path .= $query ? '?' . $query : '';
             break;
         case 'POST':
             $body = empty($data) ? $query : urlencode($data);
             if (!isset($this->headers['Content-Type'])) {
                 $add_header .= "Content-Type: application/x-www-form-urlencoded\r\n";
             }
             $add_header .= "Content-Length: " . strlen($body) . "\r\n\r\n" . $body;
             break;
         default:
             $body = $data;
             if (!isset($this->headers['Content-Type'])) {
                 $add_header .= "Content-Type: text/plain\r\n";
             }
             $add_header .= "Content-Length: " . strlen($body) . "\r\n\r\n" . $body;
             break;
     }
     $header = "{$method} {$path} HTTP/{$this->version}\r\n" . "Host: {$host}\r\n{$add_header}\r\n";
     // print ($header);
     $rawresponse = false;
     if ($this->cache > 0) {
         $rawresponse = $this->get_cache($header);
     }
     if ($rawresponse === false) {
         $errno = 0;
         $errstr = null;
         $proto = 'tcp';
         switch ($protocol) {
             case 'https':
                 $proto = 'ssl';
                 break;
             case 'ftp':
                 $proto = 'ftp';
                 break;
         }
         //echo "+ Request: $proto://$host:$port$path\n";
         if (!($sock = @stream_socket_client("{$proto}://{$host}:{$port}", $errno, $errstr, $this->timeout))) {
             $m = "Couldn't fetch {$host}! {$errstr} (errno: {$errno})";
             throw new HTTPRequestException($m);
         }
         if (!is_resource($sock)) {
             throw new HTTPRequestException("Couldn't connect to {$host}");
         }
         fputs($sock, $header);
         $rawresponse = "";
         while (!feof($sock)) {
             $rawresponse .= fgets($sock, 512);
         }
     } else {
         $rawresponse = file_get_contents($rawresponse);
     }
     $resp = new HTTPResponse($rawresponse);
     $cookie = null;
     // It's an assignment
     if ($this->cookie && ($cookie = $resp->get_header('set-cookie'))) {
         $this->cookie->set($host, $cookie);
     }
     $status = $resp->status();
     if ($status != 200) {
         //print_r ($resp);
         if ($status == 302 || $status == 301) {
             $location = $resp->get_header('location');
             if ($location != $path && !strpos($location, '://')) {
                 $url = $protocol . "://" . $host . $location;
             } else {
                 $url = $location;
             }
             $headers["Referer"] = $url;
             if ($cookie) {
                 $headers["Cookie"] = $cookie;
             }
             $this->recursions++;
             $vars = array();
             //print_r ($headers);
             return $this->do_method($method, $url, $vars, $headers, $data);
         }
     }
     if ($this->cache > 0) {
         $this->write_cache($header, $rawresponse, $resp->status());
     }
     $this->recursions = 0;
     return $resp;
 }