int ungzip2(char *source,int len,int gzip,CBuffer& buffer) { static const size_t chunk_size = 4096; int ret; unsigned have; z_stream strm; unsigned char out[chunk_size] = {0}; /* allocate inflate state */ strm.zalloc = Z_NULL; strm.zfree = Z_NULL; strm.opaque = Z_NULL; strm.avail_in = 0; strm.next_in = Z_NULL; if(gzip) ret = inflateInit2(&strm, 47); else ret = inflateInit(&strm); if (ret != Z_OK) return -1; strm.avail_in = len; strm.next_in = (Bytef*)source; do { strm.avail_out = chunk_size; strm.next_out = out; ret = inflate(&strm, Z_NO_FLUSH); switch (ret) { case Z_NEED_DICT: ret = Z_DATA_ERROR; /* and fall through */ case Z_DATA_ERROR: case Z_MEM_ERROR: inflateEnd(&strm); return -1; } have = chunk_size - strm.avail_out; buffer.Write(out,have); } while (Z_STREAM_END != ret); /* clean up and return */ (void)inflateEnd(&strm); return ret == Z_STREAM_END ? 0 : -1; }
unsigned AudioPlugin::audioThread(void* p) { int nStatus = 0; conn ftpfd = gParam.s; int listenType = gParam.recvData.type; int imgSize = 3000; char* img = new char[3000]; int (*myWrite)(conn, char*, char*, int, int) = gParam.WriteFunction; int (*myRead)(conn, char*, int, int, int, int) = gParam.readFunction; int flags = listenType == CONN_HTTP_SERVER ? 0 : 1; while(1) { __try { struct control_header header = {0}; int nRecv; //首先读取声音控制信息 int nRead = myRead(ftpfd, (char*)&header, sizeof(header), 0, 0, flags); if(nRead < 0 || (nRead == 0 && listenType != CONN_HTTP_SERVER)) { KDebug("Read from %p failed", ftpfd); nStatus = -1; goto leave; } if(!ISVALID_HEADER(header)) { KDebug("audioThread ISVALID_HEADER %s = FALSE", header.magic); continue; } if(header.dataLen > 0) { //然后读取声音数据 nRead = myRead(ftpfd, img, header.dataLen, header.isCompressed, imgSize, flags); if(nRead > 0 || (nRead == 0 && listenType == CONN_HTTP_SERVER)) header.dataLen = nRead; else { if(nRead <= -2) { KDebug("Read data encrypt from %p failed", ftpfd); continue; } else { KDebug("Connection %p lost", ftpfd); nStatus = -1; break; } } } //处理声音数据 unsigned short cmd = header.command; unsigned short resp = header.response; int dataLen = header.dataLen; int seq = header.seq; static CBuffer recvBuf; if(resp != 0) { gView->OnOperationFailed(cmd, resp); continue; } if(seq == 1 && dataLen > 0) recvBuf.ClearBuffer() ; if(dataLen > 0) recvBuf.Write((PBYTE)img, dataLen); else { if(cmd == CONTROL_AUDIO_DATA) { int len = recvBuf.GetBufferLen(); //KDebug("ProcessData2 %d", len); gView->ProcessData(len); m_Audio->playBuffer(recvBuf.GetBuffer(0), len); } } } __except(EXCEPTION_EXECUTE_HANDLER) { KDebug("audioThread exception"); } } leave: delete []img; return nStatus; }
CString ExecuteHTTPGet (const CString &sInput) { // Parse the input char *pPos = sInput.GetParsePointer() + STR_HTTP_GET_PREFIX.GetLength(); // Parse the URL CString sHost; CString sPath; if (!urlParse(pPos, NULL, &sHost, &sPath)) return CString("Invalid URL."); // If no host, then local host if (sHost.IsEmpty()) sHost = CString("localhost"); // Connect CSocket theSocket; if (!theSocket.Connect(sHost, 80)) return strPattern("Unable to connect to: %s.", sHost); // Compose a request CHTTPMessage Request; Request.InitRequest(CString("GET"), sPath); Request.AddHeader(HEADER_HOST, sHost); Request.AddHeader(HEADER_CONNECTION, CString("keep-alive")); #ifdef DEBUG_REQUEST_FRAGMENT_X Request.AddHeader(HEADER_USER_AGENT, CString("AI1/1.0 (This is a test of the header parsing system in Hexarc. There is probably a bug in which splitting the header across packets will cause failure of the HTTP parsing engine.)")); #else Request.AddHeader(HEADER_USER_AGENT, CString("AI1/1.0")); #endif // Send the request CBuffer Buffer(4096); Request.WriteToBuffer(Buffer); #ifdef DEBUG_REQUEST_FRAGMENT int iTotalLen = Buffer.GetLength(); int iSplit = 105; if (iSplit < iTotalLen) { printf("Split at %d bytes\n", iSplit); CString sPart(Buffer.GetPointer(), iSplit); printf("%s\n", (LPSTR)sPart); theSocket.Write(Buffer.GetPointer(), iSplit); ::Sleep(10); theSocket.Write(Buffer.GetPointer() + iSplit, iTotalLen - iSplit); } else theSocket.Write(Buffer.GetPointer(), Buffer.GetLength()); #else theSocket.Write(Buffer.GetPointer(), Buffer.GetLength()); #endif // Now read the response. We build up a buffer to hold it. CHTTPMessage Response; CBuffer ResponseBuff; // Keep reading until we've got enough (or until the connection drops) while (!Response.IsMessageComplete()) { CBuffer TempBuffer(8192); // Read int iBytesRead = theSocket.Read(TempBuffer.GetPointer(), 8192); TempBuffer.SetLength(iBytesRead); // If we're no making progress, then we're done if (iBytesRead == 0) return strPattern("Unable to read entire message."); // Add to entire buffer ResponseBuff.Write(TempBuffer.GetPointer(), iBytesRead); // Parse to see if we're done if (!Response.InitFromPartialBuffer(TempBuffer)) return strPattern("Unable to parse HTTP message."); } // Done theSocket.Disconnect(); return CString(ResponseBuff.GetPointer(), ResponseBuff.GetLength()); }
bool parseHttpResponse(CBuffer& buffer,bool& haserr) { assert(!buffer.empty()); if(buffer.empty()) return false; haserr = false; if(!bHeaderParsed) bHeaderParsed = ParseResponseHeader(buffer,bGZip,bChunked,nContentLen,nError); if(!bHeaderParsed) return false; if(200 != nError) return true; bool isEnd = false; if(!bChunked) { assert(nContentLen > 0); isEnd = ((int)buffer.cnt() >= nContentLen); } else { static char endChunked[] = "\r\n0\r\n\r\n"; static size_t endChunkedLen = strlen(endChunked); if(buffer.cnt() >= strlen(endChunked)) isEnd = (0 == memcmp(endChunked,(char*)buffer[buffer.rpos() + buffer.cnt() - strlen(endChunked)],strlen(endChunked))); } if(isEnd) { if(!bChunked) { if(bGZip) { // char* p_buf = NULL; // char* p_inbuf = (char*)(buffer[buffer.rpos()]); // int nResult = ungzip(p_inbuf, buffer.cnt(), &p_buf, 1); // assert(Z_OK == nResult); // if(Z_OK == nResult) // { // //gzip有10个字节的头部和8个字节的尾部 // // std::string sBuf(p_buf); // sBuf.erase(sBuf.rfind('}') + 1); // buffer.clear(); // //_pBuffer->Write((uint8*)p_buf,strlen(p_buf)-18); // buffer<<sBuf; // free(p_buf); // } CBuffer outBuffer; if(0 == ungzip2((char*)(buffer[buffer.rpos()]),buffer.cnt(),1,outBuffer)) { outBuffer.swap(buffer); } else { assert(false); } } } else { CBuffer thebuffer; while(!buffer.empty()) { const char* pStart = (const char*)buffer[buffer.rpos()]; char* pEnd = NULL; int datasize = strtol(pStart,&pEnd,16); if(0 == datasize && pEnd == pStart) { haserr = true; break; } if(0 > datasize) { haserr = true; break; } if(datasize > (int)buffer.cnt() -2) { haserr = true; break; } buffer.rpos(buffer.rpos() + (pEnd - pStart) + 2); if(datasize > 0) thebuffer.Write(buffer[buffer.rpos()],datasize); buffer.rpos(buffer.rpos() + datasize + 2); if(0 >= datasize) break; } assert(!haserr); buffer.swap(thebuffer); } } return isEnd; }