/** * 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; }
/** * 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); }