예제 #1
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;
}
예제 #2
0
//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;
}
예제 #3
0
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;
}
예제 #4
0
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;
}
예제 #5
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;
}
예제 #6
0
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;
}
예제 #7
0
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;
}
예제 #8
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;
}
예제 #9
0
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;
}
예제 #10
0
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;
    }    
}
예제 #11
0
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;
}
예제 #12
0
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;
}
예제 #13
0
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();
}
예제 #14
0
 virtual const char *buildLogId() {  return getLogId(); }