Exemple #1
0
 /**
  * Merge a request's data with the default data
  *
  * @param array $request Request data (same form as {@see request_multiple})
  * @param boolean $merge_options Should we merge options as well?
  * @return array Request data
  */
 protected function merge_request($request, $merge_options = true)
 {
     if ($this->url !== null) {
         $request['url'] = Requests_IRI::absolutize($this->url, $request['url']);
         $request['url'] = $request['url']->uri;
     }
     if (empty($request['headers'])) {
         $request['headers'] = array();
     }
     $request['headers'] = array_merge($this->headers, $request['headers']);
     if (empty($request['data'])) {
         if (is_array($this->data)) {
             $request['data'] = $this->data;
         }
     } elseif (is_array($request['data']) && is_array($this->data)) {
         $request['data'] = array_merge($this->data, $request['data']);
     }
     if ($merge_options !== false) {
         $request['options'] = array_merge($this->options, $request['options']);
         // Disallow forcing the type, as that's a per request setting
         unset($request['options']['type']);
     }
     return $request;
 }
Exemple #2
0
 /**
  * Create a new IRI object by resolving a relative IRI
  *
  * Returns false if $base is not absolute, otherwise an IRI.
  *
  * @param IRI|string $base (Absolute) Base IRI
  * @param IRI|string $relative Relative IRI
  * @return IRI|false
  */
 public static function absolutize($base, $relative)
 {
     if (!$relative instanceof Requests_IRI) {
         $relative = new Requests_IRI($relative);
     }
     if (!$relative->is_valid()) {
         return false;
     } elseif ($relative->scheme !== null) {
         return clone $relative;
     } else {
         if (!$base instanceof Requests_IRI) {
             $base = new Requests_IRI($base);
         }
         if ($base->scheme !== null && $base->is_valid()) {
             if ($relative->get_iri() !== '') {
                 if ($relative->iuserinfo !== null || $relative->ihost !== null || $relative->port !== null) {
                     $target = clone $relative;
                     $target->scheme = $base->scheme;
                 } else {
                     $target = new Requests_IRI();
                     $target->scheme = $base->scheme;
                     $target->iuserinfo = $base->iuserinfo;
                     $target->ihost = $base->ihost;
                     $target->port = $base->port;
                     if ($relative->ipath !== '') {
                         if ($relative->ipath[0] === '/') {
                             $target->ipath = $relative->ipath;
                         } elseif (($base->iuserinfo !== null || $base->ihost !== null || $base->port !== null) && $base->ipath === '') {
                             $target->ipath = '/' . $relative->ipath;
                         } elseif (($last_segment = strrpos($base->ipath, '/')) !== false) {
                             $target->ipath = substr($base->ipath, 0, $last_segment + 1) . $relative->ipath;
                         } else {
                             $target->ipath = $relative->ipath;
                         }
                         $target->ipath = $target->remove_dot_segments($target->ipath);
                         $target->iquery = $relative->iquery;
                     } else {
                         $target->ipath = $base->ipath;
                         if ($relative->iquery !== null) {
                             $target->iquery = $relative->iquery;
                         } elseif ($base->iquery !== null) {
                             $target->iquery = $base->iquery;
                         }
                     }
                     $target->ifragment = $relative->ifragment;
                 }
             } else {
                 $target = clone $base;
                 $target->ifragment = null;
             }
             $target->scheme_normalization();
             return $target;
         } else {
             return false;
         }
     }
 }
 /**
  * HTTP response parser
  *
  * @throws Requests_Exception On missing head/body separator (`requests.no_crlf_separator`)
  * @throws Requests_Exception On missing head/body separator (`noversion`)
  * @throws Requests_Exception On missing head/body separator (`toomanyredirects`)
  *
  * @param string $headers     Full response text including headers and body
  * @param string $url         Original request URL
  * @param array  $req_headers Original $headers array passed to {@link request()}, in case we need to follow redirects
  * @param array  $req_data    Original $data array passed to {@link request()}, in case we need to follow redirects
  * @param array  $options     Original $options array passed to {@link request()}, in case we need to follow redirects
  *
  * @return Requests_Response
  */
 protected static function parse_response($headers, $url, $req_headers, $req_data, $options)
 {
     $return = new Requests_Response();
     if (!$options['blocking']) {
         return $return;
     }
     $return->raw = $headers;
     $return->url = $url;
     if (!$options['filename']) {
         if (strpos($headers, "\r\n\r\n") === false) {
             // Crap!
             throw new Requests_Exception('Missing header/body separator', 'requests.no_crlf_separator');
         }
         $headers = explode("\r\n\r\n", $headers, 2);
         $return->body = array_pop($headers);
         $headers = $headers[0];
     } else {
         $return->body = '';
     }
     // Pretend CRLF = LF for compatibility (RFC 2616, section 19.3)
     $headers = str_replace("\r\n", "\n", $headers);
     // Unfold headers (replace [CRLF] 1*( SP | HT ) with SP) as per RFC 2616 (section 2.2)
     $headers = preg_replace('/\\n[ \\t]/', ' ', $headers);
     $headers = explode("\n", $headers);
     preg_match('#^HTTP/1\\.\\d[ \\t]+(\\d+)#i', array_shift($headers), $matches);
     if (empty($matches)) {
         throw new Requests_Exception('Response could not be parsed', 'noversion', $headers);
     }
     $return->status_code = (int) $matches[1];
     if ($return->status_code >= 200 && $return->status_code < 300) {
         $return->success = true;
     }
     foreach ($headers as $header) {
         list($key, $value) = explode(':', $header, 2);
         $value = trim($value);
         preg_replace('#(\\s+)#i', ' ', $value);
         $return->headers[$key] = $value;
     }
     if (isset($return->headers['transfer-encoding'])) {
         $return->body = self::decode_chunked($return->body);
         unset($return->headers['transfer-encoding']);
     }
     if (isset($return->headers['content-encoding'])) {
         $return->body = self::decompress($return->body);
     }
     //fsockopen and cURL compatibility
     if (isset($return->headers['connection'])) {
         unset($return->headers['connection']);
     }
     if ((in_array($return->status_code, [300, 301, 302, 303, 307]) || $return->status_code > 307 && $return->status_code < 400) && $options['follow_redirects'] === true) {
         if (isset($return->headers['location']) && $options['redirected'] < $options['redirects']) {
             if ($return->status_code === 303) {
                 $options['type'] = Requests::GET;
             }
             $options['redirected']++;
             $location = $return->headers['location'];
             if (strpos($location, '/') === 0) {
                 // relative redirect, for compatibility make it absolute
                 $location = Requests_IRI::absolutize($url, $location);
             }
             $redirected = self::request($location, $req_headers, $req_data, false, $options);
             $redirected->history[] = $return;
             return $redirected;
         } elseif ($options['redirected'] >= $options['redirects']) {
             throw new Requests_Exception('Too many redirects', 'toomanyredirects', $return);
         }
     }
     $return->redirects = $options['redirected'];
     $options['hooks']->dispatch('requests.after_request', [&$return, $req_headers, $req_data, $options]);
     return $return;
 }