int HttpCgiTool::buildFcgiEnv(FcgiEnv *pEnv, HttpSession *pSession) { static const char *SP_ENVs[] = { "\017\010SERVER_PROTOCOLHTTP/1.1", "\017\010SERVER_PROTOCOLHTTP/1.0", "\017\010SERVER_PROTOCOLHTTP/0.9" }; static const char *RM_ENVs[10] = { "\016\007REQUEST_METHODUNKNOWN", "\016\007REQUEST_METHODOPTIONS", "\016\003REQUEST_METHODGET", "\016\004REQUEST_METHODHEAD", "\016\004REQUEST_METHODPOST", "\016\003REQUEST_METHODPUT", "\016\006REQUEST_METHODDELETE", "\016\005REQUEST_METHODTRACE", "\016\007REQUEST_METHODCONNECT", "\016\004REQUEST_METHODMOVE" }; static int RM_ENV_LEN[10] = { 23, 23, 19, 20, 20, 19, 22, 21, 23, 20 }; HttpReq *pReq = pSession->getReq(); int n; pEnv->add(GISS_ENV, GISS_ENV_LEN); n = pReq->getVersion(); pEnv->add(SP_ENVs[n], 25); n = pReq->getMethod(); if (n < 10) pEnv->add(RM_ENVs[n], RM_ENV_LEN[n]); else pEnv->add("REQUEST_METHOD", 016, HttpMethod::get(n), HttpMethod::getLen(n)); addSpecialEnv(pEnv, pReq); buildCommonEnv(pEnv, pSession); addHttpHeaderEnv(pEnv, pReq); return 0; }
int HttpCgiTool::buildEnv( IEnv* pEnv, HttpConnection* pConn ) { HttpReq * pReq = pConn->getReq(); int n; pEnv->add( "GATEWAY_INTERFACE",17, "CGI/1.1", 7 ); if ( getenv( "PATH" ) == NULL ) { pEnv->add( "PATH", 4, DEFAULT_PATH, DEFAULT_PATHLEN ); } n = pReq->getVersion(); pEnv->add( "SERVER_PROTOCOL", 15, HttpVer::getVersionString( n ), HttpVer::getVersionStringLen( n )); const char * pServerStr; pServerStr = HttpServerVersion::getVersion(); n = HttpServerVersion::getVersionLen(); pEnv->add( "SERVER_SOFTWARE", 15, pServerStr, n); n = pReq->getMethod(); pEnv->add( "REQUEST_METHOD", 14, HttpMethod::get( n ), HttpMethod::getLen( n )); // //FIXME: do nslookup // // tmp = dnslookup(r->cn->peer.sin_addr, r->c->dns); // if (tmp) { // ADD_ENV(pEnv, "REMOTE_HOST", tmp); // free(tmp); // } // // //ADD_ENV(pEnv, "REMOTE_HOST", achTemp ); addSpecialEnv( pEnv, pReq ); buildCommonEnv( pEnv, pConn ); addHttpHeaderEnv( pEnv, pReq ); pEnv->add( 0, 0, 0, 0); return 0; }
int RequestVars::getReqVar( HttpSession *pSession, int type, char * &pValue, int bufLen) { HttpReq * pReq = pSession->getReq(); int i; char *p; if ( type < REF_STRING ) { pValue = (char *)pReq->getHeader( type ); if ( *pValue ) return pReq->getHeaderLen( type ); else return 0; } switch( type ) { case REF_REMOTE_HOST: //FIXME: use remote addr for now case REF_REMOTE_ADDR: pValue = (char *)pSession->getPeerAddrString(); return pSession->getPeerAddrStrLen(); case REF_REMOTE_PORT: return snprintf( pValue, bufLen, "%hu", pSession->getRemotePort() ); case REF_REMOTE_USER: pValue = (char *)pReq->getAuthUser(); return strlen( pValue ); case REF_REMOTE_IDENT: //do not support; return 0; case REF_REQ_METHOD: i = pReq->getMethod(); strcpy(pValue, HttpMethod::get( i ) ); return HttpMethod::getLen( i ); case REF_QUERY_STRING: pValue = (char *)pReq->getQueryString(); return pReq->getQueryStringLen(); case REF_AUTH_TYPE: //FIXME: hard code for now strncpy( pValue, "Basic", 6 ); return 5; case REF_REQUST_FN: case REF_SCRIPTFILENAME: case REF_SCRIPT_BASENAME: case REF_REQ_BASENAME: { const AutoStr2 * psTemp = pReq->getRealPath(); if ( psTemp ) { if (( type == REF_SCRIPT_BASENAME )|| ( type == REF_REQ_BASENAME )) { const char * pEnd = psTemp->c_str() + psTemp->len(); pValue = (char *)pEnd; while( pValue[-1] != '/' ) --pValue; return pEnd - pValue; } pValue = (char *)psTemp->c_str(); return psTemp->len(); } else return 0; } case REF_SCRIPT_UID: case REF_SCRIPT_GID: case REF_SCRIPT_USERNAME: case REF_SCRIPT_GRPNAME: case REF_SCRIPT_MODE: { const AutoStr2 * psTemp = pReq->getRealPath(); if ( psTemp ) { struct stat& st = pReq->getFileStat(); if ( type == REF_SCRIPT_UID ) { return snprintf( pValue, bufLen, "%d", st.st_uid ); } else if ( type == REF_SCRIPT_GID ) { return snprintf( pValue, bufLen, "%d", st.st_gid ); } else if ( type == REF_SCRIPT_MODE ) { return snprintf( pValue, bufLen, "%o", st.st_mode ); } else if ( type == REF_SCRIPT_USERNAME ) { struct passwd * pw = getpwuid( st.st_uid ); if ( pw ) return snprintf( pValue, bufLen, "%s", pw->pw_name ); } else { struct group * gr = getgrgid( st.st_gid ); if ( gr ) return snprintf( pValue, bufLen, "%s", gr->gr_name ); } } return 0; } case REF_PATH_INFO: pValue = (char *)pReq->getPathInfo(); return pReq->getPathInfoLen(); case REF_SCRIPT_NAME: pValue = (char *)pReq->getURI(); return pReq->getScriptNameLen(); case REF_SCRIPT_URI: p = pValue; if ( pSession->isSSL() ) { strcpy( p, "https://" ); p += 8; } else { strcpy( p, "http://" ); p += 7; } i = pReq->getHeaderLen( HttpHeader::H_HOST ); memmove( p, pReq->getHeader( HttpHeader::H_HOST ), i ); p += i; i = pReq->getOrgURILen(); memmove( p, pReq->getOrgURI(), i ); p += i; return p - pValue; case REF_ORG_REQ_URI: pValue = (char *)pReq->getOrgReqURL(); return pReq->getOrgReqURILen(); case REF_DOCUMENT_URI: return pReq->getDecodedOrgReqURI( pValue ); case REF_REQ_URI: pValue = (char *)pReq->getOrgReqURL(); return pReq->getOrgReqURLLen(); case REF_DOC_ROOT: pValue = (char *)pReq->getDocRoot()->c_str(); return pReq->getDocRoot()->len()-1; case REF_SERVER_ADMIN: if ( pReq->getVHost() ) { const AutoStr2 * pEmail = pReq->getVHost()->getAdminEmails(); pValue = (char *)pEmail->c_str(); return pEmail->len(); } return 0; case REF_VH_CNAME: if ( pReq->getVHost() ) { pValue = (char *)pReq->getVHost()->getVhName( i ); return i; } return 0; case REF_SERVER_NAME: pValue = (char *)pReq->getHostStr(); return pReq->getHostStrLen(); case REF_SERVER_ADDR: pValue = (char *)pReq->getLocalAddrStr()->c_str(); return pReq->getLocalAddrStr()->len(); case REF_SERVER_PORT: pValue = (char *)pReq->getPortStr().c_str(); return pReq->getPortStr().len(); case REF_SERVER_PROTO: i = pReq->getVersion(); pValue = (char *)HttpVer::getVersionString( i ); return HttpVer::getVersionStringLen( i ); case REF_SERVER_SOFT: pValue = (char *)HttpServerVersion::getVersion(); return HttpServerVersion::getVersionLen(); case REF_REQ_LINE: pValue = (char *)pReq->getOrgReqLine(); return pReq->getOrgReqLineLen(); case REF_IS_SUBREQ: strcpy( pValue, "false" ); return 5; case REF_RESP_BYTES: i = StringTool::str_off_t( pValue, bufLen, pSession->getResp()->getBodySent() ); return i; //case REF_COOKIE_VAL //case REF_STRFTIME 155 //case REF_CONN_STATE: case REF_REQ_TIME_MS: { struct timeval tv; gettimeofday( &tv, NULL ); DateTime::s_curTime = tv.tv_sec; DateTime::s_curTimeUs = tv.tv_usec; long lReqTime = (DateTime::s_curTime - pSession->getReqTime())*1000000 + (DateTime::s_curTimeUs - pSession->getReqTimeUs()); i = snprintf( pValue, bufLen, "%ld", lReqTime ); return i; } case REF_REQ_TIME_SEC: i = snprintf( pValue, bufLen, "%ld", (DateTime::s_curTime - pSession->getReqTime()) ); return i; case REF_DUMMY: return 0; case REF_PID: i = snprintf( pValue, bufLen, "%d", getpid() ); return i; case REF_STATUS_CODE: memmove( pValue, HttpStatusCode::getCodeString( pReq->getStatusCode() )+1, 3 ); pValue[3] = 0; return 3; case REF_CUR_URI: pValue = (char *)pReq->getURI(); i = pReq->getURILen(); return i; case REF_BYTES_IN: i = StringTool::str_off_t( pValue, bufLen, pSession->getBytesRecv() ); return i; case REF_BYTES_OUT: i = StringTool::str_off_t( pValue, bufLen, pSession->getBytesSent() ); return i; case REF_HTTPS: i = snprintf( pValue, bufLen, "%s", pSession->isSSL()?"on":"off" ); return i; case REF_DATE_GMT: case REF_DATE_LOCAL: case REF_LAST_MODIFIED: { time_t mtime = DateTime::s_curTime; struct tm * tm; if ( type == REF_LAST_MODIFIED ) { if ( pReq->getSSIRuntime() && pReq->getSSIRuntime()->getCurrentScript() ) { mtime = pReq->getSSIRuntime()->getCurrentScript()->getLastMod(); } else mtime = pReq->getFileStat().st_mtime; } if ( type == REF_DATE_GMT ) tm = gmtime( &mtime ); else tm = localtime( &mtime ); char fmt[101]; memccpy( fmt, pValue, 0, 100 ); fmt[100] = 0; i = strftime( pValue, bufLen, fmt, tm ); return i; } case REF_DOCUMENT_NAME: { const AutoStr2 * psTemp = pReq->getRealPath(); if ( psTemp ) { pValue = (char *)psTemp->c_str() + psTemp->len(); while( *(pValue -1) != '/' ) --pValue; return psTemp->c_str() + psTemp->len() - pValue; } else return 0; } case REF_QS_UNESCAPED: { int qsLen = pReq->getQueryStringLen(); const char * pQS = pReq->getQueryString(); if ( qsLen > 0 ) { qsLen = HttpUtil::unescape_n( pQS, qsLen, pValue, bufLen ); } return qsLen; } case REF_RESP_CONTENT_TYPE: i = 0; pValue = (char*)pSession->getResp()->getContentTypeHeader( i ); return i; case REF_RESP_CONTENT_LENGTH: { off_t l = pSession->getResp()->getContentLen(); if ( l <= 0 ) l = 0; i = StringTool::str_off_t( pValue, bufLen, l ); return i; } case REF_RESP_BODY: return 0; default: if ( type >= REF_TIME ) { time_t t = time(NULL); struct tm *tm = localtime(&t); switch( type ) { case REF_TIME: i = snprintf( pValue, bufLen, "%04d%02d%02d%02d%02d%02d", tm->tm_year + 1900, tm->tm_mon+1, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec); break; case REF_TIME_YEAR: i = snprintf( pValue, bufLen, "%04d", tm->tm_year + 1900); break; case REF_TIME_MON: i = snprintf( pValue, bufLen, "%02d", tm->tm_mon+1 ); break; case REF_TIME_DAY: i = snprintf( pValue, bufLen, "%02d", tm->tm_mday); break; case REF_TIME_HOUR: i = snprintf( pValue, bufLen, "%02d", tm->tm_hour); break; case REF_TIME_MIN: i = snprintf( pValue, bufLen, "%02d", tm->tm_min); break; case REF_TIME_SEC: i = snprintf( pValue, bufLen, "%02d", tm->tm_sec); break; case REF_TIME_WDAY: i = snprintf( pValue, bufLen, "%d", tm->tm_wday); break; default: return 0; } return i; } return 0; } return 0; }