/** * Send the HTTP request and return an HTTP response object * * @param null|string $method * * @throws \EasyRdf\Exception * @return Response */ public function request($method = null) { if (!$this->uri) { throw new Exception("Set URI before calling Client->request()"); } if ($method) { $this->setMethod($method); } $this->redirectCounter = 0; $response = null; // Send the first request. If redirected, continue. do { // Clone the URI and add the additional GET parameters to it $uri = parse_url($this->uri); if ($uri['scheme'] === 'http') { $host = $uri['host']; } elseif ($uri['scheme'] === 'https') { $host = 'ssl://' . $uri['host']; } else { throw new Exception("Unsupported URI scheme: " . $uri['scheme']); } if (isset($uri['port'])) { $port = $uri['port']; } else { if ($uri['scheme'] === 'https') { $port = 443; } else { $port = 80; } } if (!empty($this->paramsGet)) { if (!empty($uri['query'])) { $uri['query'] .= '&'; } else { $uri['query'] = ''; } $uri['query'] .= http_build_query($this->paramsGet, null, '&'); } $headers = $this->prepareHeaders($uri['host'], $port); // Open socket to remote server $socket = @fsockopen($host, $port, $errno, $errstr, $this->config['timeout']); if (!$socket) { throw new Exception("Unable to connect to {$host}:{$port} ({$errstr})"); } stream_set_timeout($socket, $this->config['timeout']); $info = stream_get_meta_data($socket); // Write the request $path = $uri['path']; if (empty($path)) { $path = '/'; } if (isset($uri['query'])) { $path .= '?' . $uri['query']; } fwrite($socket, "{$this->method} {$path} HTTP/1.1\r\n"); foreach ($headers as $k => $v) { if (is_string($k)) { $v = ucfirst($k) . ": {$v}"; } fwrite($socket, "{$v}\r\n"); } fwrite($socket, "\r\n"); // Send the request body, if there is one set if (isset($this->rawPostData)) { fwrite($socket, $this->rawPostData); } // Read in the response $content = ''; while (!feof($socket) && !$info['timed_out']) { $content .= fgets($socket); $info = stream_get_meta_data($socket); } if ($info['timed_out']) { throw new Exception("Request to {$host}:{$port} timed out"); } // FIXME: support HTTP/1.1 100 Continue // Close the socket @fclose($socket); // Parse the response string $response = Response::fromString($content); // If we got redirected, look for the Location header if ($response->isRedirect() && ($location = $response->getHeader('location'))) { // Avoid problems with buggy servers that add whitespace at the // end of some headers (See ZF-11283) $location = trim($location); // Some servers return relative URLs in the location header // resolve it in relation to previous request $baseUri = new ParsedUri($this->uri); $location = $baseUri->resolve($location)->toString(); // If it is a 303 then drop the parameters and send a GET request if ($response->getStatus() == 303) { $this->resetParameters(); $this->setMethod('GET'); } // If we got a well formed absolute URI if (parse_url($location)) { $this->setHeaders('host', null); $this->setUri($location); } else { throw new Exception("Failed to parse Location header returned by " . $this->uri); } ++$this->redirectCounter; } else { // If we didn't get any location, stop redirecting break; } } while ($this->redirectCounter < $this->config['maxredirects']); return $response; }
/** * Parse HTTP-response object into a meaningful result-object. * * Can be overridden to do custom processing * * @param Http\Response|\Zend\Http\Response $response * @return Graph|Result */ protected function parseResponseToQuery($response) { list($content_type, ) = Utils::parseMimeType($response->getHeader('Content-Type')); if (strpos($content_type, 'application/sparql-results') === 0) { $result = new Result($response->getBody(), $content_type); return $result; } else { $result = new Graph($this->queryUri, $response->getBody(), $content_type); return $result; } }