//interface defined by EdStream int CgiConnection::onRead() { if ( !getConnector() ) return -1; if ( D_ENABLED( DL_MEDIUM ) ) LOG_D(( getLogger(), "[%s] CgiConnection::onRead()\n", getLogId() )); int len = 0; int ret = 0; do { len = ret = read( HttpGlobals::g_achBuf, G_BUF_SIZE ); if ( ret > 0 ) { if ( D_ENABLED( DL_MEDIUM ) ) LOG_D(( getLogger(), "[%s] process STDOUT %d bytes", getLogId(), len )); //printf( ">>read %d bytes from CGI\n", len ); //achBuf[ ret ] = 0; //printf( "%s", achBuf ); ret = getConnector()->processRespData( HttpGlobals::g_achBuf, len ); if ( ret == -1 ) break; } else { if ( ret ) getConnector()->endResponse( 0, 0 ); break; } }while( len == G_BUF_SIZE ); if (( ret != -1 )&&( getConnector() )) getConnector()->flushResp(); return ret; }
void FileCacheDataEx::release() { switch( getStatus() ) { case MMAPED: if ( m_pCache ) { if ( D_ENABLED( DL_MORE )) LOG_D(( "[MMAP] Release mapped data at %p", m_pCache )); munmap( m_pCache, m_lSize ); s_iCurTotalMMAPCache -= m_lSize; } break; case CACHED: if ( m_pCache ) { s_iCurTotalInMemCache -= m_lSize; free( m_pCache ); } break; default: if ( m_fd != -1 ) { close( m_fd ); m_fd = -1; } } memset( &m_iStatus, 0, (char *)(&m_pCache + 1) - (char *)&m_iStatus ); }
void LshttpdMain::gracefulRestart() { if ( D_ENABLED( DL_LESS ) ) LOG_D(( "Graceful Restart... " )); close( m_fdAdmin ); broadcastSig( SIGTERM, 1 ); s_iRunning = 0; m_pidFile.closePidFile(); m_pServer->passListeners(); int pid = fork(); if ( !pid ) { char achCmd[1024]; int fd = HttpGlobals::getStdErrLogger()->getStdErr(); if ( fd != 2 ) close( fd ); int len = getFullPath( "bin/litespeed", achCmd, 1024 ); achCmd[len - 10] = 0; chdir( achCmd ); achCmd[len - 10] = '/'; if ( execl( achCmd, "litespeed", NULL ) ) { LOG_ERR(( "Failed to start new instance of LiteSpeed Web server!" )); } exit( 0 ); } if ( pid == -1 ) LOG_ERR(( "Failed to restart the server!" )); }
int L4Handler::init(HttpReq &req, const GSockAddr *pGSockAddr, const char *pIP, int iIpLen) { int ret = m_pL4conn->init(pGSockAddr); if (ret != 0) return ret; int hasSlashR = 1; //"\r\n"" or "\n" LoopBuf *pBuff = m_pL4conn->getBuf(); pBuff->append(req.getOrgReqLine(), req.getHttpHeaderLen()); char *pBuffEnd = pBuff->end(); assert(pBuffEnd[-1] == '\n'); if (pBuffEnd[-2] == 'n') hasSlashR = 0; else { assert(pBuffEnd[-2] == '\r'); } pBuff->used( -1 * hasSlashR - 1); pBuff->append("X-Forwarded-For", 15); pBuff->append(": ", 2); pBuff->append(pIP, iIpLen); if (hasSlashR) pBuff->append("\r\n\r\n", 4); else pBuff->append("\n\n", 2); continueRead(); if ( D_ENABLED( DL_LESS ) ) { LOG_D ((getLogger(), "[%s] L4Handler: init web socket, reqheader [%s], len [%d]", getLogId(), req.getOrgReqLine(), req.getHttpHeaderLen() )); } return 0; }
int FcgiRequest::processStdErr( char * pBuf, int size ) { HttpExtConnector * pConnector = getConnector(); assert( pConnector ); if ( D_ENABLED( DL_MEDIUM ) ) LOG_D(( pConnector->getLogger(), "[%s] process STDERR %d bytes", pConnector->getLogId(), size )); return pConnector->processErrData( pBuf, size ); }
int FcgiRequest::sendAbortRec( ) { if ( D_ENABLED( DL_LESS ) ) LOG_D(( getLogger(), "[%s] [FCGI] send abort packet!", getConnector()->getLogId() )); FCGI_Header rec; FcgiRecord::setRecordHeader( rec, FCGI_ABORT_REQUEST, m_iId, 0 ); return m_pFcgiConn->sendRecord( (const char *)&rec, sizeof( rec ) ); }
int LshttpdMain::preFork() { if ( D_ENABLED( DL_LESS ) ) LOG_D(( "[AutoRestarter] prepare to fork new child process to handle request!" )); if ( LsiApiHooks::getServerHooks()->isEnabled( LSI_HKPT_MAIN_PREFORK) ) LsiApiHooks::getServerHooks()->runCallbackNoParam(LSI_HKPT_MAIN_PREFORK, NULL); return 0; }
int LsapiConn::sendAbortReq() { if ( D_ENABLED( DL_LESS ) ) LOG_D(( getLogger(), "[%s] [LSAPI] send abort packet!", getLogId() )); lsapi_packet_header rec; LsapiReq::buildPacketHeader( &rec, LSAPI_ABORT_REQUEST, LSAPI_PACKET_HEADER_LEN ); return write( (char *)&rec, sizeof( rec ) ); }
int FcgiRequest::onStdOut() { HttpExtConnector * pConnector = getConnector(); assert( pConnector ); if ( D_ENABLED( DL_MEDIUM ) ) LOG_D(( pConnector->getLogger(), "[%s] onStdOut()", pConnector->getLogId() )); return pConnector->extInputReady(); }
int CgiConnection::onError() { if ( !getConnector() ) return -1; if ( D_ENABLED( DL_MEDIUM ) ) LOG_D(( getLogger(), "[%s] CgiConnection::onError()\n", getLogId() )); //getState() = HEC_COMPLETE; getConnector()->endResponse( SC_500, 0 ); return -1; }
int JConn::processPacketHeader( unsigned char * &p ) { if (( *p != AJP_RESP_PREFIX_B1)|| ( *(p+1) != AJP_RESP_PREFIX_B2 )) { LOG_ERR(( getLogger(), "[%s] Invalid AJP response signature %x%x", getLogId(), (int) *p, (int) *(p+1) )); return -1; } p+= 2; m_curPacketSize = getInt( p ); if ( m_curPacketSize > AJP_MAX_PKT_BODY_SIZE ) { LOG_ERR(( getLogger(), "[%s] packet size is too large - %d", getLogId(), m_curPacketSize )); return -1; } m_packetType = *p++; m_packetLeft = m_curPacketSize - 1; switch(m_packetType) { case AJP13_RESP_BODY_CHUNK: m_iPacketState = CHUNK_LEN; break; case AJP13_RESP_HEADERS: m_iPacketState = STATUS_CODE; break; case AJP13_END_RESP: if ( *p != 1) { if ( D_ENABLED( DL_LESS ) ) LOG_D(( getLogger(), "[%s] close connection required by servlet engine %s ", getLogId(), getWorker()->getURL() )); setState( CLOSING ); } p++; if ( getConnector() ) { incReqProcessed(); if ( getState() == ABORT ) setState( PROCESSING ); setInProcess( 0 ); getConnector()->endResponse( 0, 0 ); } break; case AJP13_MORE_REQ_BODY: default: break; } return 0; }
int LsapiConn::doError( int err) { if ( D_ENABLED( DL_LESS ) ) LOG_D(( getLogger(), "[%s] LsapiConn::doError()", getLogId() )); if ( getConnector()) { int state = getConnector()->getState(); if ( !(state & (HEC_FWD_RESP_BODY | HEC_ABORT_REQUEST | HEC_ERROR|HEC_COMPLETE) )) { if ( D_ENABLED( DL_LESS ) ) LOG_D(( getLogger(), "[%s] Lsapi Peer closed connection, " "try another connection!", getLogId() )); connError( err ); return 0; } if ( !(state & HEC_COMPLETE) ) getConnector()->endResponse( SC_500, -1 ); } return 0; }
int StaticFileCacheData::tryCreateGziped() { if ( !s_iAutoUpdateStaticGzip ) return -1; off_t size = m_fileData.getFileSize(); if (( size > s_iMaxFileSize )||( size < s_iMinFileSize )) return -1; char *p = m_gzippedPath.buf() + m_gzippedPath.len() + 4; int fd = createLockFile( m_gzippedPath.buf(), p ); if ( fd == -1 ) return -1; close( fd ); if ( size < 409600 ) { long ret = compressFile(); *p = 'l'; unlink( m_gzippedPath.buf() ); *p = 0; return ret; } else { //IMPROVE: move this to a standalone process, // fork() is too expensive. if ( D_ENABLED( DL_MORE )) { LOG_D(( "To compressed file %s in another process.", m_real.c_str() )); } int forkResult; forkResult = fork(); if( forkResult ) //error or parent process { return -1; } //child process setpriority( PRIO_PROCESS, 0, 5 ); long ret = compressFile(); if ( ret == -1 ) { LOG_WARN(( "Failed to compress file %s!", m_real.c_str() )); } *p = 'l'; unlink( m_gzippedPath.buf() ); *p = 0; exit(1); } }
int L4Handler::onWriteEx() { bool full = ((getBuf()->available() == 0) ? true : false); int length; while ((length = getBuf()->blockSize()) > 0 ) { int n = getStream()->write(getBuf()->begin(), length); if ( D_ENABLED( DL_LESS ) ) LOG_D ((getLogger(), "[%s] L4Handler: write [%d of %d]", getLogId(), n, length )); if (n > 0) getBuf()->pop_front(n); else if ( n == 0 ) break; else // if (n < 0) { closeBothConnection(); return -1; } } if (getBuf()->available() != 0) { if (full) m_pL4conn->continueRead(); if ( getBuf()->empty() ) { suspendWrite(); if ( D_ENABLED( DL_LESS ) ) { LOG_D(( getLogger(), "[%s] [L4conn] m_pL4conn->continueRead", getLogId() )); } } } return 0; }
int L4Handler::onReadEx() { bool empty = m_pL4conn->getBuf()->empty(); int space; while ( (space = m_pL4conn->getBuf()->contiguous()) > 0) { int n = getStream()->read(m_pL4conn->getBuf()->end(), space); if ( D_ENABLED( DL_LESS ) ) { LOG_D ((getLogger(), "[%s] L4Handler: read [%d]", getLogId(), n )); } if (n > 0) m_pL4conn->getBuf()->used(n); else if ( n == 0 ) break; else // if (n < 0) { closeBothConnection(); return -1; } } if ( !m_pL4conn->getBuf()->empty() ) { m_pL4conn->doWrite(); if ( !m_pL4conn->getBuf()->empty() && empty) m_pL4conn->continueWrite(); if (m_pL4conn->getBuf()->available() <= 0 ) { suspendRead(); if ( D_ENABLED( DL_LESS ) ) LOG_D ((getLogger(), "[%s] L4Handler: suspendRead", getLogId() )); } } return 0; }
int CgiConnection::onWrite() { if ( !getConnector() ) return -1; if ( D_ENABLED( DL_MEDIUM ) ) LOG_D(( getLogger(), "[%s] CgiConnection::onWrite()\n", getLogId() )); int ret = extOutputReady(); if (!( getConnector()->getState() & HEC_FWD_REQ_BODY )) { suspendWrite(); } return ret; }
int SSIEngine::executeComponent( HttpSession *pSession, SSIComponent * pComponent ) { AutoBuf * pBuf; int ret; if ( D_ENABLED( DL_MORE ) ) LOG_D(( pSession->getLogger(), "[%s] SSI Process component: %d", pSession->getLogId(), pComponent->getType() )); switch( pComponent->getType() ) { case SSIComponent::SSI_String: pBuf = pComponent->getContentBuf(); pSession->appendDynBody( pBuf->begin(), pBuf->size() ); break; case SSIComponent::SSI_Config: updateSSIConfig( pSession, pComponent, pSession->getReq()->getSSIRuntime() ); break; case SSIComponent::SSI_Echo: processEcho( pSession, pComponent ); break; case SSIComponent::SSI_Exec: ret = processExec( pSession, pComponent ); return ret; break; case SSIComponent::SSI_FSize: case SSIComponent::SSI_Flastmod: processFileAttr( pSession, pComponent ); break; case SSIComponent::SSI_Include: ret = processInclude( pSession, pComponent ); return ret; break; case SSIComponent::SSI_Printenv: processPrintEnv( pSession ); break; case SSIComponent::SSI_Set: processSet( pSession, pComponent ); break; case SSIComponent::SSI_If: case SSIComponent::SSI_Elif: processIf( pSession, (SSI_If *)pComponent ); break; //SSI_Else, //SSI_Elif, //SSI_Endif, } return 0; }
void LocalWorker::removeUnixSocket() { const GSockAddr &addr = ((LocalWorkerConfig *)getConfigPointer())->getServerAddr(); if (( m_fdApp >= 0 )&&( getPidList()->size() > 0 )&& ( addr.family() == PF_UNIX )) { if ( D_ENABLED( DL_LESS ) ) LOG_D(( "[%s] remove unix socket: %s", getName(), addr.getUnix() )); unlink( addr.getUnix() ); close( m_fdApp ); m_fdApp = -2; getConfigPointer()->altServerAddr(); } }
void LocalWorker::cleanStopPids( ) { if (( m_pidListStop )&& ( m_pidListStop->size() > 0 )) { pid_t pid; PidList::iterator iter, iterDel; for( iter = m_pidListStop->begin(); iter != m_pidListStop->end(); ) { pid = (pid_t)(long)iter->first(); long delta = DateTime::s_curTime - (long)iter->second(); int sig = 0; iterDel = iter; iter = m_pidListStop->next( iter ); if ( delta > GRACE_TIMEOUT ) { if (( kill( pid, 0 ) == -1 )&&( errno == ESRCH )) { m_pidListStop->erase( iterDel ); continue; } if ( delta > KILL_TIMEOUT ) { sig = SIGKILL; LOG_NOTICE(( "[%s] Send SIGKILL to process [%d] that won't stop.", getName(), pid )); } else { sig = m_sigGraceStop; LOG_NOTICE(( "[%s] Send SIGTERM to process [%d].", getName(), pid )); } if ( kill( pid , sig ) != -1 ) { if ( D_ENABLED( DL_LESS ) ) LOG_D(( "[%s] kill pid: %d", getName(), pid )); } else if ( errno == EPERM ) { PidRegistry::markToStop( pid, KILL_TYPE_TERM ); } } } } }
int FileCacheDataEx::readyData(const char * pPath) { int fd; int ret = openFile( pPath, fd ); if ( ret ) return ret; if ( (size_t)m_lSize < s_iMaxInMemCacheSize ) { ret = allocateCache( m_lSize ); if ( ret == 0 ) { ret = nio_read( fd, m_pCache, m_lSize ); if ( ret == m_lSize ) { close( fd ); return 0; } else { release(); } } } else if (( (size_t)m_lSize < s_iMaxMMapCacheSize ) &&((size_t)m_lSize + s_iCurTotalMMAPCache < s_iMaxTotalMMAPCache )) { m_pCache = (char *)mmap( 0, m_lSize, PROT_READ, MAP_PRIVATE, fd, 0 ); s_iCurTotalMMAPCache += m_lSize; if ( D_ENABLED( DL_MORE )) LOG_D(( "[MMAP] Map %p to file:%s", m_pCache, pPath )); if ( m_pCache == MAP_FAILED ) { m_pCache = 0; } else { setStatus( MMAPED ); close( fd ); return 0; } } setfd( fd ); fcntl( fd, F_SETFD, FD_CLOEXEC ); return 0; }
int HttpListener::checkAccess( struct conn_data * pData ) { struct sockaddr * pPeer = ( struct sockaddr *) pData->achPeerAddr; if (( AF_INET6 == pPeer->sa_family )&& ( IN6_IS_ADDR_V4MAPPED( &((struct sockaddr_in6 *)pPeer)->sin6_addr )) ) { pPeer->sa_family = AF_INET; ((struct sockaddr_in *)pPeer)->sin_addr.s_addr = *((in_addr_t *)&pData->achPeerAddr[20]); } ClientInfo * pInfo = HttpGlobals::getClientCache()->getClientInfo( pPeer ); pData->pInfo = pInfo; if ( D_ENABLED( DL_MORE )) LOG_D(( "[%s] New connection from %s:%d.", getAddrStr(), pInfo->getAddrString(), ntohs( ((struct sockaddr_in*)pPeer)->sin_port) )); return pInfo->checkAccess(); }
int JConn::doRead() { int len = 0; int ret = 0; while( true ) { int toRead = m_pRespBufEnd - m_pCurPos; len = read( (char *)m_pCurPos, toRead); if ( len > 0 ) { if ( D_ENABLED( DL_MEDIUM ) ) LOG_D(( getLogger(), "[%s] process STDOUT %d bytes", getLogId(), len )); //printf( ">>read %d bytes from CGI\n", len ); //::write( 1, m_pCurPos, len ); m_pCurPos += len; ret = processRespData(); if ( ret == -1 ) { errno = EIO; len = -1; break; } if ( len < toRead ) { if (( m_packetType != AJP13_END_RESP )&& ( getConnector() )) getConnector()->flushResp(); break; } } else break; } if ( getState() == ABORT ) { if ( getConnector() ) { incReqProcessed(); getConnector()->endResponse( 0, 0 ); } } return len; }
int LsapiConn::connect( Multiplexer * pMplx ) { LsapiWorker * pWorker = (LsapiWorker *)getWorker(); if ( pWorker->selfManaged() ) return ExtConn::connect( pMplx ); int fds[2]; errno = ECONNRESET; if ( socketpair( AF_UNIX, SOCK_STREAM, 0, fds ) == -1 ) { LOG_ERR(( "[LsapiConn::connect()] socketpair() failed!" )); return -1; } fcntl( fds[0], F_SETFD, FD_CLOEXEC ); setReqProcessed( 0 ); setToStop( 0 ); //if ( pApp->getCurInstances() >= pApp->getConfig().getInstances() ) // return -1; m_pid = LocalWorker::workerExec( pWorker->getConfig(), fds[1] ); ::close( fds[1] ); if ( m_pid == -1 ) { ::close( fds[0] ); return -1; } else { if ( D_ENABLED( DL_LESS ) ) LOG_D(( "[%s] add child process pid: %d", pWorker->getName(), m_pid )); PidRegistry::add( m_pid, pWorker, 0 ); } ::fcntl( fds[0], F_SETFL, HttpGlobals::getMultiplexer()->getFLTag() ); init( fds[0], pMplx ); //Increase the number of successful request to avoid max connections reduction. incReqProcessed(); setState( PROCESSING ); onWrite(); return 1; }
int LocalWorker::stop() { pid_t pid; PidList::iterator iter; removeUnixSocket(); LOG_NOTICE(( "[%s] stop worker processes", getName() )); for( iter = getPidList()->begin(); iter != getPidList()->end(); ) { pid = (pid_t)(long)iter->first(); iter = getPidList()->next( iter ); killProcess( pid ); if ( D_ENABLED( DL_LESS ) ) LOG_D(( "[%s] kill pid: %d", getName(), pid )); } moveToStopList(); setState( ST_NOTSTARTED ); return 0; }
int CgidConn::doWrite() { if ( !getConnector() ) return -1; if ( D_ENABLED( DL_MEDIUM ) ) LOG_D(( getLogger(), "[%s] CgidConn::onWrite()\n", getLogId() )); int ret = getConnector()->extOutputReady(); if (!( getConnector()->getState() & HEC_FWD_REQ_BODY )) { if ( m_iTotalPending > 0 ) return flush(); else { suspendWrite(); ::shutdown( getfd(), SHUT_WR ); } } return ret; }
int LsapiConn::doRead() { if ( D_ENABLED( DL_LESS ) ) LOG_D(( getLogger(), "[%s] LsapiConn::doRead()\n", getLogId() )); int ret; ret = processResp(); // if ( m_respState ) // ret = processResp(); // else // ret = processRespBuffed(); if ( getState() == ABORT ) { if ( getConnector() ) { incReqProcessed(); getConnector()->endResponse( 0, 0 ); } } return ret; }
int JConn::addRequest( ExtRequest * pReq ) { assert( pReq ); setConnector( (HttpExtConnector *)pReq ); reset(); m_pCurPos = m_respBuf; m_iPacketState = PACKET_HEADER; int ret = buildReqHeader(); if ( ret ) { if ( D_ENABLED( DL_LESS ) ) LOG_D(( getLogger(), "[%s] Request header can't fit into 8K buffer, " "can't forward request to servlet engine", getLogId() )); ((HttpExtConnector *)pReq)->setProcessor( NULL ); setConnector( NULL ); ret = SC_500; } return ret; //return 0; }
int LsapiConn::readStderrStream() { register HttpExtConnector * pHEC = getConnector(); int ret; size_t bufLen; char achBuf[2049]; while( m_iPacketLeft > 0 ) { char * pBuf = achBuf; bufLen = sizeof( achBuf ); int toRead = m_iPacketLeft + sizeof( m_respHeader ); if ( toRead > (int)bufLen ) toRead = bufLen ; ret = read( pBuf, toRead ); if ( ret > 0 ) { int len, packetLen; if ( D_ENABLED( DL_MEDIUM ) ) LOG_D(( getLogger(), "[%s] process STDERR stream %d bytes, packet left: %d", getLogId(), ret, m_iPacketLeft )); if ( ret >= m_iPacketLeft ) { packetLen = m_iPacketLeft; m_iPacketLeft = 0; } else { packetLen = ret; m_iPacketLeft -= ret; } if ( pHEC ) pHEC->processErrData( pBuf, packetLen ); else { char ch = pBuf[packetLen]; pBuf[ packetLen ] = 0; LOG_NOTICE(( getLogger(), "[%s] [LSAPI:STDERR]: %s", getLogId(), pBuf )); pBuf[ packetLen ] = ch; } if ( m_iPacketLeft <= 0 ) { m_iPacketHeaderLeft = LSAPI_PACKET_HEADER_LEN; if ( ret > packetLen ) { if ( D_ENABLED( DL_MEDIUM ) ) LOG_D(( getLogger(), "[%s] process packet header %d bytes", getLogId(), ret - packetLen )); len = processPacketHeader( pBuf + packetLen, ret - packetLen ); if ( len <= 0 ) return len; if (( m_respHeader.m_type != LSAPI_STDERR_STREAM )|| ( m_iPacketLeft <= 0 )) return 1; } else break; } } else { return ret; } } return 1; }
int LsapiConn::readRespBody() { register HttpExtConnector * pHEC = getConnector(); int ret; size_t bufLen; if ( !pHEC ) return -1; int &respState = pHEC->getRespState(); while( m_iPacketLeft > 0 ) { char * pBuf = pHEC->getRespBuf( bufLen ); if ( !pBuf ) { return -1; } int toRead = m_iPacketLeft + sizeof( m_respHeader ); if ( toRead > (int)bufLen ) toRead = bufLen ; ret = read( pBuf, toRead ); if ( ret > 0 ) { int len, packetLen; if ( D_ENABLED( DL_MEDIUM ) ) LOG_D(( getLogger(), "[%s] process response stream %d bytes, packet left: %d", getLogId(), ret, m_iPacketLeft )); if ( ret >= m_iPacketLeft ) { packetLen = m_iPacketLeft; m_iPacketLeft = 0; } else { packetLen = ret; m_iPacketLeft -= ret; } if ( !(respState & 0xff) ) { len = pHEC->processRespData( pBuf, packetLen ); if ( respState & 0xff ) m_respState = LSAPI_CONN_READ_RESP_BODY; if ( len == -1 ) return len; } else { len = pHEC->respBodyRecv( pBuf, packetLen ); } if ( m_iPacketLeft <= 0 ) { m_iPacketHeaderLeft = LSAPI_PACKET_HEADER_LEN; if ( ret > packetLen ) { if ( D_ENABLED( DL_MEDIUM ) ) LOG_D(( getLogger(), "[%s] process packet header %d bytes", getLogId(), ret - packetLen )); int len1 = processPacketHeader( pBuf + packetLen, ret - packetLen ); if ( len1 <= 0 ) return len1; if (( m_respHeader.m_type != LSAPI_RESP_STREAM )|| ( m_iPacketLeft <= 0 )) return 1; } else break; } if ( len == 1) return 0; if ( len ) return len; if ( ret < (int)toRead) { pHEC->flushResp(); return 0; } } else { return ret; } } return 1; }
int LsapiConn::processRespHeader() { register HttpExtConnector * pHEC = getConnector(); int ret; int len = 0; if ( !pHEC ) return -1; int &respState = pHEC->getRespState(); if ( !(respState & 0xff) ) { while( m_iPacketLeft > 0 ) { len = ExtConn::read( m_pRespHeader, m_pRespHeaderBufEnd - m_pRespHeader ); if ( D_ENABLED( DL_MEDIUM ) ) LOG_D(( getLogger(), "[%s] process response header %d bytes", getLogId(), len )); if ( len > 0 ) { m_iPacketLeft -= len; ret = processRespHeader( m_pRespHeader + len, respState ); switch( ret ) { case -2: LOG_WARN(( getLogger(), "[%s] Invalid Http response header, retry!", getLogId() )); //debug code //::write( 1, pBuf, len ); errno = ECONNRESET; case -1: return -1; } if ( m_iPacketLeft > 0 ) { m_pRespHeader += len; if (( m_pRespHeader > m_pRespHeaderProcess )&& ( m_pRespHeader != &m_respBuf[ m_respInfo.m_cntHeaders * sizeof(short) ] )) { len = m_pRespHeader - m_pRespHeaderProcess; memmove( &m_respBuf[ m_respInfo.m_cntHeaders * sizeof(short) ], m_pRespHeaderProcess, m_pRespHeader - m_pRespHeaderProcess ); m_pRespHeaderProcess = &m_respBuf[ m_respInfo.m_cntHeaders * sizeof(short) ]; m_pRespHeader = m_pRespHeaderProcess + len; } else m_pRespHeader = m_pRespHeaderProcess = &m_respBuf[ m_respInfo.m_cntHeaders * sizeof(short) ]; setRespBuf( m_pRespHeader ); } } else return len; } if ( m_iPacketLeft == 0 ) { m_iPacketHeaderLeft = LSAPI_PACKET_HEADER_LEN; len = 1; } return len; } else { //error: protocol error, header received already. errno = EIO; return -1; } }