/** * Callback called when new headers are found on the stream. * * @access public * @param string $data * @return void */ public function on_headers($data) { if ($this->_server->config('VERBOSE') >= 2) { file_put_contents($this->_server->config('LOG_FILE'), "REQUEST HEADERS\t" . $this->_start . ":\r\n\r\n" . $data . "\r\n", FILE_APPEND); } list($start_line, $data) = explode("\r\n", $data, 2); list($method, $uri, $version) = explode(' ', $start_line); // Make sure this is an HTTP request. if (strpos($version, 'HTTP/') !== 0) { return; } // Parse the headers. $headers = HTTPHeaders::parse($data); // Check for a WebSocket upgrade. if ($headers->has('Upgrade') && strtolower($headers->get('Upgrade')) == 'websocket') { $this->_request = new WSRequest($this, $method, $uri, $version, $headers, $this->_address); if ($headers->has('Sec-WebSocket-Key1') && $headers->has('Sec-WebSocket-Key2')) { $this->_stream->read_bytes(8, array($this, 'on_finish_handshake_v76')); } else { //missed parameter for function handshake $this->write($this->_request->handshake()); call_user_func($this->_request_callback, $this->_request); $this->_stream->read_until(chr(255), array($this, 'on_request_body')); } } else { $this->_request = new HTTPRequest($this, $method, $uri, $version, $headers, $this->_address); } // Increment the request count. ++$this->_request_count; // Stop the connection from being closed if this is a keep alive request. if (!empty($this->_keep_alive_timeoutid)) { $this->_server->get_loop()->remove_timeout($this->_keep_alive_timeoutid); } // Check for a request body. $content_length = $headers->get('Content-Length'); if ($content_length) { if ($content_length > IOStream::MAX_BUFFER_SIZE) { throw new OverflowException('Content-Length too long'); } if ($headers->get('Expect') == '100-continue') { $this->_stream->write("HTTP/1.0 100 (Continue)\r\n\r\n"); } $this->_stream->read_bytes($content_length, array($this, 'on_request_body')); } elseif (!$this->_request instanceof WSRequest) { call_user_func($this->_request_callback, $this->_request); } }
/** * Copy all data from the current stream to the specified one * * @param IOStream $dest * @return this */ public function pipe(IOStream $dest) { $this->on('data', function ($data, $src) use($dest) { $dest->write($data); }); return $this; }