コード例 #1
0
int LsapiConn::processPacketHeader( char * pBuf, int len )
{
    if ( m_iPacketHeaderLeft < len )
    {
        len = m_iPacketHeaderLeft;
    }
    memmove( ((char *)&m_respHeader) + sizeof( m_respHeader ) - m_iPacketHeaderLeft,
            pBuf, len );

    m_iPacketHeaderLeft -= len;

    if ( m_iPacketHeaderLeft == 0 )
    {
        m_iPacketLeft = verifyPacketHeader( &m_respHeader ) -
                LSAPI_PACKET_HEADER_LEN;
        if ( m_iPacketLeft < 0 )
        {
            LOG_WARN(( "[%s] LSAPI Packet header is invalid!",
                    getLogId() ));
			errno = EIO;
            return -1;
        }
//         if ( m_iPacketLeft > LSAPI_MAX_HEADER_LEN )
//         {
//             LOG_WARN(( "[%s] LSAPI Packet is too large: %d",
//                     getLogId(), m_iPacketLeft ));
// 			errno = EIO;
//             return -1;
//         }
        switch( m_respHeader.m_type )
        {
        case LSAPI_RESP_END:
			incReqProcessed();
            setInProcess( 0 );
            if ( getConnector() )
                getConnector()->endResponse( 0, 0 );
            return 0;
        case LSAPI_RESP_HEADER:
            if ( m_respState == LSAPI_CONN_READ_RESP_BODY )
            {
                LOG_WARN(( "[%s] Invalid LSAPI Response Header Packet following STREAM packet",
                    getLogId() ));
			    errno = EIO;
                return -1;
            }
            else
            {
                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;
        }
    }
    return len;
}
コード例 #2
0
ファイル: jconn.cpp プロジェクト: ewwink/openlitespeed
int JConn::sendReqHeader()
{
    m_iovec.clear();
    m_iovec.append( m_buf, m_pBufEnd - m_buf );
    m_iTotalPending = m_pBufEnd - m_buf;
    setInProcess( 1 );
    return 1;
}
コード例 #3
0
ファイル: jconn.cpp プロジェクト: ewwink/openlitespeed
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;    
}
コード例 #4
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;
}
コード例 #5
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;
}
コード例 #6
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;
}
コード例 #7
0
ファイル: proxyconn.cpp プロジェクト: 52M/openlitespeed
int ProxyConn::readRespBody()
{
    HttpExtConnector *pHEC = getConnector();
    int ret = 0;
    size_t bufLen;
    if (!pHEC)
        return LS_FAIL;
    if (m_pChunkIS)
    {
        while (getState() != ABORT && !m_pChunkIS->eos())
        {
            char *pBuf = pHEC->getRespBuf(bufLen);
            if (!pBuf)
                return LS_FAIL;
            ret = m_pChunkIS->read(pBuf, bufLen);
            if (ret >= 0)
            {
                if (ret > 0)
                {
                    m_lLastRespRecvTime = time(NULL);
                    m_iRespBodyRecv += ret;
                    int ret1 = pHEC->processRespBodyData(pBuf, ret);
                    if (ret1 == -1)
                        ret = LS_FAIL;
                    if (ret > 1024 || (ret < (int)bufLen))
                        pHEC->flushResp();
                }
                if (m_pChunkIS->eos())
                {
                    ret = 0;
                    break;
                }
                pHEC->flushResp();
                return ret;
            }
            else
            {
                if ((errno == ECONNRESET) && (getConnector()))
                    break;
                return LS_FAIL;
            }
        }
    }
    else
    {
        while ((getState() != ABORT) && (m_iRespBodySize - m_iRespBodyRecv > 0))
        {
            char *pBuf = pHEC->getRespBuf(bufLen);
            if (!pBuf)
                return LS_FAIL;
            int64_t toRead = m_iRespBodySize - m_iRespBodyRecv;
            if (toRead > (int64_t)bufLen)
                toRead = bufLen ;
            ret = read(pBuf, toRead);
            if (ret > 0)
            {
                m_iRespBodyRecv += ret;
                pHEC->processRespBodyData(pBuf, ret);
                if (ret > 1024)
                    pHEC->flushResp();
                //if ( ret1 )
                //    return ret1;
                if (m_iRespBodySize - m_iRespBodyRecv <= 0)
                    break;
                if (ret < (int)toRead)
                {
                    pHEC->flushResp();
                    return 0;
                }
            }
            else
            {
                if (ret)
                {
                    if ((errno == ECONNRESET) && (getConnector()))
                        break;
                }
                return ret;
            }
        }
    }
    incReqProcessed();
    if (pHEC->getRespState() & HEC_RESP_CONN_CLOSE)
        setState(CLOSING);

    setInProcess(0);
    pHEC->endResponse(0, 0);
    return ret;

}
コード例 #8
0
ファイル: proxyconn.cpp プロジェクト: 52M/openlitespeed
int ProxyConn::processResp()
{
    HttpExtConnector *pHEC = getConnector();
    if (!pHEC)
    {
        errno = ECONNRESET;
        return LS_FAIL;
    }
    int len = 0;
    int ret = 0;
    int &respState = pHEC->getRespState();
    if (!(respState & 0xff))
    {
        char *p = HttpResourceManager::getGlobalBuf();
        const char *pBuf = p;
        if (m_iSsl)
            len = m_ssl.read(p, 1460);
        else
            len = ExtConn::read(p, 1460);

        if (len > 0)
        {
            int copy = len;
            if (m_iRespHeaderRecv + copy > 4095)
                copy = 4095 - m_iRespHeaderRecv;
            //memmove( &m_achRespBuf[ m_iRespHeaderRecv ], pBuf, copy );
            m_iRespHeaderRecv += copy;
            m_iRespRecv += len;
            LS_DBG_L(this, "Read Response %d bytes", len);
            //debug code
            //::write( 1, pBuf, len );

            ret = pHEC->parseHeader(pBuf, len, 1);
            switch (ret)
            {
            case -2:
                LS_WARN(this, "Invalid Http response header, retry!");
                //debug code
                //::write( 1, pBuf, len );
                errno = ECONNRESET;
            case -1:
                return LS_FAIL;
            }
        }
        else
            return len;
        if (respState & 0xff)
        {
            //debug code
            //::write(1, HttpResourceManager::getGlobalBuf(),
            //        pBuf - HttpResourceManager::getGlobalBuf() );
            HttpReq *pReq = pHEC->getHttpSession()->getReq();
            if (pReq->noRespBody())
            {
                incReqProcessed();
                if (len > 0)
                    abort();
                else if (respState & HEC_RESP_CONN_CLOSE)
                    setState(CLOSING);
                else if (getState() == ABORT)
                    setState(PROCESSING);

                setInProcess(0);
                pHEC->endResponse(0, 0);
                return 0;
            }

            m_iRespBodySize = pHEC->getHttpSession()->getResp()->getContentLen();
            LS_DBG_L(this, "Response body size of proxy reply is %d",
                     m_iRespBodySize);
            if (m_iRespBodySize == LSI_RSP_BODY_SIZE_CHUNKED)
                setupChunkIS();
            else if (!(respState & HEC_RESP_CONT_LEN))
                m_iRespBodySize = INT_MAX;

            m_pBufBegin = pBuf;
            m_pBufEnd = pBuf + len;
            LS_DBG_M(this, "Process Response body %d bytes", len);
            return readRespBody();
        }
    }
    else
        return readRespBody();
    return 0;
}
コード例 #9
0
ファイル: proxyconn.cpp プロジェクト: 52M/openlitespeed
int ProxyConn::sendReqHeader()
{
    m_iovec.clear();
    HttpSession *pSession = getConnector()->getHttpSession();
    HttpReq *pReq = pSession->getReq();
    //remove the trailing "\r\n" before adding our headers
    const char *pBegin = pReq->getOrgReqLine();
    m_iTotalPending = pReq->getHttpHeaderLen();
    int newReqLineLen = 0;
    int headerLen = 17;
    char *pExtraHeader = &m_extraHeader[23];
    const char *pForward = pReq->getHeader(HttpHeader::H_X_FORWARDED_FOR);
    int len;
    if (*pForward != '\0')
    {
        len = pReq->getHeaderLen(HttpHeader::H_X_FORWARDED_FOR);
        if (len > 160)
            len = 160;
        memmove(&pExtraHeader[headerLen], pForward, len);
        headerLen += len;
        pExtraHeader[headerLen++] = ',';

    }
    //add "X-Forwarded-For" header
    memmove(&pExtraHeader[headerLen], pSession->getPeerAddrString(),
            pSession->getPeerAddrStrLen());
    headerLen += pSession->getPeerAddrStrLen();
    pExtraHeader[headerLen++] = '\r';
    pExtraHeader[headerLen++] = '\n';

#if 1       //always set "Accept-Encoding" header to "gzip"
    char *pAE = (char *)pReq->getHeader(HttpHeader::H_ACC_ENCODING);
    if (*pAE)
    {
        int len = pReq->getHeaderLen(HttpHeader::H_ACC_ENCODING);
        if (len >= 4)
        {
            memmove(pAE, "gzip", 4);
            memset(pAE + 4, ' ', len - 4);
        }
    }
    else
    {
        pExtraHeader = m_extraHeader;
        headerLen += 23;
    }
#endif

    if (*(pBegin + --m_iTotalPending - 1) == '\r')
        --m_iTotalPending;
    if (*pForward)
    {
        if ((pBegin + m_iTotalPending) -
            (pForward + pReq->getHeaderLen(HttpHeader::H_X_FORWARDED_FOR)) == 2)
        {
            const char *p = pForward -= 16;
            while (*(p - 1) != '\n')
                --p;
            m_iTotalPending = p - pBegin;
        }
    }

    //reconstruct request line if URL has been rewritten
    if (pReq->getRedirects() > 0)
    {
        const char *pReqLine = pReq->encodeReqLine(newReqLineLen);
        if (newReqLineLen > 0)
        {
            m_iovec.append(pReqLine, newReqLineLen);
            pBegin += pReq->getOrgReqLineLen() - 9;
            m_iTotalPending -= pReq->getOrgReqLineLen() - 9;
        }

    }

    int newHostLen = pReq->getNewHostLen();
    char *pHost = (char *)pReq->getHeader(HttpHeader::H_HOST);
    int hostLen = pReq->getHeaderLen(HttpHeader::H_HOST);
    if (newHostLen > 0)
    {
        if (*pHost)
        {
            m_iovec.append(pBegin, pHost - pBegin);
            m_iovec.append(pReq->getNewHost(), newHostLen);
            m_iovec.append(pHost + hostLen,
                           pBegin + m_iTotalPending - pHost - hostLen);
            m_iTotalPending += (newHostLen - hostLen);
        }
        else
        {
            m_iovec.append(pBegin, m_iTotalPending);
            m_iovec.append("Host: ", 6);
            m_iovec.append(pReq->getNewHost(), newHostLen);
            m_iovec.append("\r\n", 2);
            m_iTotalPending += newHostLen + 8;
        }
    }
    else
        m_iovec.append(pBegin, m_iTotalPending);
    m_iTotalPending += newReqLineLen;

    if (hostLen)
    {
        m_iovec.append(s_achForwardHost, sizeof(s_achForwardHost) - 1);
        m_iovec.append(pHost, hostLen);
        m_iovec.append("\r\n", 2);
        m_iTotalPending += hostLen + sizeof(s_achForwardHost) + 1 ;
    }

    if (pSession->isSSL())
    {
        m_iovec.append(s_achForwardHttps, sizeof(s_achForwardHttps) - 1);
        m_iTotalPending += sizeof(s_achForwardHttps) - 1;
    }

    //if ( headerLen > 0 )
    {
        pExtraHeader[headerLen++] = '\r';
        pExtraHeader[headerLen++] = '\n';
        m_iovec.append(pExtraHeader, headerLen);
        m_iTotalPending += headerLen;
    }
    m_iReqHeaderSize = m_iTotalPending;
    m_iReqBodySize = pReq->getContentFinished();
    setInProcess(1);
    return 1;
}