php写的http协议
这个协议纯自已手工打造,超级灵活,如,我可以用它来分析wireshark的截包
用法请看 test函数. 用到请保留作者信息。
<?php /** * * @author aerror * */ class HttpHeader { public $method; public $status_code; public $chunked; public $status_line; public $headers; public $content_len; public $header_len; public $contentEncoding; public function HttpHeader() { self::reset(); } public function reset() { $this->headers = array(); $this->status_code=0; $this->chunked=0; $this->status_line=""; $this->content_len=0; $this->header_len=0; $this->contentEncoding = ""; } }; class XAutoBuffer { private $m_innerbuf=""; private $length=0; private $each_inc_size=1024; public function XAutoBuffer($initSize) { $this->m_innerbuf=""; $this->length = 0; } public function Append($buf, $offset, $len) { $this->m_innerbuf .= substr($buf, $offset,$len); $this->length +=$len; } public function SetLength($val) { $this->m_innerbuf = substr($this->m_innerbuf,0,$val); $this->length = $val; } public function GetLength() { return $this->length; } public function GetBuffer() { return $this->m_innerbuf; } public function Clear() { $this->m_innerbuf=""; $this->length =0; } } class HttpContext { public $m_header; public $m_state; public $m_bHeaderReceived; public $m_cur_chunk_len; public $m_cur_chunk_read; public $m_chunk_hdr_offset; public $header_origin; public function HttpContext() { self::reset(); } public function reset() { $this->m_header = new HttpHeader(); $this->m_state = 0; $this->m_bHeaderReceived=0; $this->m_cur_chunk_len=0; $this->m_cur_chunk_read=0; $this->m_chunk_hdr_offset=0; $this->header_origin=0; } public function getHeaderValueByName($name) { foreach($this->m_header->headers as $p) { if($p["name"] == $name) { return $p["value"]; } } return null; } }; class HttpProtocolClient { const NEW_PACKET=0; const RECEIVING_HEADER=1; const RECEIVING_CONTENT=2; const RECEIVING_CHUNKED_LEN=3; const RECEIVING_CHUNKED_BODY=4; const PACKET_COMPLETE=5; const PACKET_PARSE_FAILED=6; const MAX_HEADER_LEN =2048; const HTTP_HEADER_END_STRING = " "; const HTTP_HEADER_END_STRING_SIZE =4; const HTTP_1_1_MAGIC = "HTTP/1."; const HTTP_1_1_MAGIC_LEN =7; const HTTP_HEAD_CONNECTION = "Connection"; const HTTP_TRANSFER_ENCODING = "Transfer-Encoding"; const HTTP_CONTENT_ENCODING = "Content-Encoding"; const HTTP_CONTENT_LENGTH = "Content-length"; const HTTP_CHUNKED = "chunked"; const HTTP_TEXT_HTML = "text/html"; const HTTP_CHUNKED_END = "0 "; const HTTP_CRLF = " "; const HTTP_CRLF_SIZE = 2; const XPROTO_FAILED =-1; const XPROTO_REMAIN_LENGTH_ERROR =-2; const XPROTO_XCMD_OUT_OF_RANGE =-3; const XPROTO_PACKET_LENGTH_OVERFLOW =-4; const XPROTO_PACKET_NOT_COMPLETED =-5; const XPROTO_PACKET_LESS_THAN_HDRLEN =-6; const XPROTO_DISPATCH_EXCEPTION =-7; const XPROTO_OUT_OF_MEMORY =-8; const XPROTO_GET_SEND_BUFF_FAILED =-9; const XPROTO_FROM_BUFF_FAILED =-10; const XPROTO_TO_BUFF_FAILED =-11; const XPROTO_XML_NODE_NOT_FOUND =-12; const XPROTO_TOO_LESS_HEADER_LINE =-13; const XPROTO_MAGIC_NOT_MATCH =-14; const XPROTO_TOO_LESS_HEADER_VALUE =-15; const XPROTO_PROTOCOL_STATE_WRONG =-16; const XPROTO_PARSE_HEADER_FAILED =-17; const XPROTO_MAX_HEADER_LEN =-18; const XPROTO_UNKOWN_CONTENT_TYPE =-19; const XPROTO_UNSUPPORT_TRANS_TYPE =-20; public static function strsnstr( $dest1,$dst1Off, $dstlen1, $dest2,$dst2Off, $dstlen2, $src,$srclen) { $dlen = $dstlen1+ $dstlen2; $p1 = 0; $p2 = 0; for($j=0;$j<=$dlen-$srclen;$j++) { $p1 =$dst1Off+$j; $match=1; for($i=0;$i<$srclen;$i++) { if(($j+$i) < $dstlen1) { $p2 = $dest1[$dst1Off+$j+$i]; } else { $p2 = $dest2[$dst2Off+$j+$i-$dstlen1]; } if($p2!=$src[$i]) { $match=0; break; } } if($match!=0) { return $p1; } } return -1; } public static function HexStringnToIntegerA($lpHexString, $offset, $len) { $x=substr($lpHexString, $offset, $len); return hexdec($x); } public static function parseHttp($ctx, $inputBuf,$len, $buf ) { $byteAvailable = $len; $curOffset=0; $res =0; $phdr = null; //uses state machine. // while($byteAvailable>0) { switch($ctx->m_state) { case HttpProtocolClient::NEW_PACKET: { //new packet // $ctx->m_state =HttpProtocolClient::RECEIVING_HEADER; continue; } case HttpProtocolClient::RECEIVING_HEADER: { $ptemp = 0; if($buf->GetLength()>=HttpProtocolClient::HTTP_HEADER_END_STRING_SIZE) { $ptemp =self::strsnstr( $buf->GetBuffer(), //d1 $buf->GetLength()-HttpProtocolClient::HTTP_HEADER_END_STRING_SIZE,//do1 HttpProtocolClient::HTTP_HEADER_END_STRING_SIZE,//dl2 $inputBuf, $curOffset, $byteAvailable, HttpProtocolClient::HTTP_HEADER_END_STRING, HttpProtocolClient::HTTP_HEADER_END_STRING_SIZE); } else { $ptemp =self::strsnstr( $buf->GetBuffer(), 0, $buf->GetLength(), $inputBuf, $curOffset, $byteAvailable, HttpProtocolClient::HTTP_HEADER_END_STRING, HttpProtocolClient::HTTP_HEADER_END_STRING_SIZE); } if($ptemp<0) { if($byteAvailable+$buf->GetLength() >HttpProtocolClient::MAX_HEADER_LEN ) { $ctx->m_state =(HttpProtocolClient::PACKET_PARSE_FAILED); return HttpProtocolClient::XPROTO_MAX_HEADER_LEN; } //header not completed. // $buf->Append($inputBuf,$curOffset,$byteAvailable); //update pointers. // $curOffset+=$byteAvailable; $byteAvailable = 0; $ctx->m_state =(HttpProtocolClient::RECEIVING_HEADER); return $len; } //head completed. // $hdrRemain = 0; if($ptemp < $buf->GetLength()) { $hdrRemain = (int)(HttpProtocolClient::HTTP_HEADER_END_STRING_SIZE- ($buf->GetLength() -$ptemp)); } else { $hdrRemain = (int)(($ptemp-$buf->GetLength()) + HttpProtocolClient::HTTP_HEADER_END_STRING_SIZE); } if($hdrRemain+$buf->GetLength() > HttpProtocolClient::MAX_HEADER_LEN ) { $ctx->m_state =(HttpProtocolClient::PACKET_PARSE_FAILED); return HttpProtocolClient::XPROTO_MAX_HEADER_LEN; } $buf->Append($inputBuf,$curOffset,$hdrRemain); //var_dump($buf); //update pointers. // $curOffset+=$hdrRemain; $byteAvailable-= $hdrRemain; $ctx->m_bHeaderReceived = 1; if(($res=HttpProtocolClient::ParseHeader($ctx,$buf->GetBuffer(),$buf->GetLength()))!=0) { $ctx->m_state =(HttpProtocolClient::PACKET_PARSE_FAILED); return $res; } if($ctx->m_header->chunked!=0) { //very import to update the content pointer. // $ctx->m_chunk_hdr_offset = $buf->GetLength(); $ctx->m_state =(HttpProtocolClient::RECEIVING_CHUNKED_LEN); } else { //$ctx->m_header->all = pCurrentBuf-hdr_len; $ctx->m_state =(HttpProtocolClient::RECEIVING_CONTENT); if($ctx->m_header->content_len ==0) //sometime head with content-length:0, suck! { $ctx->m_state =(HttpProtocolClient::PACKET_COMPLETE); return $len-$byteAvailable; } } continue; } case HttpProtocolClient::RECEIVING_CONTENT: { $phdr =$ctx->m_header; if($phdr->content_len >0) { $remainLen = $phdr->content_len + $phdr->header_len - $buf->GetLength(); if($byteAvailable < $remainLen) { //not completed //copy and return // $buf->Append($inputBuf,$curOffset,$byteAvailable); //should use this.buf // $byteAvailable =0; $ctx->m_state =(HttpProtocolClient::RECEIVING_CONTENT); return $len; } $buf->Append($inputBuf,$curOffset,$remainLen); $curOffset += $remainLen; $byteAvailable -= $remainLen; } $ctx->m_state =(HttpProtocolClient::PACKET_COMPLETE); return $len-$byteAvailable; } //break;//case RECEIVING_CONTENT case HttpProtocolClient::RECEIVING_CHUNKED_LEN: { /*0x48,0x54,0x54,0x50,0x2F,0x31,0x2E,0x31,0x20,0x32,0x30,0x30,0x20,0x4F,0x4B,0x0D,0x0A,0x53,0x65,0x72,0x76,0x65,0x72,0x3A,0x20,0x6E,0x67,0x69,0x6E,0x78,0x2F,0x30, 0x2E,0x37,0x2E,0x36,0x32,0x0D,0x0A,0x44,0x61,0x74,0x65,0x3A,0x20,0x53,0x61,0x74,0x2C,0x20,0x32,0x35,0x20,0x4A,0x75,0x6E,0x20,0x32,0x30,0x31,0x31,0x20,0x31,0x33, 0x3A,0x30,0x36,0x3A,0x35,0x35,0x20,0x47,0x4D,0x54,0x0D,0x0A,0x43,0x6F,0x6E,0x74,0x65,0x6E,0x74,0x2D,0x54,0x79,0x70,0x65,0x3A,0x20,0x69,0x6D,0x61,0x67,0x65,0x2F, 0x67,0x69,0x66,0x0D,0x0A,0x54,0x72,0x61,0x6E,0x73,0x66,0x65,0x72,0x2D,0x45,0x6E,0x63,0x6F,0x64,0x69,0x6E,0x67,0x3A,0x20,0x63,0x68,0x75,0x6E,0x6B,0x65,0x64,0x0D, 0x0A,0x43,0x6F,0x6E,0x6E,0x65,0x63,0x74,0x69,0x6F,0x6E,0x3A,0x20,0x63,0x6C,0x6F,0x73,0x65,0x0D,0x0A,0x0D,0x0A,0x32,0x62,0x0D,0x0A,0x47,0x49,0x46,0x38,0x39,0x61, 0x01,0x00,0x01,0x00,0x80,0x00,0x00,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x21,0xF9,0x04,0x01,0x00,0x00,0x00,0x00,0x2C,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x00,0x02, 0x02,0x44,0x01,0x00,0x3B,0x0D,0x0A,0x31,0x0D,0x0A,0x31,0x0D,0x0A,0x30,0x0D,0x0A,0x0D,0x0A*/ $ptemp = 0; $cur_chunk_hdr_len = (int)($buf->GetLength() - $ctx->m_chunk_hdr_offset); $chunkHdr = $ctx->m_chunk_hdr_offset; if($cur_chunk_hdr_len >=HttpProtocolClient::HTTP_CRLF_SIZE) { $ptemp =self::strsnstr( $buf->GetBuffer(), $buf->GetLength()-HttpProtocolClient::HTTP_CRLF_SIZE, HttpProtocolClient::HTTP_CRLF_SIZE, $inputBuf, $curOffset, $byteAvailable, HttpProtocolClient::HTTP_CRLF, HttpProtocolClient::HTTP_CRLF_SIZE); } else { $ptemp =self::strsnstr( $buf->GetBuffer(), $chunkHdr, $cur_chunk_hdr_len, $inputBuf, $curOffset, $byteAvailable, HttpProtocolClient::HTTP_CRLF, HttpProtocolClient::HTTP_CRLF_SIZE); } if($ptemp<0) { //chunked len not completed. // $buf->Append($inputBuf,$curOffset,$byteAvailable); //update pointers. // $curOffset+=$byteAvailable; $byteAvailable = 0; $ctx->m_state =(HttpProtocolClient::RECEIVING_CHUNKED_LEN); return $len; } //head completed. // $hdrRemain = 0; if($ptemp < $buf->GetLength()) { //partial header received. // $hdrRemain = (int)(HttpProtocolClient::HTTP_CRLF_SIZE-($buf->GetLength() -$ptemp)); } else { $hdrRemain = (int)(($ptemp-$buf->GetLength())+HttpProtocolClient::HTTP_CRLF_SIZE); } if($hdrRemain+$cur_chunk_hdr_len >12 ) { $ctx->m_state =(HttpProtocolClient::PACKET_PARSE_FAILED); return HttpProtocolClient::XPROTO_MAX_HEADER_LEN; } $cur_chunk_hdr_len +=$hdrRemain; $buf->Append($inputBuf,$curOffset,$hdrRemain); //calc again , because bufs will realloc. // $chunkHdr = $ctx->m_chunk_hdr_offset; //update pointers. // $curOffset+=$hdrRemain; $byteAvailable-= $hdrRemain; $ctx->m_cur_chunk_len = (int)HttpProtocolClient::HexStringnToIntegerA($buf->GetBuffer(),$chunkHdr,$cur_chunk_hdr_len); $ctx->m_cur_chunk_read = 0; //skip the header before copy chunk body // $buf->SetLength($buf->GetLength()-$cur_chunk_hdr_len); $ctx->m_state =(HttpProtocolClient::RECEIVING_CHUNKED_BODY); }//case RECEIVING_CHUNKED_LEN break; case HttpProtocolClient::RECEIVING_CHUNKED_BODY: { $remainLen = ($ctx->m_cur_chunk_len + HttpProtocolClient::HTTP_CRLF_SIZE)-$ctx->m_cur_chunk_read; if($byteAvailable < $remainLen) { //not completed //copy and return // $buf->Append($inputBuf,$curOffset,$byteAvailable); $ctx->m_cur_chunk_read+=$byteAvailable; $byteAvailable =0; $ctx->m_state =(HttpProtocolClient::RECEIVING_CHUNKED_BODY); return $len; } //here should be a completed chunk body. // $buf->Append($inputBuf,$curOffset,$remainLen); $ctx->m_cur_chunk_read+=$remainLen; $buf->SetLength($buf->GetLength()-HttpProtocolClient::HTTP_CRLF_SIZE);//SKIP BODY CRLF $curOffset += $remainLen; $byteAvailable -= $remainLen; if($ctx->m_cur_chunk_len==0) { //chunk over. // $ctx->m_state =(HttpProtocolClient::PACKET_COMPLETE); //must set content_len before dispatch // $ctx->m_header->content_len = $buf->GetLength() - $ctx->m_header->header_len; return $len-$byteAvailable; } else //next chunk { $ctx->m_chunk_hdr_offset = $buf->GetLength(); $ctx->m_state =(HttpProtocolClient::RECEIVING_CHUNKED_LEN); } }//case RECEIVING_CHUNKED_BODY break; case HttpProtocolClient::PACKET_PARSE_FAILED: { return -1; } default: return -2; } }//while return $len; } public static function ParseHeader( $ctx, $buf, $len) { $s = substr($buf,0,$len); $lines = explode(" ",$s); if(count($lines) <= 0) { return -1; } $ctx->m_header->header_len = $len; $ctx->m_header->status_line = $lines[0]; $statu_values = explode(" ",$ctx->m_header->status_line); if(count($statu_values) >2) { $ctx->m_header->status_code =$statu_values[1]; $ctx->m_header->method = $statu_values[0]; } for($i=1;$i<count($lines);$i++) { $idx = strpos($lines[$i],":"); if($idx > 0) { $name = trim(substr($lines[$i], 0,$idx)); $value = trim(substr($lines[$i],$idx+1)); if(strcasecmp(HttpProtocolClient::HTTP_CONTENT_LENGTH,$name)==0) { $ctx->m_header->content_len = intval($value); } else if(strcasecmp(HttpProtocolClient::HTTP_TRANSFER_ENCODING, $name)==0 && strcasecmp(HttpProtocolClient::HTTP_CHUNKED,$value)==0) { $ctx->m_header->chunked = 1; } else if(strcasecmp(HttpProtocolClient::HTTP_CONTENT_ENCODING, $name)==0 ) { $ctx->m_header->contentEncoding = $value; } array_push($ctx->m_header->headers, array("name"=>$name,"value"=>$value)); } } return 0; } /** * return the uncomp$ressed content. * * */ public function uncompressContent( $ctx, $input) { // $content_len = input.GetLength()-$ctx->m_header->header_len; // if(content_len<=0) // { // return null; // } // long t1 = System.currentTimeMillis(); // byte []tmp = new byte[4096]; // InputStream body=null; // $guess_ratio = 1; // if($ctx->m_header->contentEncoding.equals("gzip")) // { // ByteArrayInputStream ins = new ByteArrayInputStream(input.GetBuffer(), // $ctx->m_header->header_len, // content_len); // body = new GZIPInputStream(ins); // guess_ratio = 5; // } // else if($ctx->m_header->contentEncoding.equals("deflate")) // { // ByteArrayInputStream ins = new ByteArrayInputStream(input.GetBuffer(), // $ctx->m_header->header_len, // content_len); // body = new InflaterInputStream(ins); // guess_ratio = 5; // } // else if($ctx->m_header->contentEncoding.equals("")) // { // body = new ByteArrayInputStream(input.GetBuffer(), // $ctx->m_header->header_len, // content_len); // guess_ratio = 1; // } // if(body!=null) // { // XAutoBuffer ret = new XAutoBuffer(content_len*guess_ratio); // while(true) // { // $rn = body.read(tmp,0,tmp.length); // if(rn<=0) // { // break; // } // ret.Append(tmp, 0, rn); // } // // print("SEND_POST_MANUALLY_PROFILE","UNCOMP$resS_CONTENT("+$ctx->m_header->contentEncoding+"): "+ (System.currentTimeMillis()-t1) // // +" zip size:"+content_len + " unzip size: " + ret.GetLength()); // return ret; // } return null; } public static function getContentLen($ctx, $input) { return input.GetLength() - $ctx->m_header->header_len; } public static function getContent($ctx, $input) { // try { // return uncomp$ressContent(ctx,input); // } catch (IOException e) { // print("HTTP getContent", e.getMessage()); // } return $input; } public static function test() { $szChunked ="x48x54x54x50x2Fx31x2Ex31x20x32x30x30x20x4Fx4Bx0Dx0Ax53x65x72x76x65x72x3Ax20x6Ex67x69x6Ex78x2Fx30x2Ex37x2Ex36x32x0Dx0Ax44x61x74x65x3Ax20x53x61x74x2Cx20x32x35x20x4Ax75x6Ex20x32x30x31x31x20x31x33x3Ax30x36x3Ax35x35x20x47x4Dx54x0Dx0Ax43x6Fx6Ex74x65x6Ex74x2Dx54x79x70x65x3Ax20x69x6Dx61x67x65x2Fx67x69x66x0Dx0Ax54x72x61x6Ex73x66x65x72x2Dx45x6Ex63x6Fx64x69x6Ex67x3Ax20x63x68x75x6Ex6Bx65x64x0Dx0Ax43x6Fx6Ex6Ex65x63x74x69x6Fx6Ex3Ax20x63x6Cx6Fx73x65x0Dx0Ax0Dx0Ax32x62x0Dx0Ax47x49x46x38x39x61x01x00x01x00x80x00x00xFFxFFxFFx00x00x00x21xF9x04x01x00x00x00x00x2Cx00x00x00x00x01x00x01x00x00x02x02x44x01x00x3Bx0Dx0Ax31x0Dx0Ax31x0Dx0Ax30x0Dx0Ax0Dx0A"; $szContentLenght="x48x54x54x50x2Fx31x2Ex31x20x32x30x30x20x4Fx4Bx0Dx0Ax53x65x72x76x65x72x3Ax20x4Dx65x64x69x61x56x2Fx30x2Ex31x2Ex35x34x0Dx0Ax44x61x74x65x3Ax20x53x61x74x2Cx20x32x35x20x4Ax75x6Ex20x32x30x31x31x20x31x34x3Ax34x34x3Ax30x38x20x47x4Dx54x0Dx0Ax43x6Fx6Ex74x65x6Ex74x2Dx54x79x70x65x3Ax20x69x6Dx61x67x65x2Fx67x69x66x0Dx0Ax43x6Fx6Ex74x65x6Ex74x2Dx4Cx65x6Ex67x74x68x3Ax20x34x33x0Dx0Ax43x6Fx6Ex6Ex65x63x74x69x6Fx6Ex3Ax20x6Bx65x65x70x2Dx61x6Cx69x76x65x0Dx0Ax53x65x74x2Dx43x6Fx6Fx6Bx69x65x3Ax20x20x76x3Dx67x24x3Cx66x46x3Cx41x41x29x63x43x40x2Ax21x2Dx29x37x40x77x67x3Bx20x65x78x70x69x72x65x73x3Dx57x65x64x6Ex65x73x64x61x79x2Cx20x30x32x2Dx4Ex6Fx76x2Dx32x30x39x39x20x32x32x3Ax34x34x3Ax30x38x20x47x4Dx54x3Bx20x70x61x74x68x3Dx2Fx3Bx20x64x6Fx6Dx61x69x6Ex3Dx2Ex6Dx65x64x69x61x76x2Ex63x6Fx6Dx0Dx0Ax43x6Fx6Ex6Ex65x63x74x69x6Fx6Ex3Ax20x43x6Cx6Fx73x65x0Dx0Ax50x72x61x67x6Dx61x3Ax20x6Ex6Fx2Dx63x61x63x68x65x0Dx0Ax50x33x50x3Ax20x43x50x3Dx22x43x55x52x61x20x41x44x4Dx61x20x44x45x56x61x20x50x53x41x6Fx20x50x53x44x6Fx20x4Fx55x52x20x42x55x53x20x55x4Ex49x20x50x55x52x20x49x4Ex54x20x44x45x4Dx20x53x54x41x20x50x52x45x20x43x4Fx4Dx20x4Ex41x56x20x4Fx54x43x20x4Ex4Fx49x20x44x53x50x20x43x4Fx52x22x0Dx0Ax43x61x63x68x65x2Dx43x6Fx6Ex74x72x6Fx6Cx3Ax20x6Ex6Fx2Dx63x61x63x68x65x2Cx20x6Dx75x73x74x2Dx72x65x76x61x6Cx69x64x61x74x65x0Dx0Ax0Dx0Ax47x49x46x38x39x61x01x00x01x00x80x01x00x00x00x00xFFxFFxFFx21xF9x04x01x00x00x01x00x2Cx00x00x00x00x01x00x01x00x00x02x02x4Cx01x00x3B"; $ctx= new HttpContext(); $bufs = new XAutoBuffer(4096); $consumeLen = HttpProtocolClient::parseHttp($ctx,$szChunked,strlen($szChunked),$bufs); if($consumeLen==strlen($szChunked) && $ctx->m_state==HttpProtocolClient::PACKET_COMPLETE) { print("TEST HTTP PROTOCOL STAGE 1 OK "); } else { print("TEST HTTP PROTOCOL STAGE 1 FAILED "); } $ctx->reset(); $bufs->Clear(); $consumeLen = 0; for($i=0;$i<strlen($szChunked);$i++) { $tmb = pack( "c", ord($szChunked[$i]) ); $consumeLen += HttpProtocolClient::parseHttp($ctx,$tmb,1,$bufs); } if($consumeLen==strlen($szChunked) && $ctx->m_state==HttpProtocolClient::PACKET_COMPLETE) { print("TEST HTTP PROTOCOL STAGE 2 OK "); } else { print("TEST HTTP PROTOCOL STAGE 2 FAILED "); } $ctx->reset(); $bufs->Clear(); $consumeLen = 0; $consumeLen = HttpProtocolClient::parseHttp($ctx,$szContentLenght,strlen($szContentLenght),$bufs); if($consumeLen==strlen($szContentLenght) && $ctx->m_state==HttpProtocolClient::PACKET_COMPLETE) { print("TEST HTTP PROTOCOL STAGE 3 OK "); } else { print("TEST HTTP PROTOCOL STAGE 3 FAILED "); } $ctx->reset(); $bufs->Clear(); $consumeLen = 0; for($i=0;$i<strlen($szContentLenght);$i++) { $tmb = pack ( "c", ord($szContentLenght[$i]) ); $consumeLen += HttpProtocolClient::parseHttp($ctx,$tmb,1,$bufs); } if($consumeLen==strlen($szContentLenght) && $ctx->m_state==HttpProtocolClient::PACKET_COMPLETE) { print("TEST HTTP PROTOCOL STAGE 4 OK "); } else { print("TEST HTTP PROTOCOL STAGE 4 FAILED "); } } public static function test2() { $input = fopen("/tmp/httpdata.dump","rb"); $filesize = fstat($input); var_dump($filesize); $filesize = $filesize["size"]; $data = fread($input,$filesize); fclose($input); $ctx= new HttpContext(); $bufs = new XAutoBuffer(4096); while($filesize>0) { $consumeLen = HttpProtocolClient::parseHttp($ctx,$data,$filesize,$bufs); $data = substr($data, $consumeLen); $filesize -=$consumeLen; if($consumeLen>=0 && $ctx->m_state==HttpProtocolClient::PACKET_COMPLETE) { echo " ok $consumeLen "; $ctx->reset(); $bufs->Clear(); } else { echo "not ok $consumeLen "; var_dump($ctx); break; } } } }; //HttpProtocolClient::test2();
声明:该文观点仅代表作者本人,牛骨文系教育信息发布平台,牛骨文仅提供信息存储空间服务。