public function handleInput(&$data, &$errNo) { // What is this? we're getting input while we're sending a reply? if ($this->sendFile) { $this->writeFileReset(); $this->httpRequest = null; } else { if ($this->sendQLen > 0) { $this->sendQReset(); $this->httpRequest = null; } } if (!$this->httpRequest) { $this->httpRequest = new HttpRequest(); } // Pass the incoming data to the HttpRequest class, so it can handle it. if (!$this->httpRequest->handleInput($data)) { // An error was encountered while receiving the requst. // Send reply (unless 444, a special 'direct reject' code) and return false to close this connection. if ($this->httpRequest->errNo != 444) { $r = new HttpResponse('1.1', $this->httpRequest->errNo); $r->addBody($this->createErrorPage($this->httpRequest->errNo, $this->httpRequest->errStr)); if ($this->httpRequest->errNo == 405) { $r->addHeader('Allow: GET, POST, HEAD'); $r->addHeader('Access-Control-Allow-Methods: GET, POST, HEAD'); } $this->write($r->getHeaders()); $this->write($r->getBody()); $this->logRequest($r->getResponseCode(), $r->getHeader('Content-Length') ? $r->getHeader('Content-Length') : 0); } else { $this->logRequest(444, 0); } $errNo = $this->httpRequest->errNo; return false; } // If we have no headers, or we are busy with receiving. // Just return and wait for more data. if (!$this->httpRequest->hasHeaders || $this->httpRequest->isReceiving) { // We're still receiving the body of a request return true; } // Return true to just wait and try again later // At this point we have a fully qualified and parsed HttpRequest // The HttpRequest object contains all info about the headers / GET / POST / COOKIE / FILES // Just finalise it by adding some extra client info. $this->httpRequest->SERVER['REMOTE_ADDR'] = $this->ip; $this->httpRequest->SERVER['REMOTE_PORT'] = $this->port; $this->httpRequest->SERVER['SERVER_ADDR'] = $this->localIP; $this->httpRequest->SERVER['SERVER_PORT'] = $this->localPort; $exp = explode(':', $this->httpRequest->headers['Host']); $this->httpRequest->SERVER['SERVER_NAME'] = $exp[0]; $this->httpRequest->SERVER['HTTP_HOST'] = $this->httpRequest->headers['Host']; $this->httpRequest->SERVER['HTTP_USER_AGENT'] = isset($this->httpRequest->headers['User-Agent']) ? $this->httpRequest->headers['User-Agent'] : ''; $this->httpRequest->SERVER['HTTP_ACCEPT'] = isset($this->httpRequest->headers['Accept']) ? $this->httpRequest->headers['Accept'] : ''; $this->httpRequest->SERVER['HTTP_ACCEPT_LANGUAGE'] = isset($this->httpRequest->headers['Accept-Language']) ? $this->httpRequest->headers['Accept-Language'] : ''; $this->httpRequest->SERVER['HTTP_ACCEPT_ENCODING'] = isset($this->httpRequest->headers['Accept-Encoding']) ? $this->httpRequest->headers['Accept-Encoding'] : ''; $this->httpRequest->SERVER['HTTP_ACCEPT_CHARSET'] = isset($this->httpRequest->headers['Accept-Charset']) ? $this->httpRequest->headers['Accept-Charset'] : ''; $this->httpRequest->SERVER['HTTP_CONNECTION'] = isset($this->httpRequest->headers['Connection']) ? $this->httpRequest->headers['Connection'] : ''; $this->httpRequest->SERVER['HTTP_KEEP_ALIVE'] = isset($this->httpRequest->headers['Keep-Alive']) ? $this->httpRequest->headers['Keep-Alive'] : ''; if (isset($this->httpRequest->headers['Referer'])) { $this->httpRequest->SERVER['HTTP_REFERER'] = $this->httpRequest->headers['Referer']; } if (isset($this->httpRequest->headers['Range'])) { $this->httpRequest->SERVER['HTTP_RANGE'] = $this->httpRequest->headers['Range']; } if (isset($this->httpRequest->headers['Cookie'])) { $this->httpRequest->SERVER['HTTP_COOKIE'] = $this->httpRequest->headers['Cookie']; } if (isset($this->httpRequest->headers['Authorization'])) { $this->httpRequest->SERVER['HTTP_AUTHORIZATION'] = $this->httpRequest->headers['Authorization']; } $this->httpRequest->SERVER['REQUEST_TIME'] = time(); // Check if we have to match siteDomain if ($this->http->getSiteDomain() != '' && $this->http->getSiteDomain() != $this->httpRequest->SERVER['SERVER_NAME']) { $r = new HttpResponse($this->httpRequest->SERVER['httpVersion'], 404); $r->addBody($this->createErrorPage(404)); $this->write($r->getHeaders()); $this->write($r->getBody()); $errNo = 404; $this->logRequest($r->getResponseCode(), $r->getHeader('Content-Length') ? $r->getHeader('Content-Length') : 0); return false; } // HTTP Authorisation? if ($this->http->getHttpAuthPath() != '') { $scriptPath = pathinfo($this->httpRequest->SERVER['SCRIPT_NAME'], PATHINFO_DIRNAME); // Check if path must be auth'd and if HTTP_AUTHORIZATION header exists and if so, validate it if (isDirInDir($this->http->getHttpAuthPath(), $this->http->getDocRoot() . $scriptPath) && (!isset($this->httpRequest->SERVER['HTTP_AUTHORIZATION']) || !$this->validateAuthorization())) { // Not validated - send 401 Unauthorized do { $nonce = createRandomString(17, RAND_HEX); if (!$this->http->getNonceInfo($nonce)) { break; } } while (true); $opaque = $this->http->addNewNonce($nonce); $r = new HttpResponse($this->httpRequest->SERVER['httpVersion'], 401); if ($this->http->getHttpAuthType() == 'Digest') { $r->addHeader('WWW-Authenticate: Digest realm="' . HTTP_AUTH_REALM . '", qop="auth", nonce="' . $nonce . '", opaque="' . $opaque . '"'); } else { $r->addHeader('WWW-Authenticate: Basic realm="' . HTTP_AUTH_REALM . '"'); } $r->addBody($this->createErrorPage(401, '', true)); $this->write($r->getHeaders()); $this->write($r->getBody()); $errNo = 401; $this->logRequest($r->getResponseCode(), $r->getHeader('Content-Length') ? $r->getHeader('Content-Length') : 0); $this->httpRequest = null; return true; // we return true this time because we may stay connected } } //var_dump($this->httpRequest->headers); //var_dump($this->httpRequest->SERVER); //var_dump($this->httpRequest->GET); //var_dump($this->httpRequest->POST); //var_dump($this->httpRequest->COOKIE); // Rewrite script name? (keep it internal - don't rewrite SERVER header $scriptName = $this->httpRequest->SERVER['SCRIPT_NAME'] == '/' ? '/index.php' : $this->httpRequest->SERVER['SCRIPT_NAME']; if (file_exists($this->http->getDocRoot() . $scriptName)) { // Should we serve a file or pass the request to PHPParser for page generation? if (preg_match('/^.*\\.php$/', $scriptName)) { if ($this->httpRequest->SERVER['REQUEST_METHOD'] == 'HEAD') { $r = new HttpResponse($this->httpRequest->SERVER['httpVersion'], 200); $this->write($r->getHeaders()); } else { // 'Parse' the php file $r = new HttpResponse($this->httpRequest->SERVER['httpVersion'], 200); $html = PHPParser::parseFile($r, $scriptName, $this->httpRequest->SERVER, $this->httpRequest->GET, $this->httpRequest->POST, $this->httpRequest->COOKIE, $this->httpRequest->FILES); $r->addBody($html); $this->write($r->getHeaders()); $this->write($r->getBody()); } } else { if (is_dir($this->http->getDocRoot() . $this->httpRequest->SERVER['SCRIPT_NAME'])) { // 403 - not allowed to view folder contents $r = new HttpResponse($this->httpRequest->SERVER['httpVersion'], 403); $r->addBody($this->createErrorPage(403)); $this->write($r->getHeaders()); $this->write($r->getBody()); } else { // Send a file if ($this->httpRequest->SERVER['REQUEST_METHOD'] == 'HEAD') { $r = new HttpResponse($this->httpRequest->SERVER['httpVersion'], 200); $this->write($r->getHeaders()); } else { $r = $this->serveFile(); } } } } else { // 404 $r = new HttpResponse($this->httpRequest->SERVER['httpVersion'], 404); $r->addBody($this->createErrorPage(404)); $this->write($r->getHeaders()); $this->write($r->getBody()); } // log line $this->logRequest($r->getResponseCode(), $r->getHeader('Content-Length') ? $r->getHeader('Content-Length') : 0); // Reset httpRequest $this->httpRequest = null; return true; }