/** * @param $data */ public function parseHead($data) { $this->buffer .= $data; if (false !== strpos($this->buffer, "\r\n\r\n")) { list($headers, $bodyBuffer) = explode("\r\n\r\n", $data, 2); // Reset buffer useless now $this->buffer = ""; // extract headers $psrRequest = \GuzzleHttp\Psr7\parse_request($headers); $this->request->onHead($psrRequest); $encoding = $this->request->getHeader("Transfer-Encoding"); if (in_array($this->request->getMethod(), ['GET', 'HEAD'])) { $this->notifyCompleted(); return; } switch ($encoding) { case "chunked": $this->parserCallable = [$this, 'parseChunk']; break; // TODO multipart // TODO multipart default: $this->parserCallable = [$this, 'parseContentLength']; if ($length = $this->request->getHeader("Content-Length")) { $this->contentLength = intval($length); } } // Parse rest of body $this->parse($bodyBuffer); } }
/** * @param HttpdRequest $request * @param HttpdResponse $response * @param array $labels */ protected function dispatch(HttpdRequest $request, HttpdResponse $response, array $labels = []) { $labels['method'] = strtolower($request->getMethod()); if (empty($this->routes)) { $request->subscribeCallback(null, null, function () use($request, $response, $labels) { $this->notifyNext(new HttpdEvent("/httpd/request", ['request' => $request, 'response' => $response], $labels)); }); return; } $info = $this->dispatcher->dispatch($request->getMethod(), $request->getPath()); switch ($info[0]) { case Dispatcher::NOT_FOUND: $response->sendError("Route does not exist", 404); break; case Dispatcher::METHOD_NOT_ALLOWED: $response->sendError("Method not allowed", 405); break; case Dispatcher::FOUND: $labels['method'] = $request->getMethod(); $labels['path'] = $request->getPath(); $labels = array_merge($labels, $info[2]); $callable = $info[1]; $request->setRouteParams($info[2]); // For streamable route, subscribe on event $this->notifyNext(new HttpdEvent("/httpd/request", ['request' => $request, 'response' => $response], $labels)); // On end of request (whole data received) $request->subscribeCallback(null, null, function () use($request, $response, $callable) { $callable($request, $response); }); } }