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; }
//interface defined by EdStream int CgidConn::doRead() { if ( !getConnector() ) return -1; if ( D_ENABLED( DL_MEDIUM ) ) LOG_D(( getLogger(), "[%s] CgidConn::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 ); return 0; } break; } }while( len == G_BUF_SIZE ); if (( ret != -1 )&&( getConnector() )) getConnector()->flushResp(); return ret; }
int LsapiConn::sendReqHeader() { int ret = m_lsreq.buildReq( getConnector()->getHttpConn(), &m_iTotalPending ); if ( ret ) { LOG_INFO(( getLogger(), "[%s] Failed to build LSAPI request header, " "can't forward request to external LSAPI application ", getLogId() )); // ((HttpExtConnector *)pReq)->setProcessor( NULL ); // setConnector( NULL ); return -1; } setInProcess( 1 ); m_lReqSentTime = DateTime::s_curTime; return 1; }
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 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; } }
int LsapiConn::processResp() { int ret; while( getState() == PROCESSING ) { if ( m_iPacketHeaderLeft > 0 ) { ret = read( ((char *)&m_respHeader) + sizeof( m_respHeader ) - m_iPacketHeaderLeft, m_iPacketHeaderLeft ); if ( D_ENABLED( DL_MEDIUM ) ) LOG_D(( getLogger(), "[%s] process packet header %d bytes", getLogId(), ret )); if ( ret > 0 ) { m_iPacketHeaderLeft -= ret; if ( m_iPacketHeaderLeft == 0 ) { m_iPacketLeft = verifyPacketHeader( &m_respHeader ) - LSAPI_PACKET_HEADER_LEN; if ( m_iPacketLeft < 0 ) { const char * p = (const char *)&m_respHeader; LOG_WARN(( "[%s] LSAPI Packet header is invalid," "('%c','%c','%c','%c','%c','%c','%c','%c')", getLogId(), *p, *(p+1), *(p+2), *(p+3), *(p+4), *(p+5), *(p+6), *(p+7) )); break; } // if ( m_iPacketLeft > LSAPI_MAX_HEADER_LEN ) // { // LOG_WARN(( "[%s] LSAPI Packet is too large: %d", // getLogId(), m_iPacketLeft )); // break; // } switch( m_respHeader.m_type ) { case LSAPI_RESP_END: m_respState = 0; incReqProcessed(); setInProcess( 0 ); getConnector()->endResponse( 0, 0 ); return 0; case LSAPI_RESP_HEADER: m_iCurRespHeader = 0; m_respState = LSAPI_CONN_READ_RESP_INFO; m_pRespHeaderProcess = (char *)&m_respInfo; setRespBuf( m_pRespHeaderProcess ); break; case LSAPI_REQ_RECEIVED: m_reqReceived = 1; break; } } } else { if (( m_respState == LSAPI_CONN_READ_RESP_BODY )&& ( getConnector())) getConnector()->flushResp(); return ret; } } if ( m_iPacketLeft > 0 ) { switch( m_respHeader.m_type ) { case LSAPI_RESP_HEADER: ret = processRespHeader(); if ( ret <= 0 ) return ret; break; case LSAPI_RESP_STREAM: ret = readRespBody(); if ( ret <= 0 ) { if (( m_respState == LSAPI_CONN_READ_RESP_BODY )&& ( getConnector())) getConnector()->flushResp(); return ret; } break; case LSAPI_STDERR_STREAM: ret = readStderrStream(); if ( ret <= 0 ) return ret; break; default: //error: protocol error LOG_NOTICE(( getLogger(), "[%s] Unknown Packet Type %c, LSAPI protcol is broken.", getLogId(), m_respHeader.m_type )); errno = EIO; return -1; } } else { m_iPacketHeaderLeft = LSAPI_PACKET_HEADER_LEN; } } errno = EIO; return -1; }
int LsapiConn::processRespBuffed() { int ret; int left; int len; m_pRespHeader = (char *)&m_respHeader; m_pRespHeaderBufEnd = &m_respBuf[1024]; ret = read( m_pRespHeader, m_pRespHeaderBufEnd - m_pRespHeader ); if ( ret <= 0 ) return ret; if ( ret < (int)sizeof( lsapi_packet_header ) ) { m_iPacketHeaderLeft = sizeof( lsapi_packet_header ) - ret; return ret; } m_pRespHeaderBufEnd = m_pRespHeader + ret; m_iPacketLeft = verifyPacketHeader( &m_respHeader ) - LSAPI_PACKET_HEADER_LEN; if ( m_iPacketLeft < 0 ) { errno = EIO; return -1; } if ( !m_iPacketLeft ) m_iPacketHeaderLeft = LSAPI_PACKET_HEADER_LEN; else m_iPacketHeaderLeft = 0; if ( ret < (int)(sizeof( lsapi_packet_header ) + sizeof( lsapi_resp_info )) ) { m_pRespHeader += ret; switch( m_respHeader.m_type ) { case LSAPI_RESP_END: m_respState = LSAPI_CONN_IDLE; incReqProcessed(); setInProcess( 0 ); getConnector()->endResponse( 0, 0 ); return 0; case LSAPI_RESP_HEADER: m_iCurRespHeader = 0; m_respState = LSAPI_CONN_READ_RESP_INFO; m_pRespHeaderProcess = (char *)&m_respInfo; setRespBuf( m_pRespHeaderProcess ); return ret; case LSAPI_REQ_RECEIVED: m_reqReceived = 1; break; } m_pRespHeaderProcess = (char *)&m_respInfo; } else { m_iCurRespHeader = 0; m_respState = LSAPI_CONN_READ_HEADER_LEN; m_pRespHeaderProcess = m_respBuf; } while( (left = m_pRespHeaderBufEnd - m_pRespHeaderProcess) > 0 ) { if ( m_iPacketHeaderLeft > 0 ) { ret = processPacketHeader( m_pRespHeaderProcess, left ); if ( ret <= 0 ) return ret; m_pRespHeaderProcess += ret; left -= ret; } if ( m_iPacketLeft > 0 ) { register HttpExtConnector * pHEC = getConnector(); if ( !pHEC ) return -1; int &respState = pHEC->getRespState(); if ( m_iPacketLeft < left ) { len = m_iPacketLeft; m_iPacketLeft = 0; m_iPacketHeaderLeft = LSAPI_PACKET_HEADER_LEN; } else { len = left; m_iPacketLeft -= left; left = 0; } switch( m_respHeader.m_type ) { case LSAPI_RESP_HEADER: ret = processRespHeader(m_pRespHeaderBufEnd, respState); if ( ret < 0 ) return ret; break; case LSAPI_RESP_STREAM: if ( D_ENABLED( DL_MEDIUM ) ) LOG_D(( getLogger(), "[%s] process response stream %d bytes", getLogId(), len )); ret = pHEC->processRespData( m_pRespHeaderProcess, len ); if ( respState & 0xff ) m_respState = LSAPI_CONN_READ_RESP_BODY; if ( ret == -1 ) return ret; m_pRespHeaderProcess += len; break; case LSAPI_STDERR_STREAM: if ( D_ENABLED( DL_MEDIUM ) ) LOG_D(( getLogger(), "[%s] process STDERR stream %d bytes", getLogId(), len )); ret = pHEC->processErrData( m_pRespHeaderProcess, len ); m_pRespHeaderProcess += len; break; default: LOG_NOTICE(( getLogger(), "[%s] Unknown Packet Type %c, LSAPI protcol is broken.", getLogId(), m_respHeader.m_type )); errno = EIO; return -1; } } else m_iPacketHeaderLeft = LSAPI_PACKET_HEADER_LEN; } return 1; }
void LsapiConn::onTimer() { if ( m_respState && !m_reqReceived &&( DateTime::s_curTime - m_lReqSentTime >= 3 )) { LOG_NOTICE(( getLogger(), "[%s] No request delivery notification has been received from LSAPI application, possible dead lock.", getLogId() )); if ( ((LsapiWorker *)getWorker())->getConfig().getSelfManaged() ) getWorker()->addNewProcess(); else connError( ETIMEDOUT ); return; } /* if ( m_lLastRespRecvTime ) { long tm = time( NULL ); long delta = tm - m_lLastRespRecvTime; if (( delta > getWorker()->getTimeout() )&&( m_iRespBodyRecv )) { if ( m_pChunkIS ) LOG_INFO(( getLogger(), "[%s] Timeout, partial chunk encoded body received," " received: %d, chunk len: %d, remain: %d!", getLogId(), m_iRespBodyRecv, m_pChunkIS->getChunkLen(), m_pChunkIS->getChunkRemain() )); else LOG_INFO((getLogger(), "[%s] Timeout, partial response body received," " body len: %d, received: %d!", getLogId(), m_iRespBodySize, m_iRespBodyRecv )); setState( CLOSING ); if ( getConnector() ) getConnector()->endResponse( 0, 0 ); return; } else if (( m_pChunkIS )&&( delta > 2 )) { if ((!m_pChunkIS->getChunkLen())&&( getConnector() )) { LOG_INFO(( getLogger(), "[%s] Missing trailing CRLF in Chunked Encoding!", getLogId() )); setState( CLOSING ); getConnector()->endResponse( 0, 0 ); return; } } }*/ ExtConn::onTimer(); }
virtual const char *buildLogId() { return getLogId(); }