int HttpCgiTool::processHeaderLine( HttpExtConnector * pExtConn, const char * pLineBegin, const char * pLineEnd, int &status ) { int index; const char * pKeyEnd; const char * pValue = pLineBegin; char * p; HttpResp* pResp = pExtConn->getHttpConn()->getResp(); HttpReq * pReq = pExtConn->getHttpConn()->getReq(); index = HttpHeader::getRespHeaderIndex( pValue ); if ( index < HttpHeader::H_HEADER_END ) { pValue += HttpHeader::getHeaderStringLen( index ); while( isspace(*pValue) ) ++pValue; pKeyEnd = pValue; if ( *pValue != ':' ) { index = HttpHeader::H_HEADER_END; } else { do { ++pValue; } while( isspace(*pValue) ); } } if ( index == HttpHeader::H_HEADER_END ) { pKeyEnd = (char *)memchr( pValue, ':', pLineEnd - pValue ); if ( pKeyEnd != NULL ) { pValue = pKeyEnd + 1; while( isspace(*pValue) ) ++pValue; } else { if ( !isspace( *pLineBegin ) ) return 0; } } switch( index ) { case HttpHeader::H_CONTENT_TYPE: p = (char *)memchr( pValue, ';', pLineEnd - pValue ); if ( pReq->gzipAcceptable() ) { register char ch = 0; register char *p1; if ( p ) { p1 = (char*)p; } else p1 = (char*)pLineEnd; ch = *p1; *p1 = 0; if ( !HttpGlobals::getMime()->compressable( pValue ) ) pReq->setGzip( 0 ); *p1 = ch; } if ( pReq->isKeepAlive() ) pReq->smartKeepAlive( pValue ); { if ( !HttpMime::needCharset( pValue ) ) break; const AutoStr2 * pCharset = pReq->getDefaultCharset(); if ( !pCharset ) break; if ( p ) { while( isspace( *(++p) ) ) ; if ( strncmp( p, "charset=", 8 ) == 0 ) break; } AutoBuf& buf = pResp->getOutputBuf(); if ( buf.available() < pLineEnd - pLineBegin + pCharset->len() + 4 ) { buf.grow( pLineEnd - pLineBegin + pCharset->len() + 4 ); } buf.appendNoCheck( pLineBegin, pLineEnd - pLineBegin ); buf.appendNoCheck( pCharset->c_str(), pCharset->len() ); buf.appendNoCheck( "\r\n", 2 ); } return 0; case HttpHeader::H_CONTENT_ENCODING: pReq->setGzip( 0 ); break; case HttpHeader::H_LOCATION: if ( pReq->getStatusCode() != SC_200 ) break; if ( *pValue != '/' ) { //set status code to 307 pReq->setStatusCode( SC_302 ); } else { pReq->setLocation( pValue, pLineEnd - pValue ); return 0; } break; case HttpHeader::CGI_STATUS: index = HttpStatusCode::codeToIndex( pValue ); if ( index != -1 ) { pReq->updateNoRespBodyByStatus( index ); if (( index >= SC_300 )&&( index < SC_400 )) { if ( *pReq->getLocation() ) { pResp->appendHeader( "Location: ", 10, pReq->getLocation(), pReq->getLocationLen() ); pReq->clearLocation(); } } if (( status & HEC_RESP_AUTHORIZER )&&( index == SC_200)) status |= HEC_RESP_AUTHORIZED; } return 0; case HttpHeader::H_TRANSFER_ENCODING: pResp->setContentLen( -1 ); return 0; case HttpHeader::H_PROXY_CONNECTION: case HttpHeader::H_CONNECTION: if ( strncasecmp( pValue, "close", 5 ) == 0 ) status |= HEC_RESP_CONN_CLOSE; return 0; case HttpHeader::H_CONTENT_LENGTH: if ( pResp->getContentLen() >= 0 ) { long lContentLen = strtol( pValue, NULL, 10 ); if (( lContentLen >= 0 )&&( lContentLen != LONG_MAX )) pResp->setContentLen( lContentLen ); } //fall through case HttpHeader::H_KEEP_ALIVE: case HttpHeader::H_SERVER: case HttpHeader::H_DATE: return 0; default: //"script-control: no-abort" is not supported break; } if ( status & HEC_RESP_AUTHORIZED ) { if (strncasecmp( pLineBegin, "Variable-", 9 ) == 0 ) { if ( pKeyEnd > pLineBegin + 9 ) pReq->addEnv( pLineBegin + 9, pKeyEnd - pLineBegin - 9, pValue, pLineEnd - pValue ); } return 0; } return pResp->appendHeaderLine( pLineBegin, pLineEnd ); }
int HttpCgiTool::processHeaderLine(HttpExtConnector *pExtConn, const char *pLineBegin, const char *pLineEnd, int &status) { HttpRespHeaders::HEADERINDEX index; int tmpIndex; const char *pKeyEnd = NULL; const char *pValue = pLineBegin; char *p; HttpResp *pResp = pExtConn->getHttpSession()->getResp(); HttpReq *pReq = pExtConn->getHttpSession()->getReq(); index = HttpRespHeaders::getRespHeaderIndex(pValue); if (index < HttpRespHeaders::H_HEADER_END) { pValue += HttpRespHeaders::getHeaderStringLen(index); while (isspace(*pValue)) ++pValue; pKeyEnd = pValue; if (*pValue != ':') index = HttpRespHeaders::H_HEADER_END; else { do { ++pValue; } while (isspace(*pValue)); } } if (index == HttpRespHeaders::H_HEADER_END) { pKeyEnd = (char *)memchr(pValue, ':', pLineEnd - pValue); if (pKeyEnd != NULL) { pValue = pKeyEnd + 1; while (isspace(*pValue)) ++pValue; } else { if (!isspace(*pLineBegin)) return 0; } } switch (index) { case HttpRespHeaders::H_CONTENT_TYPE: if (pReq->getStatusCode() == SC_304) return 0; p = (char *)memchr(pValue, ';', pLineEnd - pValue); if (pReq->gzipAcceptable() == GZIP_REQUIRED) { char ch = 0; char *p1; if (p) p1 = (char *)p; else p1 = (char *)pLineEnd; ch = *p1; *p1 = 0; if (!HttpMime::getMime()->compressible(pValue)) pReq->andGzip(~GZIP_ENABLED); *p1 = ch; } if (pReq->isKeepAlive()) pReq->smartKeepAlive(pValue); { if (!HttpMime::needCharset(pValue)) break; const AutoStr2 *pCharset = pReq->getDefaultCharset(); if (!pCharset) break; if (p) { while (isspace(*(++p))) ; if (strncmp(p, "charset=", 8) == 0) break; } HttpRespHeaders &buf = pResp->getRespHeaders(); AutoStr2 str = ""; str.append(pLineBegin, pLineEnd - pLineBegin); str.append(pCharset->c_str(), pCharset->len()); str.append("\r\n", 2); buf.parseAdd(str.c_str(), str.len(), LSI_HEADEROP_ADD); } return 0; case HttpRespHeaders::H_CONTENT_ENCODING: if (pReq->getStatusCode() == SC_304) return 0; if (strncasecmp(pValue, "gzip", 4) == 0) pReq->orGzip(UPSTREAM_GZIP); else if (strncasecmp(pValue, "deflate", 7) == 0) pReq->orGzip(UPSTREAM_DEFLATE); // if ( !(pReq->gzipAcceptable() & REQ_GZIP_ACCEPT) ) // return 0; // } // else //if ( strncasecmp( pValue, "deflate", 7 ) == 0 ) // { // pReq->andGzip( ~GZIP_ENABLED ); // } break; case HttpRespHeaders::H_LOCATION: if ((status & HEC_RESP_PROXY) || (pReq->getStatusCode() != SC_200)) break; case HttpRespHeaders::H_LITESPEED_LOCATION: if (*pValue != '/') { //set status code to 307 pReq->setStatusCode(SC_302); } else { if ((pReq->getStatusCode() == SC_404) || (index == HttpRespHeaders::H_LITESPEED_LOCATION)) pReq->setStatusCode(SC_200); if (index == HttpRespHeaders::H_LITESPEED_LOCATION) { char ch = *pLineEnd; *((char *)pLineEnd) = 0; pReq->locationToUrl(pValue, pLineEnd - pValue); *((char *)pLineEnd) = ch; } else pReq->setLocation(pValue, pLineEnd - pValue); pExtConn->getHttpSession()->changeHandler(); //status |= HEC_RESP_LOC_SET; return 0; } break; case HttpRespHeaders::H_CGI_STATUS: tmpIndex = HttpStatusCode::getInstance().codeToIndex(pValue); if (tmpIndex != -1) { pReq->updateNoRespBodyByStatus(tmpIndex); if ((tmpIndex >= SC_300) && (tmpIndex < SC_400)) { if (pReq->getLocation() != NULL) { pResp->appendHeader("location: ", 10, pReq->getLocation(), pReq->getLocationLen()); pReq->clearLocation(); } } if ((status & HEC_RESP_AUTHORIZER) && (tmpIndex == SC_200)) status |= HEC_RESP_AUTHORIZED; } return 0; case HttpRespHeaders::H_TRANSFER_ENCODING: pResp->setContentLen(LSI_RSP_BODY_SIZE_CHUNKED); return 0; case HttpRespHeaders::H_SET_COOKIE: //pReq->getRespCacheCtrl().setHasCookie(); pReq->processSetCookieHeader(pValue, pLineEnd - pValue); break; case HttpRespHeaders::H_PROXY_CONNECTION: case HttpRespHeaders::H_CONNECTION: if (strncasecmp(pValue, "close", 5) == 0) status |= HEC_RESP_CONN_CLOSE; return 0; case HttpRespHeaders::H_CONTENT_LENGTH: if (pResp->getContentLen() == LSI_RSP_BODY_SIZE_UNKNOWN) { off_t lContentLen = strtoll(pValue, NULL, 10); if ((lContentLen >= 0) && (lContentLen != LLONG_MAX)) { pResp->setContentLen(lContentLen); status |= HEC_RESP_CONT_LEN; pReq->orContextState(RESP_CONT_LEN_SET); } } //fall through case HttpRespHeaders::H_KEEP_ALIVE: case HttpRespHeaders::H_SERVER: case HttpRespHeaders::H_DATE: return 0; default: //"script-control: no-abort" is not supported break; } if (status & HEC_RESP_AUTHORIZED) { if (strncasecmp(pLineBegin, "Variable-", 9) == 0) { if (pKeyEnd > pLineBegin + 9) RequestVars::setEnv(pExtConn->getHttpSession(), pLineBegin + 9, pKeyEnd - pLineBegin - 9, pValue, pLineEnd - pValue); } return 0; } assert(pKeyEnd); return pResp->appendHeader(pLineBegin, pKeyEnd - pLineBegin, pValue, pLineEnd - pValue); }