public function onOpen(ConnectionInterface $from, RequestInterface $request = null) { echo "New HTTP connection!\n"; //Variables in URLs are not supported in Ratchet for now //See https://github.com/cboden/Ratchet/pull/143 $requestPath = $request->getPath(); $pathParts = explode('/', preg_replace('#^/peerjs/#', '', $requestPath)); //Remove /peerjs $action = array_pop($pathParts); $peerToken = array_pop($pathParts); $peerId = array_pop($pathParts); $key = array_pop($pathParts); $respStatus = 200; $respHeaders = array('X-Powered-By' => \Ratchet\VERSION, 'Access-Control-Allow-Origin' => '*'); $respBody = null; switch ($action) { case 'id': $respHeaders['Content-Type'] = 'text/html'; if ($peerId === null) { do { $peerId = substr(sha1(uniqid('', true) . mt_rand()), 0, self::PEERID_LENGTH); } while ($this->peerServer->peerIdExists($peerId)); } $respBody = $peerId; break; case 'peers': if (self::ALLOW_DISCOVERY) { $peers = $this->peerServer->listPeers(); $list = array(); foreach ($peers as $peer) { $list[] = $peer['id']; } $respBody = $list; } else { $respStatus = 401; // Access denied } break; case 'offer': case 'candidate': case 'answer': case 'leave': //TODO: start streaming? //TODO: start streaming? default: $respStatus = 400; //Bad request } if (is_array($respBody)) { // Encode to JSON $respHeaders['Content-Type'] = 'application/json'; $respBody = json_encode($respBody); } //Send response $response = new Response($respStatus, $respHeaders, (string) $respBody); $from->send((string) $response); $from->close(); }
public function onOpen(ConnectionInterface $from, RequestInterface $request = null) { echo "New HTTP connection!\n"; //Variables in URLs are not supported in Ratchet for now //See https://github.com/cboden/Ratchet/pull/143 $requestPath = $request->getPath(); $pathParts = explode('/', preg_replace('#^/peerjs/#', '', $requestPath)); //Remove /peerjs $action = array_pop($pathParts); $peerToken = array_pop($pathParts); $peerId = array_pop($pathParts); $key = array_pop($pathParts); $respStatus = 200; $respHeaders = array('X-Powered-By' => \Ratchet\VERSION, 'Access-Control-Allow-Origin' => '*'); $respBody = null; switch ($action) { case 'id': $respHeaders['Content-Type'] = 'text/html'; if ($peerId === null) { do { $peerId = sha1(uniqid('', true) . mt_rand()); } while ($this->peerServer->peerIdExists($peerId)); } $respBody = $peerId; break; case 'offer': case 'candidate': case 'answer': case 'leave': //TODO: start streaming? //TODO: start streaming? default: $respStatus = 400; //Bad request } //Send response $response = new Response($respStatus, $respHeaders, (string) $respBody); $from->send((string) $response); $from->close(); }
/** * {@inheritdoc} * @throws \UnexpectedValueException If a controller is not \Ratchet\Http\HttpServerInterface */ public function onOpen(ConnectionInterface $conn, RequestInterface $request = null) { if (null === $request) { throw new \UnexpectedValueException('$request can not be null'); } $context = $this->_matcher->getContext(); $context->setMethod($request->getMethod()); $context->setHost($request->getHost()); try { $route = $this->_matcher->match($request->getPath()); } catch (MethodNotAllowedException $nae) { return $this->close($conn, 403); } catch (ResourceNotFoundException $nfe) { return $this->close($conn, 404); } if (is_string($route['_controller']) && class_exists($route['_controller'])) { $route['_controller'] = new $route['_controller'](); } if (!$route['_controller'] instanceof HttpServerInterface) { throw new \UnexpectedValueException('All routes must implement Ratchet\\Http\\HttpServerInterface'); } $parameters = array(); foreach ($route as $key => $value) { if (is_string($key) && '_' !== substr($key, 0, 1)) { $parameters[$key] = $value; } } $url = Url::factory($request->getPath()); $url->setQuery($parameters); $request->setUrl($url); $conn->controller = $route['_controller']; $conn->controller->onOpen($conn, $request); }
/** * @param RequestInterface|EntityEnclosingRequestInterface $request * @param Credentials $credentials */ public function signRequest($request, $credentials) { $request->setHeader('X-HMB-Signature-Method', self::DEFAULT_METHOD); $request->setHeader('X-HMB-Signature-Version', self::DEFAULT_SIGN_VERSION); $request->setHeader('X-HMB-TimeStamp', time()); $contentMd5 = $request instanceof EntityEnclosingRequestInterface ? md5($request->getBody()) : ''; if ($contentMd5) { $request->setHeader('Content-MD5', $contentMd5); } $sign = array(); $sign[] = strtoupper($request->getMethod()); $sign[] = $request->getHost(); if ($request->getHeader('Content-MD5')) { $sign[] = $request->getHeader('Content-MD5'); } if ($request->getHeader('Content-Type')) { $sign[] = $request->getHeader('Content-Type'); } $sign[] = $request->getHeader('X-HMB-Signature-Method'); $sign[] = $request->getHeader('X-HMB-Signature-Version'); $sign[] = $request->getHeader('X-HMB-TimeStamp'); if ($request->getHeader('X-HMB-User-Session-Token')) { $sign[] = $request->getHeader('X-HMB-User-Session-Token'); } $sign[] = $request->getQuery(true) ? $request->getPath() . '?' . $request->getQuery(true) : $request->getPath(); $signature = base64_encode(hash_hmac(strtolower($request->getHeader('X-HMB-Signature-Method')), implode("\n", $sign), $credentials->getSecret())); $request->setHeader('Authorization', sprintf('%s %s:%s', self::AUTHORIZATION_SCHME, $credentials->getKey(), $signature)); }
public function onOpen(ConnectionInterface $conn, RequestInterface $request = null) { $this->log('open', $conn); $response = new Response(200, array('Content-type' => 'text/javascript', 'Content-Length' => $this->getFilesize($request->getPath()))); $response->setBody($this->getContent($request->getPath())); $conn->send((string) $response); $conn->close(); }
protected function invokeWrappedIfEntityEnclosed($method, array $params = []) { if (!$this->wrapped instanceof EntityEnclosingRequestInterface) { throw new BadMethodCallException(sprintf('Cannot call method "%s" on a request that does not enclose an entity.' . ' Did you expect a POST/PUT request instead of %s %s?', $method, $this->wrapped->getMethod(), $this->wrapped->getPath())); } return call_user_func_array([$this->wrapped, $method], $params); }
/** * Add cookies to a request based on the destination of the request and * the cookies stored in the storage backend. Any previously set cookies * will be removed. * * @param RequestInterface $request Request to add cookies to. If the * request object already has a cookie header, then no further cookies * will be added. * * @return array Returns an array of the cookies that were added */ public function addCookies(RequestInterface $request) { $request->removeHeader('Cookie'); // Find cookies that match this request $cookies = $this->jar->getCookies($request->getHost(), $request->getPath()); $match = false; if ($cookies) { foreach ($cookies as $cookie) { $match = true; // If a port restriction is set, validate the port if (!empty($cookie['port'])) { if (!in_array($request->getPort(), $cookie['port'])) { $match = false; } } // Validate the secure flag if ($cookie['secure']) { if ($request->getScheme() != 'https') { $match = false; } } // If this request is eligible for the cookie, then merge it in if ($match) { $request->addCookie($cookie['cookie'][0], isset($cookie['cookie'][1]) ? $cookie['cookie'][1] : null); } } } return $match && $cookies ? $cookies : array(); }
/** * {@inheritdoc} */ public function onOpen(ConnectionInterface $conn, RequestInterface $request = null) { if (null === $request) { throw new \UnexpectedValueException('$request can not be null'); } $context = $this->_matcher->getContext(); $context->setMethod($request->getMethod()); $context->setHost($request->getHost()); try { $parameters = $this->_matcher->match($request->getPath()); } catch (MethodNotAllowedException $nae) { return $this->close($conn, 403); } catch (ResourceNotFoundException $nfe) { return $this->close($conn, 404); } if ($parameters['_controller'] instanceof ServingCapableInterface) { $parameters['_controller']->serve($conn, $request, $parameters); } else { $query = array(); foreach ($query as $key => $value) { if (is_string($key) && '_' !== substr($key, 0, 1)) { $query[$key] = $value; } } $url = Url::factory($request->getPath()); $url->setQuery($query); $request->setUrl($url); $conn->controller = $parameters['_controller']; $conn->controller->onOpen($conn, $request); } }
/** * @param Guzzle\Http\Message\RequestInterface * @return Guzzle\Http\Message\Response */ public function handshake(RequestInterface $request) { $body = $this->sign($request->getHeader('Sec-WebSocket-Key1', true), $request->getHeader('Sec-WebSocket-Key2', true), (string) $request->getBody()); $headers = array('Upgrade' => 'WebSocket', 'Connection' => 'Upgrade', 'Sec-WebSocket-Origin' => $request->getHeader('Origin', true), 'Sec-WebSocket-Location' => 'ws://' . $request->getHeader('Host', true) . $request->getPath()); $response = new Response(101, $headers, $body); $response->setStatus(101, 'WebSocket Protocol Handshake'); return $response; }
public function onOpen(ConnectionInterface $from, RequestInterface $request = null) { $requestPath = $request->getPath(); $pathParts = explode('/', preg_replace('#^/peerjs/#', '', $requestPath)); //Remove /peerjs $action = array_pop($pathParts); $query = $request->getQuery(); $peerId = isset($query['id']) ? $query['id'] : null; $peerToken = isset($query['token']) ? $query['token'] : null; $respStatus = 200; $respHeaders = array('Access-Control-Allow-Origin' => '*'); $respBody = null; switch ($action) { case 'id': $respHeaders['Content-Type'] = 'text/html'; if ($peerId === null) { do { $peerId = substr(sha1(uniqid('', true) . mt_rand()), 0, self::PEERID_LENGTH); } while ($this->peerServer->peerIdExists($peerId)); } $respBody = $peerId; break; case 'peers': if (self::ALLOW_DISCOVERY) { $peers = $this->peerServer->listPeers(); $list = array(); foreach ($peers as $peer) { $list[] = $peer['id']; } $respBody = $list; } else { $respStatus = 401; // Access denied } break; case 'offer': case 'candidate': case 'answer': case 'leave': //TODO: start streaming? //TODO: start streaming? default: $respStatus = 400; //Bad request } if (is_array($respBody)) { // Encode to JSON $respHeaders['Content-Type'] = 'application/json'; $respBody = json_encode($respBody); } //Send response $response = new Response($respStatus, $respHeaders, (string) $respBody); $from->send((string) $response); $from->close(); }
/** * @param \Guzzle\Http\Message\RequestInterface $request * @return \Guzzle\Http\Message\Response * @throws \UnderflowException If there hasn't been enough data received */ public function handshake(RequestInterface $request) { $body = substr($request->getBody(), 0, 8); if (8 !== strlen($body)) { throw new \UnderflowException("Not enough data received to issue challenge response"); } $challenge = $this->sign((string) $request->getHeader('Sec-WebSocket-Key1'), (string) $request->getHeader('Sec-WebSocket-Key2'), $body); $headers = array('Upgrade' => 'WebSocket', 'Connection' => 'Upgrade', 'Sec-WebSocket-Origin' => (string) $request->getHeader('Origin'), 'Sec-WebSocket-Location' => 'ws://' . (string) $request->getHeader('Host') . $request->getPath()); $response = new Response(101, $headers, $challenge); $response->setStatus(101, 'WebSocket Protocol Handshake'); return $response; }
/** * Given an array of the headers this method will run through all verification methods * @param \Guzzle\Http\Message\RequestInterface $request * @return bool TRUE if all headers are valid, FALSE if 1 or more were invalid */ public function verifyAll(RequestInterface $request) { $passes = 0; $passes += (int) $this->verifyMethod($request->getMethod()); $passes += (int) $this->verifyHTTPVersion($request->getProtocolVersion()); $passes += (int) $this->verifyRequestURI($request->getPath()); $passes += (int) $this->verifyHost((string) $request->getHeader('Host')); $passes += (int) $this->verifyUpgradeRequest((string) $request->getHeader('Upgrade')); $passes += (int) $this->verifyConnection((string) $request->getHeader('Connection')); $passes += (int) $this->verifyKey((string) $request->getHeader('Sec-WebSocket-Key')); //$passes += (int)$this->verifyVersion($headers['Sec-WebSocket-Version']); // Temporarily breaking functionality return 7 === $passes; }
/** * Sign the Pusher request * * @link http://pusher.com/docs/rest_api#authentication * @param RequestInterface $request * @param Credentials $credentials */ public function signRequest(RequestInterface $request, Credentials $credentials) { $queryParameters = array('auth_key' => $credentials->getKey(), 'auth_timestamp' => time(), 'auth_version' => self::AUTH_VERSION); if ($request instanceof EntityEnclosingRequestInterface) { $body = $request->getBody(); $queryParameters['body_md5'] = $body->getContentLength() ? $body->getContentMd5() : ''; } // The signature algorithm asks that keys are all lowercased $queryParameters = array_change_key_case($request->getQuery()->toArray()) + $queryParameters; $queryParameters = array_filter($queryParameters); ksort($queryParameters); $method = strtoupper($request->getMethod()); $requestPath = $request->getPath(); $query = urldecode(http_build_query($queryParameters)); $signature = $this->signString(implode("\n", array($method, $requestPath, $query)), $credentials); $queryParameters['auth_signature'] = $signature; $request->getQuery()->replace($queryParameters); }
/** * Calculate the hash key of a request object * * @param RequestInterface $request Request to hash * @param string $raw Set to TRUE to retrieve the un-encoded string for debugging * * @return string */ public function getCacheKey(RequestInterface $request, $raw = false) { // See if the key has already been calculated $key = $request->getParams()->get('cache.key'); // Always recalculate when using the raw option if (!$key || $raw) { // Generate the start of the key $key = $request->getMethod() . '_' . $request->getScheme() . '_' . $request->getHost() . $request->getPath(); $filterHeaders = array('Cache-Control'); $filterQuery = array(); // Check to see how and if the key should be filtered foreach (explode(';', $request->getParams()->get('cache.key_filter')) as $part) { $pieces = array_map('trim', explode('=', $part)); if (isset($pieces[1])) { $remove = array_map('trim', explode(',', $pieces[1])); if ($pieces[0] == 'header') { $filterHeaders = array_merge($filterHeaders, $remove); } elseif ($pieces[0] == 'query') { $filterQuery = array_merge($filterQuery, $remove); } } } // Use the filtered query string $queryString = (string) $request->getQuery()->filter(function ($key, $value) use($filterQuery) { return !in_array($key, $filterQuery); }); // Use the filtered headers $headerString = http_build_query($request->getHeaders()->map(function ($key, $value) { return count($value) == 1 ? $value[0] : $value; })->filter(function ($key, $value) use($filterHeaders) { return !in_array($key, $filterHeaders); })->getAll()); if ($raw) { $key = strtolower('gz_' . $key . $queryString . '_' . $headerString); } else { $key = strtolower('gz_' . md5($key . $queryString . '_' . $headerString)); $request->getParams()->set('cache.key', $key); } } return $key; }
/** * {@inheritdoc} * @throws \UnexpectedValueException If a controller is not \Ratchet\Http\HttpServerInterface */ public function onOpen(ConnectionInterface $conn, RequestInterface $request = null) { if (null === $request) { throw new \UnexpectedValueException('$request can not be null'); } $context = $this->_matcher->getContext(); $context->setMethod($request->getMethod()); $context->setHost($request->getHost()); try { $route = $this->_matcher->match($request->getPath()); } catch (MethodNotAllowedException $nae) { return $this->close($conn, 403); } catch (ResourceNotFoundException $nfe) { return $this->close($conn, 404); } if (is_string($route['_controller']) && class_exists($route['_controller'])) { $route['_controller'] = new $route['_controller'](); } if (!$route['_controller'] instanceof HttpServerInterface) { throw new \UnexpectedValueException('All routes must implement Ratchet\\Http\\HttpServerInterface'); } $conn->controller = $route['_controller']; $conn->controller->onOpen($conn, $request); }
/** * Create a canonicalized resource for a request * * @param RequestInterface $request Request for the resource * * @return string */ protected function createCanonicalizedResource(RequestInterface $request) { // If this is a virtual hosted bucket, then append the bucket name $host = $request->getHost(); $parts = explode('.', $host); $totalParts = count($parts); if ($parts[$totalParts - 2] !== 'amazonaws') { // The host does not contain S3, so it must be a CNAME $buffer = '/' . $host; } elseif ($totalParts > 3) { // The host contains more than three parts, so it is a virtual hosted bucket $buffer = '/' . implode('.', array_slice($parts, 0, -3)); } else { // The host does not contain any bucket information $buffer = ''; } $buffer .= $request->getPath(); $buffer = str_replace('//', '/', $buffer); // Add sub resource parameters $query = $request->getQuery(); $first = true; foreach ($this->signableQueryString as $key) { if ($value = $query->get($key)) { $buffer .= $first ? '?' : '&'; $first = false; $buffer .= $key; if ($value !== QueryString::BLANK) { $buffer .= "={$value}"; } } } return $buffer; }
/** * {@inheritdoc} */ public function getMatchingCookies(RequestInterface $request) { // Find cookies that match this request $cookies = $this->all($request->getHost(), $request->getPath()); // Remove ineligible cookies foreach ($cookies as $index => $cookie) { if (!$cookie->matchesPort($request->getPort()) || $cookie->getSecure() && $request->getScheme() != 'https') { unset($cookies[$index]); } } return $cookies; }
/** * @return string */ public function getPath() { return $this->request->getPath(); }
/** * Overrides the parent class to prevent the removal of dot-segments */ protected function normalizePath(RequestInterface $request) { return '/' . ltrim($request->getPath(), '/'); }
/** * Collect & sanitize data about a Guzzle request * * @param Guzzle\Http\Message\RequestInterface $request * * @return array */ private function collectRequest(GuzzleRequestInterface $request) { $body = null; if ($request instanceof EntityEnclosingRequestInterface) { $body = (string) $request->getBody(); } return array('headers' => $request->getHeaders(), 'method' => $request->getMethod(), 'scheme' => $request->getScheme(), 'host' => $request->getHost(), 'port' => $request->getPort(), 'path' => $request->getPath(), 'query' => $request->getQuery(), 'body' => $body); }
/** * Create the canonical representation of a request * * @param RequestInterface $request Request to canonicalize * @param string $payload Request payload (typically the value * of the x-amz-content-sha256 header. * * @return array Returns an array of context information including: * - canonical_request * - signed_headers */ private function createSigningContext(RequestInterface $request, $payload) { // Normalize the path as required by SigV4 and ensure it's absolute $canon = $request->getMethod() . "\n" . '/' . ltrim($request->getPath(), '/') . "\n" . $this->getCanonicalizedQueryString($request) . "\n"; // Create the canonical headers $headers = array(); foreach ($request->getHeaders()->getAll() as $key => $values) { $key = strtolower($key); if ($key != 'user-agent') { $headers[$key] = array(); foreach ($values as $value) { $headers[$key][] = preg_replace('/\\s+/', ' ', trim($value)); } // Sort the value if there is more than one if (count($values) > 1) { sort($headers[$key]); } } } // The headers must be sorted ksort($headers); // Continue to build the canonical request by adding headers foreach ($headers as $key => $values) { // Combine multi-value headers into a comma separated list $canon .= $key . ':' . implode(',', $values) . "\n"; } // Create the signed headers $signedHeaders = implode(';', array_keys($headers)); $canon .= "\n{$signedHeaders}\n{$payload}"; return array('canonical_request' => $canon, 'signed_headers' => $signedHeaders); }
protected function onRequest(ConnectionInterface $from, RequestInterface $request) { $requestPath = $request->getPath(); $body = (string) $request->getBody(); if (!empty($body)) { $query = QueryString::fromString($body); $fields = $query->getAll(); $request->addPostFields($fields); } // TODO: use only $req->acceptLanguage() in Managers $_SERVER['HTTP_ACCEPT_LANGUAGE'] = (string) $request->getHeaders()->get('accept-language'); $routes = array('/' => 'executeUiBooter', '/api' => 'executeApiCall', '/api/group' => 'executeApiCallGroup', '/sbin/apicall.php' => 'executeApiCall', '/sbin/apicallgroup.php' => 'executeApiCallGroup', '/sbin/rawdatacall.php' => 'executeRawDataCall', '#^/([a-zA-Z0-9-_.]+)\\.html$#' => 'executeUiBooter', '#^/(bin|boot|etc|home|tmp|usr|var)/(.*)$#' => 'executeReadFile', '/webos.webapp' => 'executeReadManifest', '/hello' => 'executeSayHello'); foreach ($routes as $path => $method) { $matched = false; if (substr($path, 0, 1) == '#') { // Regex if (preg_match($path, $requestPath, $matches)) { $result = $this->{$method}($from, $request, $matches); $matched = true; } } else { if ($path == $requestPath) { $result = $this->{$method}($from, $request); $matched = true; } } if ($matched) { if (empty($result)) { $result = ''; } if ($result instanceof ResponseContent) { $result = $result->generate(); } if ($result instanceof HTTPServerResponse) { if ($result->headersSent()) { // Implicit mode, content already sent if ($result->getHeader('Connection') != 'keep-alive') { $from->close(); } } else { $result->send(); } return; } $response = null; if (is_string($result)) { $response = new Response(200, array(), (string) $result); } else { $response = $result; } $from->send((string) $response); $from->close(); return; } } $resp = new Response(404, array('Content-Type' => 'text/plain'), '404 Not Found'); $from->send((string) $resp); $from->close(); }
/** * Amazon S3 does not double-encode the path component in the canonical req */ protected function createCanonicalizedPath(RequestInterface $request) { return '/' . ltrim($request->getPath(), '/'); }
/** * Tries to find and return the application for the passed request. * * @param \Guzzle\Http\Message\RequestInterface $request The request to find and return the application instance for * * @return \AppserverIo\Psr\Application\ApplicationInterface The application instance * @throws \AppserverIo\Lab\WebSocketProtocol\BadRequestException Is thrown if no application can be found for the passed application name */ public function findApplication(RequestInterface $request) { // load the path information and the server name $pathInfo = $request->getPath(); // initialize the handler path $request->setHandlerPath($request->getPath()); // strip the leading slash and explode the application name list($applicationName, ) = explode('/', substr($pathInfo, 1)); // if not, check if the request matches a folder if (array_key_exists($applicationName, $this->applications)) { // load the application from the array $application = $this->applications[$applicationName]; } else { throw new BadRequestException("Can't find application for '{$applicationName}'"); } // inject the application context into the handler request $request->injectContext($application); // return, because request has been prepared successfully return $application; }
protected function createCanonicalizedPath(RequestInterface $request) { $doubleEncoded = rawurlencode(ltrim($request->getPath(), '/')); return '/' . str_replace('%2F', '/', $doubleEncoded); }