Source for file NS_HTTP_Service_Handler.php
Documentation is available at NS_HTTP_Service_Handler.php
* nanoserv handlers - HTTP service handler
* Copyright (C) 2004-2010 Vincent Negrier aka. sIX <six@aegis-corp.org>
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *
* Require the nanoserv core
require_once "nanoserv-compat/nanoserv.php";
* HTTP Service handler class
* Response status codes and strings
private $STATUS_CODES = array(100 => "100 Continue",
206 => "Partial Content",
300 => "Multiple Choices",
301 => "Moved Permanently",
307 => "Temporary Redirect",
405 => "Method Not Allowed",
408 => "Request Timeout",
413 => "Request Entity Too Large",
414 => "Request URI Too Long",
415 => "Unsupported Media Type",
416 => "Requested Range Not Satisfiable",
417 => "Expectation Failed",
500 => "Internal Server Error",
501 => "Method Not Implemented",
503 => "Service Unavailable",
506 => "Variant Also Negotiates");
* Request content (raw POST data)
private $request_buffer = "";
private $response_headers = array();
private $response_content_type;
private $response_status = 200;
$this->response_content_type = static::DEFAULT_CONTENT_TYPE;
final public function on_Read($data) {
$this->request_buffer .= $data;
while ($this->request_buffer) {
if (($p = strpos($this->request_buffer, "\r\n\r\n")) !== false) {
$hdrs = substr($this->request_buffer, 0, $p);
$cnt = substr($this->request_buffer, $p + 4);
} else if (($p = strpos($this->request_buffer, "\n\n")) !== false) {
$hdrs = substr($this->request_buffer, 0, $p);
$cnt = substr($this->request_buffer, $p + 2);
if (isset ($this->request_buffer[static::MAX_REQUEST_LENGTH])) {
$this->Set_Response_Status(414);
foreach ($hdrs as $hdr) {
if ($cl > static::MAX_REQUEST_LENGTH) {
$this->Set_Response_Status(413);
} else if (strlen($cnt) < $cl) {
$this->request_buffer = $cnt;
* Event called on HTTP request
* the string returned by on_Request() will be sent back as the HTTP response
* Add HTTP header to the response
$this->response_headers[] = $header;
* Set response content type
* @param string $content_type
$this->response_content_type = $content_type;
* Set HTTP response status code
* 200 = OK, 403 = Forbidden, 404 = Not found, ...
$this->response_status = $code;
case self::COMPRESS_OFF: $this->compress = $opt; break;
default: throw new NS_Exception("invalid compress option '{$opt}'");
* Compress a response if possible and needed
* @param string &$encoding
$methods = array( "deflate" => "gzdeflate",
"compress" => "gzcompress");
foreach ($methods as $m => $func) {
if (!isset ($method)) return false;
* Send HTTP response back to client
* This method is only invoked by the on_Read() handler
$resp = "HTTP/1.1 " . (int) $this->response_status . " " . $this->STATUS_CODES[$this->response_status] . "\r\n"
. "Date: " . gmdate("D, d M Y H:i:s T") . "\r\n"
. "Server: " . (static::SERVER_STRING ? static::SERVER_STRING : "nanoserv/2.1.1-dev") . "\r\n"
. "Content-Type: " . $this->response_content_type . "\r\n"
. "Content-Length: " . (isset ($length) ? $length : strlen($data)) . "\r\n"
. "Connection: " . ($keep ? "Keep-Alive" : "Close") . "\r\n";
if (($this->compress !== self::COMPRESS_OFF) && $this->Compress_Response($data, $encoding)) $resp .= "Content-Encoding: " . $encoding . "\r\n";
if ($this->response_headers) $resp .= implode("\r\n", $this->response_headers) . "\r\n";
$this->Write($resp, ($keep ? false : array($this, "Disconnect")));
$this->response_content_type = static::DEFAULT_CONTENT_TYPE;
$this->response_headers = array();
$this->response_status = 200;
* HTTP Asynchronous service handler class
|