Example #1
0
 /**
  * Request HTTP using stream.
  * This method is modified from function drupal_http_request in Drupal 7.
  */
 protected function requesterStream()
 {
     $result = new HTTPResponse();
     $url = $this->getUrl();
     $uri = $this->parse_url;
     $options = $this->options();
     $headers = $this->headers();
     $post = $this->post();
     // Merge the default headers.
     $headers += array('User-Agent' => 'Drupal (+http://drupal.org/)');
     // Merge the default options.
     $options += array('method' => 'GET');
     // stream_socket_client() requires timeout to be a float.
     $options['timeout'] = (double) $options['timeout'];
     // Set post.
     if (!empty($post)) {
         // $headers['Content-Type'] = 'multipart/form-data';
         $headers['Content-Type'] = 'application/x-www-form-urlencoded';
         $options['method'] = 'POST';
         // $options['data'] = http_build_query($post);
         $post = ArrayDimensional::simplify($post);
         $options['data'] = self::httpBuildQuery($post);
     }
     // Support proxy.
     $proxy_server = $this->options('proxy_server');
     $proxy_exceptions = $this->options('proxy_exceptions');
     $is_host_not_proxy_exceptions = !in_array(strtolower($uri['host']), $proxy_exceptions, TRUE);
     if ($proxy_server && $is_host_not_proxy_exceptions) {
         // Set the scheme so we open a socket to the proxy server.
         $uri['scheme'] = 'proxy';
         // Set the path to be the full URL.
         $uri['path'] = $url;
         // Since the URL is passed as the path, we won't use the parsed query.
         unset($uri['query']);
         // Add in username and password to Proxy-Authorization header if needed.
         if ($proxy_username = $this->options('proxy_username')) {
             $proxy_password = $this->options('proxy_password');
             $headers['Proxy-Authorization'] = 'Basic ' . base64_encode($proxy_username . (!empty($proxy_password) ? ":" . $proxy_password : ''));
         }
         // Some proxies reject requests with any User-Agent headers, while others
         // require a specific one.
         $proxy_user_agent = $this->options('proxy_user_agent');
         // The default value matches neither condition.
         if ($proxy_user_agent === NULL) {
             unset($headers['User-Agent']);
         } elseif ($proxy_user_agent) {
             $headers['User-Agent'] = $proxy_user_agent;
         }
     }
     switch ($uri['scheme']) {
         case 'proxy':
             // Make the socket connection to a proxy server.
             $socket = 'tcp://' . $proxy_server . ':' . $this->options('proxy_port');
             // The Host header still needs to match the real request.
             $headers['Host'] = $uri['host'];
             $headers['Host'] .= isset($uri['port']) && $uri['port'] != 80 ? ':' . $uri['port'] : '';
             break;
         case 'http':
         case 'feed':
             $port = isset($uri['port']) ? $uri['port'] : 80;
             $socket = 'tcp://' . $uri['host'] . ':' . $port;
             // RFC 2616: "non-standard ports MUST, default ports MAY be included".
             // We don't add the standard port to prevent from breaking rewrite rules
             // checking the host that do not take into account the port number.
             $headers['Host'] = $uri['host'] . ($port != 80 ? ':' . $port : '');
             break;
         case 'https':
             // Note: Only works when PHP is compiled with OpenSSL support.
             $port = isset($uri['port']) ? $uri['port'] : 443;
             $socket = 'ssl://' . $uri['host'] . ':' . $port;
             $headers['Host'] = $uri['host'] . ($port != 443 ? ':' . $port : '');
             break;
         default:
             $result->error = 'invalid schema ' . $uri['scheme'];
             $result->code = -1003;
             return $result;
     }
     if (empty($options['context'])) {
         $fp = @stream_socket_client($socket, $errno, $errstr, $options['timeout']);
     } else {
         // Create a stream with context. Allows verification of a SSL certificate.
         $fp = @stream_socket_client($socket, $errno, $errstr, $options['timeout'], STREAM_CLIENT_CONNECT, $options['context']);
     }
     // Make sure the socket opened properly.
     if (!$fp) {
         // When a network error occurs, we use a negative number so it does not
         // clash with the HTTP status codes.
         $result->code = -$errno;
         $result->error = trim($errstr) ? trim($errstr) : Log::interpolate('Error opening socket {socket}', array('socket' => $socket));
         // Mark that this request failed. This will trigger a check of the web
         // server's ability to make outgoing HTTP requests the next time that
         // requirements checking is performed.
         // See system_requirements().
         // $this->setState('drupal_http_request_fails', TRUE);
         return $result;
     }
     // Construct the path to act on.
     $path = isset($uri['path']) ? $uri['path'] : '/';
     if (isset($uri['query'])) {
         $path .= '?' . $uri['query'];
     }
     // 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.
     $content_length = strlen($options['data']);
     if ($content_length > 0 || $options['method'] == 'POST' || $options['method'] == 'PUT') {
         $headers['Content-Length'] = $content_length;
     }
     // If the server URL has a user then attempt to use basic authentication.
     if (isset($uri['user'])) {
         $headers['Authorization'] = 'Basic ' . base64_encode($uri['user'] . (isset($uri['pass']) ? ':' . $uri['pass'] : '******'));
     }
     //
     $request = $options['method'] . ' ' . $path . " HTTP/1.0\r\n";
     foreach ($headers as $name => $value) {
         $request .= $name . ': ' . trim($value) . "\r\n";
     }
     $request .= "\r\n" . $options['data'];
     $result->request = $request;
     // Calculate how much time is left of the original timeout value.
     $timeout = $options['timeout'] - $this->timer->read() / 1000;
     if ($timeout > 0) {
         stream_set_timeout($fp, floor($timeout), floor(1000000 * fmod($timeout, 1)));
         fwrite($fp, $request);
     }
     // Fetch response. Due to PHP bugs like http://bugs.php.net/bug.php?id=43782
     // and http://bugs.php.net/bug.php?id=46049 we can't rely on feof(), but
     // instead must invoke stream_get_meta_data() each iteration.
     $info = stream_get_meta_data($fp);
     $alive = !$info['eof'] && !$info['timed_out'];
     $response = '';
     while ($alive) {
         // Calculate how much time is left of the original timeout value.
         $timeout = $options['timeout'] - $this->timer->read() / 1000;
         if ($timeout <= 0) {
             $info['timed_out'] = TRUE;
             break;
         }
         stream_set_timeout($fp, floor($timeout), floor(1000000 * fmod($timeout, 1)));
         $chunk = fread($fp, 1024);
         $response .= $chunk;
         $info = stream_get_meta_data($fp);
         $alive = !$info['eof'] && !$info['timed_out'] && $chunk;
     }
     fclose($fp);
     if ($info['timed_out']) {
         $result->code = -1;
         $result->error = 'request timed out';
         return $result;
     }
     // echo "\r\n-----------------\r\n";
     // print_r($response);
     // echo "\r\n-----------------\r\n";
     // Drupal code stop here, next we passing to HTTPResponse::parse.
     $result->parse($response);
     return $result;
 }
Example #2
0
 /**
  * Alternative handler for bca_set_referer.
  */
 protected function bcaSetReferer()
 {
     $menu_name = $this->step['menu'];
     $referer = $this->configuration("menu][bca_{$menu_name}][referer");
     if (empty($referer)) {
         return;
     }
     $language = $this->configuration('language');
     $part = null;
     switch ($language) {
         case 'en':
             $part = 'nav_bar_indo';
             // Masih belum tahu.
             break;
         case 'id':
             $part = 'nav_bar_indo';
             break;
     }
     null === $part or $referer = Log::interpolate($referer, ['language' => $part]);
     $this->browser->headers('Referer', $referer);
 }