/** * {@inheritdoc} */ public function call() { $method = $this->request->getMethod(); $call = strtolower($method); $params = $this->params($method); if ($params === false || $params === null || !is_callable(array($this, $call))) { throw new GraphException("Method not allowed", HttpResponse::HTTP_METHOD_NOT_ALLOWED); } return $this->{$call}(new ParameterBag((array) $params)); }
/** * Handles graph requests * * /graph/<node>[/<edge>] * * @param array $segments URL segments * @return bool */ public function pageHandler($segments) { elgg_register_plugin_hook_handler('debug', 'log', array($this->logger, 'debugLogHandler')); error_reporting(E_ALL); set_error_handler(array($this->logger, 'errorHandler')); set_exception_handler(array($this->logger, 'exceptionHandler')); try { if ($this->request->getUrlSegments()[0] == 'services') { elgg_trigger_plugin_hook('auth', 'graph'); } else { // graph page handler is being accessed directly, and not routed to from services // check csrf tokens action_gatekeeper(''); if ($this->request->getMethod() != HttpRequest::METHOD_GET) { elgg_gatekeeper(); } } elgg_set_context('services'); elgg_push_context('api'); elgg_push_context('graph'); $viewtype = $this->mapViewtype(); $endpoint = implode('/', $segments); if (!elgg_is_registered_viewtype($viewtype)) { $viewtype = 'json'; } elgg_set_viewtype($viewtype); $result = $this->route($endpoint); } catch (Exception $ex) { $result = new ErrorResult($ex->getMessage(), $ex->getCode(), $ex); } $this->send($result); return true; }
/** * @inheritdoc */ public function format(HttpRequest $request) { $data = (array) $request->getData(); $content = http_build_query($data, '', '&', $this->encodingType); if (strcasecmp('get', $request->getMethod()) === 0) { if (!empty($content)) { $url = $request->getUrl(); $url .= strpos($url, '?') === false ? '?' : '&'; $url .= $content; $request->setUrl($url); } return $request; } $request->addHeader('Content-Type', 'application/x-www-form-urlencoded'); $request->setContent($content); return $request; }
/** * Executes an HTTP transaction and returns the response. * * @param HttpRequest $request * @return HttpResponse */ public function getResponse(HttpRequest $request) { $uri = $request->getUrl(); $headers = $request->getHeaders(); $flatHeaders = []; foreach ($headers as $key => $value) { $flatHeaders[] = $key . ": " . $value; } $flatHeaders[] = 'Connection: Keep-Alive'; $flatHeaders[] = 'Expect:'; $flatHeaders[] = 'Accept-Language: en-GB'; $flatHeaders[] = 'Cache-Control: no-cache'; $flatHeaders[] = 'User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0)'; $curl = curl_init($uri); curl_setopt($curl, CURLOPT_HEADER, false); $payload = $request->getPayload(); switch ($request->getMethod()) { case "head": curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "HEAD"); break; case "delete": curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "DELETE"); break; case "post": curl_setopt($curl, CURLOPT_POST, true); curl_setopt($curl, CURLOPT_POSTFIELDS, $payload); break; case "put": curl_setopt($curl, CURLOPT_POST, true); curl_setopt($curl, CURLOPT_POSTFIELDS, $payload); curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "PUT"); break; } curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($curl, CURLOPT_HTTPHEADER, $flatHeaders); curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); $response = curl_exec($curl); $responseCode = curl_getinfo($curl, CURLINFO_HTTP_CODE); curl_close($curl); $httpResponse = new HttpResponse(); $httpResponse->setResponseBody($response); $httpResponse->setResponseCode($responseCode); return $httpResponse; }
/** * Check that authenticated consumer and user can access the endpoint * * @param string $hook "permissions_check:graph" * @param string $route Route * @param bool $return Current permission * @param array $params Hook params * @return bool Filtered permission */ public function checkAccess($hook, $route, $return, $params) { $request_type = $this->request->getMethod(); $request = "{$request_type} /{$route}"; $user_auth_exceptions = array('POST /:site/users'); if (!in_array($request_type, array(HttpRequest::METHOD_GET, HttpRequest::METHOD_HEAD)) && !in_array($request, $user_auth_exceptions)) { return elgg_is_logged_in(); } $consumer = $this->session->consumer(); if (!$consumer) { return $return; } $ia = elgg_set_ignore_access(true); $endpoints = (array) $consumer->endpoints; elgg_set_ignore_access($ia); if (!in_array($request, $endpoints)) { return false; } return $return; }
function threadmain() { // Read request block $buf = ""; while (true) { $rl = socket_read($this->sock, 4096, PHP_BINARY_READ); if (false == $rl) { socket_close($this->sock); return; } else { $buf = $buf . $rl; } if (strpos($buf, "\r\n\r\n")) { break; } else { console::writeLn('%s', $buf); } } $db = explode("\r\n\r\n", $buf); $data = $db[0]; // Put back the rest of the buffer for posts etc $buf = join('', array_slice($db, 1)); $request = new HttpRequest($data); // data $response = new HttpResponse(); // Pop the header off the buffer $status = call_user_func_array($this->handler, array(&$request, &$response)); if ($status == 0) { $status = 200; } $peer = ""; $port = 0; socket_getpeername($this->sock, $peer, $port); console::writeLn("%s %s:%d %d %s", $request->getMethod(), $peer, $port, $status, $request->getUri()); $response->writeHeaders($this->sock, 200); $response->writeContent($this->sock); socket_shutdown($this->sock, 2); usleep(50000); socket_close($this->sock); }
/** * Request test. * @return void */ public function testRequest() { $_SERVER = array('HTTPS' => 'On', 'HTTP_HOST' => 'nettephp.com:8080', 'QUERY_STRING' => 'x param=val.&pa%%72am=val2¶m3=v%20a%26l%3Du%2Be)', 'REMOTE_ADDR' => '192.168.188.66', 'REQUEST_METHOD' => 'GET', 'REQUEST_URI' => '/file.php?x param=val.&pa%%72am=val2¶m3=v%20a%26l%3Du%2Be)', 'SCRIPT_FILENAME' => '/public_html/www/file.php', 'SCRIPT_NAME' => '/file.php'); $request = new HttpRequest(); $request->addUriFilter('%20', '', PHP_URL_PATH); $request->addUriFilter('[.,)]$'); $this->assertEquals('GET', $request->getMethod()); $this->assertEquals(TRUE, $request->isSecured()); $this->assertEquals('192.168.188.66', $request->getRemoteAddress()); $this->assertEquals('/file.php', $request->getUri()->scriptPath); $this->assertEquals('https', $request->getUri()->scheme); $this->assertEquals('', $request->getUri()->user); $this->assertEquals('', $request->getUri()->pass); $this->assertEquals('nettephp.com', $request->getUri()->host); $this->assertEquals(8080, $request->getUri()->port); $this->assertEquals('/file.php', $request->getUri()->path); $this->assertEquals("pa%ram=val2¶m3=v a%26l%3Du%2Be&x param=val.", $request->getUri()->query); $this->assertEquals('', $request->getUri()->fragment); $this->assertEquals('nettephp.com:8080', $request->getUri()->authority); $this->assertEquals('https://nettephp.com:8080', $request->getUri()->hostUri); $this->assertEquals('https://nettephp.com:8080/', $request->getUri()->baseUri); $this->assertEquals('/', $request->getUri()->basePath); $this->assertEquals('file.php', $request->getUri()->relativeUri); $this->assertEquals("https://nettephp.com:8080/file.php?pa%ram=val2¶m3=v a%26l%3Du%2Be&x param=val.", $request->getUri()->absoluteUri); $this->assertEquals('', $request->getUri()->pathInfo); $this->assertEquals('https', $request->getOriginalUri()->scheme); $this->assertEquals('', $request->getOriginalUri()->user); $this->assertEquals('', $request->getOriginalUri()->pass); $this->assertEquals('nettephp.com', $request->getOriginalUri()->host); $this->assertEquals(8080, $request->getOriginalUri()->port); $this->assertEquals('/file.php', $request->getOriginalUri()->path); $this->assertEquals('x param=val.&pa%%72am=val2¶m3=v%20a%26l%3Du%2Be)', $request->getOriginalUri()->query); $this->assertEquals('', $request->getOriginalUri()->fragment); $this->assertEquals('val.', $request->getQuery('x_param')); $this->assertEquals('val2', $request->getQuery('pa%ram')); $this->assertEquals('v a&l=u+e', $request->getQuery('param3')); $this->assertEquals('', $request->getPostRaw()); $this->assertEquals('nettephp.com:8080', $request->headers['host']); }
/** * Signs request with signature v3 * * @param \HttpRequest $request Http request * @param string $subdomain optional A subdomain */ protected function signRequestV3($request, $subdomain = null) { $time = time(); //Gets the http method name $httpMethod = self::$httpMethods[$request->getMethod()]; $components = parse_url($request->getUrl()); //Retrieves headers from request $options = $request->getHeaders(); //Adding timestamp if (!isset($options['Date'])) { $options['Date'] = gmdate('r', $time); $request->addHeaders(['Date' => $options['Date']]); } //This also includes a mock objects which look like "Mock_S3QueryClient_d65a1dc1". if (preg_match('#(?<=[_\\\\])S3QueryClient(?=_|$)#', get_class($this))) { $amzHeaders = []; foreach ($options as $key => $val) { if (preg_match('/^x-amz-/i', $key)) { //Saves amz headers which are used to sign the request $amzHeaders[strtolower($key)] = $val; } } //S3 Client has a special Authorization string $canonicalizedAmzHeaders = ''; if (!empty($amzHeaders)) { ksort($amzHeaders); foreach ($amzHeaders as $k => $v) { $canonicalizedAmzHeaders .= $k . ':' . trim(preg_replace('/#( *[\\r\\n]+ *)+#/', ' ', $v)) . "\n"; } } //Note that in case of multiple sub-resources, sub-resources must be lexicographically sorted //by sub-resource name and separated by '&'. e.g. ?acl&versionId=value. if (!empty($components['query'])) { $canonPath = $components['path'] . '?'; parse_str($components['query'], $subresources); ksort($subresources); $allowed = $this->getAllowedSubResources(); foreach ($subresources as $k => $v) { if (in_array($k, $allowed)) { $canonPath .= $k . ($v !== '' ? '=' . $v : '') . '&'; } } $canonPath = substr($canonPath, 0, -1); } $canonicalizedResource = (isset($subdomain) ? '/' . strtolower($subdomain) : '') . (isset($canonPath) ? $canonPath : $components['path'] . (!empty($components['query']) ? '?' . $components['query'] : '') . (!empty($components['fragment']) ? '#' . $components['fragment'] : '')); $stringToSign = $httpMethod . "\n" . (!empty($options['Content-Md5']) ? $options['Content-Md5'] . '' : '') . "\n" . (!empty($options['Content-Type']) ? $options['Content-Type'] . '' : '') . "\n" . (isset($amzHeaders['x-amz-date']) ? '' : $options['Date'] . "\n") . $canonicalizedAmzHeaders . $canonicalizedResource; $options['Authorization'] = "AWS " . $this->awsAccessKeyId . ":" . base64_encode(hash_hmac('sha1', $stringToSign, $this->secretAccessKey, 1)); } else { $options['Authorization'] = "AWS " . $this->awsAccessKeyId . ":" . base64_encode(hash_hmac('sha1', $options['Date'], $this->secretAccessKey, 1)); } $request->addHeaders(['Authorization' => $options['Authorization']]); }
/** * Signs request with signature version 2 * * Only POST http method is supported * * @param \HttpRequest $request Http request object * @throws QueryClientException */ protected function signRequestV2($request) { $time = time(); //Gets the http method name $httpMethod = self::$httpMethods[$request->getMethod()]; //Gets both host and path from the url $components = parse_url($request->getUrl()); $common = ['AWSAccessKeyId' => $this->awsAccessKeyId, 'SignatureVersion' => '2', 'SignatureMethod' => 'HmacSHA1', 'Timestamp' => gmdate('Y-m-d\\TH:i:s', $time) . "Z"]; $request->addPostFields($common); //Gets adjusted options $options = $request->getPostFields(); //Calculating canonicalized query string ksort($options); $canonicalizedQueryString = ''; foreach ($options as $k => $v) { $canonicalizedQueryString .= '&' . rawurlencode($k) . '=' . rawurlencode($v); } $canonicalizedQueryString = ltrim($canonicalizedQueryString, '&'); $stringToSign = $httpMethod . "\n" . strtolower($components['host']) . "\n" . $components['path'] . "\n" . $canonicalizedQueryString; switch ($common['SignatureMethod']) { case 'HmacSHA1': case 'HmacSHA256': $algo = strtolower(substr($common['SignatureMethod'], 4)); break; default: throw new QueryClientException('Unknown SignatureMethod ' . $common['SignatureMethod']); } $request->addPostFields(['Signature' => base64_encode(hash_hmac($algo, $stringToSign, $this->secretAccessKey, 1))]); $request->addHeaders(['X-Amz-Date' => gmdate(\DateTime::ISO8601, $time)]); }
private function readBody() { // head only if ($this->req->getMethod() === 'HEAD') { return $this->finish(); } // chunked $res = $this->res; $conn = $this->conn; $length = $res->getHeader('content-length'); $encoding = $res->getHeader('transfer-encoding'); if ($encoding !== null && !strcasecmp($encoding, 'chunked')) { // unfinished chunk if ($this->chunkLeft > 0) { $buf = $conn->read($this->chunkLeft); if ($buf === false) { return $this->finish('BROKEN'); } if (is_string($buf)) { HttpClient::debug('read chunkLeft(', $this->chunkLeft, ')=', strlen($buf)); $res->body .= $buf; $this->chunkLeft -= strlen($buf); if ($this->chunkLeft === 0) { // strip CRLF $res->body = substr($res->body, 0, -2); } } if ($this->chunkLeft > 0) { return; } } // next chunk while (($line = $conn->getLine()) !== null) { if ($line === false) { return $this->finish('BROKEN'); } HttpClient::debug('read chunk line: ', $line); if (($pos = strpos($line, ';')) !== false) { $line = substr($line, 0, $pos); } $size = intval(hexdec(trim($line))); if ($size <= 0) { while ($line = $conn->getLine()) { if ($line === '') { break; } HttpClient::debug('read tailer line: ', $line); if (($pos = strpos($line, ':')) !== false) { $res->addHeader(substr($line, 0, $pos), trim(substr($line, $pos + 1))); } } return $this->finish(); } // add CRLF, save to chunkLeft for next loop $this->chunkLeft = $size + 2; // add CRLF return; } } else { if ($length !== null) { $size = intval($length) - strlen($res->body); if ($size > 0) { $buf = $conn->read($size); if ($buf === false) { return $this->finish('BROKEN'); } if (is_string($buf)) { HttpClient::debug('read fixedBody(', $size, ')=', strlen($buf)); $res->body .= $buf; $size -= strlen($buf); } } if ($size === 0) { return $this->finish(); } } else { if ($res->body === '') { $res->setHeader('connection', 'close'); } if (($buf = $conn->read()) === false) { return $this->finish(); } if (is_string($buf)) { HttpClient::debug('read streamBody()=', strlen($buf)); $res->body .= $buf; } } } }
/** * Parses the supplied request uri based on the supplied routes and * the request method. * * Routes should be of the following format: * * <code> * $routes = array( * array( * mixed $request_method, string $request_uri, callable $callback * ), * ... * ); * </code> * * where: * * <code> * $request_method can be a string ('GET', 'POST', 'PUT', 'DELETE'), * or an array (e.g., array('GET, 'POST')). Note that $request_method * is case-insensitive. * </code> * * <code> * $request_uri is a string, with optional match types. Valid match types * are as follows: * * [i] - integer * [a] - alphanumeric * [h] - hexadecimal * [*] - anything * * Match types can be combined with parameter names, which will be * captured: * * [i:id] - will match an integer, storing it within the returned 'params' * array under the 'id' key * [a:name] - will match an alphanumeric value, storing it within the * returned 'params' array under the 'name' key * * Here are some examples to help illustrate: * * /post/[i:id] - will match on /post/32 (with the returned 'params' array * containing an 'id' key with a value of 32), but will not match on * /post/today * * /find/[h:serial] - will match on /find/ae32 (with the returned 'params' * array containing a 'serial' key will a value of 'ae32'), but will not * match on /find/john * </code> * * <code> * $callback is a valid callback function. * </code> * * Returns an array containing the following keys: * * * 'params' - The parameters collected from the matched uri * * 'callback' - The callback function pulled from the matched route * * @access public * @param string $requestUri The request uri. * @param string $requestMethod The request method. * @param Route[] $routes The routes. * @return array */ public function parse(HttpRequest $request, $routes) { foreach ($routes as $route) { if (!$route instanceof Route) { throw new \LogicException(sprintf('The route given don\'t is instance of Route. Type given "%s".', gettype($route))); } list($methods, $patternUri, $action) = array($route->getMethods(), $route->getPatternUri(), $route->getAction()); if (is_array($methods)) { $found = false; foreach ($methods as $method) { if (strcasecmp($request->getMethod(), $method) == 0) { $found = true; break; } elseif (($method === strtolower('ajax') || $method === strtolower('xhr')) && $request->isAjax()) { $found = true; break; } } if (!$found) { continue; } } elseif (strcasecmp($request->getMethod(), $methods) != 0) { continue; } elseif (($methods === strtolower('ajax') || $methods === strtolower('xhr')) && $request->isAjax()) { continue; } if (is_null($patternUri) || $patternUri == '*') { $found = false; $params = array(); return compact('action', 'found', 'params'); } $found = true; $routeToMatch = ''; $len = strlen($patternUri); $requestUri = $request->url; for ($i = 0; $i < $len; $i++) { $char = $patternUri[$i]; $is_regex = $char == '[' || $char == '(' || $char == '.' || $char == '?' || $char == '+' || $char == '{'; if ($is_regex) { $routeToMatch = $patternUri; break; } elseif (!isset($requestUri[$i]) || $char != $requestUri[$i]) { continue 2; } $routeToMatch .= $char; } $params = array(); $regex = $this->_compile_regex($routeToMatch); if (preg_match($regex, $requestUri, $paramsMatched)) { foreach ($paramsMatched as $key => $arg) { if (is_numeric($key)) { unset($paramsMatched[$key]); } else { $params[$key] = $arg; } } return compact('action', 'found', 'params'); } } return array('found' => false, 'params' => null, 'action' => null); }
protected function makeHandle(HttpRequest $request, CurlHttpResponse $response) { $handle = curl_init(); Assert::isNotNull($request->getMethod()); $options = array(CURLOPT_WRITEFUNCTION => array($response, 'writeBody'), CURLOPT_HEADERFUNCTION => array($response, 'writeHeader'), CURLOPT_URL => $request->getUrl()->toString(), CURLOPT_USERAGENT => 'onPHP::' . __CLASS__); if ($this->isPhp55()) { $options[CURLOPT_SAFE_UPLOAD] = true; } if ($this->noBody !== null) { $options[CURLOPT_NOBODY] = $this->noBody; } if ($this->followLocation !== null) { $options[CURLOPT_FOLLOWLOCATION] = $this->followLocation; } switch ($request->getMethod()->getId()) { case HttpMethod::GET: $options[CURLOPT_HTTPGET] = true; if ($request->getGet()) { $options[CURLOPT_URL] .= ($request->getUrl()->getQuery() ? '&' : '?') . $this->argumentsToString($request->getGet()); } break; case HttpMethod::POST: if ($request->getGet()) { $options[CURLOPT_URL] .= ($request->getUrl()->getQuery() ? '&' : '?') . $this->argumentsToString($request->getGet()); } $options[CURLOPT_POST] = true; $options[CURLOPT_POSTFIELDS] = $this->getPostFields($request); break; default: $options[CURLOPT_CUSTOMREQUEST] = $request->getMethod()->getName(); break; } $headers = array(); foreach ($request->getHeaderList() as $headerName => $headerValue) { $headers[] = "{$headerName}: {$headerValue}"; } if ($headers) { $options[CURLOPT_HTTPHEADER] = $headers; } if ($request->getCookie()) { $cookies = array(); foreach ($request->getCookie() as $name => $value) { $cookies[] = $name . '=' . urlencode($value); } $options[CURLOPT_COOKIE] = implode('; ', $cookies); } foreach ($this->options as $key => $value) { $options[$key] = $value; } curl_setopt_array($handle, $options); return $handle; }