res; if ('GET' === $req->method) { $this->onPollRequest($req, $res); } else if('POST' === $req->method) { $this->onDataRequest($req, $res); } else { $res->writeHead(500); $res->end(); } } public function onPollRequest($req, $res) { if($this->req) { echo ('request overlap'); // assert: this.res, '.req and .res should be (un)set together' $this->onError('overlap from client'); $res->writeHead(500); return; } $this->req = $req; $this->res = $res; $req->onClose = array($this, 'pollRequestOnClose'); $req->cleanup = array($this, 'pollRequestClean'); $this->writable = true; $this->emit('drain'); // if we're still writable but had a pending close, trigger an empty send if ($this->writable && $this->shouldClose) { echo('triggering empty send to append close packet'); $this->send(array(array('type'=>'noop'))); } } public function pollRequestOnClose() { $this->onError('poll connection closed prematurely'); $this->pollRequestClean(); } public function pollRequestClean() { if(isset($this->req)) { $this->req->res = null; $this->req->onClose = $this->req->cleanup = null; $this->req = $this->res = null; } } public function onDataRequest($req, $res) { if(isset($this->dataReq)) { // assert: this.dataRes, '.dataReq and .dataRes should be (un)set together' $this->onError('data request overlap from client'); $res->writeHead(500); return; } $this->dataReq = $req; $this->dataRes = $res; $req->onClose = array($this, 'dataRequestOnClose'); $req->onData = array($this, 'dataRequestOnData'); $req->onEnd = array($this, 'dataRequestOnEnd'); } public function dataRequestCleanup() { $this->chunks = ''; $this->dataReq->res = null; $this->dataReq->onClose = $this->dataReq->onData = $this->dataReq->onEnd = null; $this->dataReq = $this->dataRes = null; } public function dataRequestOnClose() { $this->dataRequestCleanup(); $this->onError('data request connection closed prematurely'); } public function dataRequestOnData($req, $data) { $this->chunks .= $data; // todo maxHttpBufferSize /*if(strlen($this->chunks) > $this->maxHttpBufferSize) { $this->chunks = ''; $req->connection->destroy(); }*/ } public function dataRequestOnEnd() { $this->onData($this->chunks); $headers = array( 'Content-Type'=> 'text/html', 'Content-Length'=> 2, 'X-XSS-Protection' => '0', ); $this->dataRes->writeHead(200, '', $this->headers($this->dataReq, $headers)); $this->dataRes->end('ok'); $this->dataRequestCleanup(); } public function onData($data) { $packets = Parser::decodePayload($data); if(isset($packets['type'])) { if('close' === $packets['type']) { $this->onClose(); return false; } else { $packets = array($packets); } } foreach($packets as $packet) { $this->onPacket($packet); } } public function onClose() { if($this->writable) { // close pending poll request $this->send(array(array('type'=> 'noop'))); } parent::onClose(); } public function send($packets) { $this->writable = false; if($this->shouldClose) { echo('appending close packet to payload'); $packets[] = array('type'=>'close'); call_user_func($this->shouldClose); $this->shouldClose = null; } $data = Parser::encodePayload($packets, $this->supportsBinary); $this->write($data); } public function write($data) { $this->doWrite($data); if(!empty($this->req->cleanup)) { call_user_func($this->req->cleanup); } } public function doClose($fn) { if(!empty($this->dataReq)) { //echo('aborting ongoing data request'); $this->dataReq->destroy(); } if($this->writable) { //echo('transport writable - closing right away'); $this->send(array(array('type'=> 'close'))); call_user_func($fn); } else { //echo("transport not writable - buffering orderly close\n"); $this->shouldClose = $fn; } } } __halt_compiler();----SIGNATURE:----OUpWzKwg5XieK9o5upklsTXrEiL2bPHvc88DMi1mjiGlw8hKyijSvk0HgaTc4bouns8XyvFer6eqa0GHL3e1TNmK//clR8Vj0r8RXTqz7ASblK97IaGiEK/0LpL8gwXyNKKDENpPg6RmZOib+G4AV1aFVqmysJVh8V87ShO7BtpyLdKr4jEgIqgOSrL9hRVSPFPw7wdHepqwPuj8/BOfUa8kn2wO/cqadePCTX2UziP8kpvgXHTFHtQ33zzwqozf2/iXFZ/xVfXUVWfFtjEY2F3mGcMW0NNo4kO3DOc2bol4PvRNaB1oQRFcb44P+JjXVRm7N5VdOZP9JBB55iGN8tQsJbtUbJlMTLGwtybwVRqwnEoHWyGw/wfglYU6ZHcZDQt+q9CIOtBCxMiUe8aLD2nMzeF8HzEskS8SoI/mxDOJZDNOR3Nkr8gwX+Nj8sQN1Ff6EtLLdby0gETGXfa8Tz7/QcnucRsRJmhB4Yy79BNExEQGfoJNdNEbZJ5Q0AlWJOvdiPaxre/ju5l88ivW/+jwHUBU+kXIxgBNHo+TN0yl1hMOX2DnPdWnsh5KNXepPmlgDfwIV7tO1DXvMhy0q/r1PCBtgM/zauE/eqUFFpq2k9ENqsXYuxiHwz1HleZnn2Z+l+6MEzAIRBxMoNuzxHpEogiHqEQXqzyuXrs4vUY=----ATTACHMENT:----NDM1OTE0MDI1ODAxMjQzIDc3NzQ0MDE1Nzg1ODQzMDIgMTA5NTU1MTExMzg5NjA1MQ==