#include "shrink.h" /************************************************************************ ** Function name: deal_cgi ** Descriptions: 处理cgi请求 ** output parameters: pr:服务请求指针 *************************************************************************/ #ifdef _WIN32 void deal_cgi(struct request * pr) { char env[CGI_ENV_MAX]; int len = 0; STARTUPINFO si; PROCESS_INFORMATION pi; FILE *fp; char buf[IO_MAX]; char cmdline[PATH_MAX]; char line[PATH_MAX]; DWORD dwRead=0; char chBuf[4096]; int buflen=0; HANDLE hReadPipe1,hWritePipe1; //创建管道 SECURITY_ATTRIBUTES sa; sa.nLength=12; sa.lpSecurityDescriptor=0; sa.bInheritHandle=TRUE; CreatePipe(&hReadPipe1,&hWritePipe1,&sa,0); (void) memset(&si, 0, sizeof(si)); (void) memset(&pi, 0, sizeof(pi)); si.cb = sizeof(si); si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW; si.wShowWindow = SW_HIDE; //si.hStdInput = hReadPipe2; si.hStdOutput = si.hStdError = hWritePipe1; //获得环境变量 setcgienv(pr, env); //cgi script if ((fp = fopen(pr->path, "r")) != NULL) { //first line (void) fscanf(fp,"%s\n",line); //perl if (memcmp(line, "#!", 2) == 0) {} //lua else if (memcmp(line, "--", 2) == 0) {} else { line[2] = '\0'; } (void) fclose(fp); } (void) _snprintf(cmdline, sizeof(cmdline), "%s%s%s",line + 2, line[2] == '\0' ? "" : " ", pr->path); //创建进程 if (CreateProcess(NULL,cmdline , NULL, NULL, TRUE, 0, env, NULL, &si, &pi) == 0) { #ifdef _DEBUG printf("process error\n"); #endif CloseHandle(pi.hProcess); CloseHandle(hReadPipe1); CloseHandle(hWritePipe1); errstatus(pr,500,"CGI Error","","CGI Error"); return; } else { #ifdef _DEBUG printf("process ok\n"); #endif CloseHandle(pi.hThread); } //等待cgi处理完,超时时间为2秒 if (WaitForSingleObject(pi.hProcess, 2000) == WAIT_TIMEOUT) { // break; errstatus(pr,500,"CGI Error","","CGI Error"); TerminateProcess(pi.hProcess, 0); } else { CloseHandle(hWritePipe1); while(ReadFile(hReadPipe1, chBuf, 2048, &dwRead, NULL) && dwRead != 0) { _snprintf(buf+buflen,dwRead,chBuf); buflen += dwRead; } if (buflen != 0) { buf[buflen++] = '\0'; pr->io_local.readlen = _snprintf(pr->io_local.buf,IO_MAX,"HTTP/1.1 200 OK\r\n"); len = IO_SPACELEN(&pr->io_local); pr->io_local.readlen += _snprintf(pr->io_local.buf+pr->io_local.readlen,len,buf); pr->io_local.done ++; } else { errstatus(pr,500,"CGI Error","","CGI Error"); } } //关闭handle CloseHandle(hReadPipe1); CloseHandle(hWritePipe1); } #elif _UCOS void setluaenv(struct request * pr, char * env) { int n = 0; char * p; #define ADDENV(x) \ n += 1 + _snprintf(env + n, CGI_ENV_MAX-n-1, x) #define ADDENV1(x, y) if (y) \ n += 1 + _snprintf(env + n, CGI_ENV_MAX-n-1, x, y) ADDENV1("REQUEST_METHOD=\"%s\"","HTTP/1.1"); ADDENV1("GATEWAY_INTERFACE=\"%s\"","CGI/1.1"); if(pr->query) { p = *(pr->query) ? pr->query : ""; ADDENV1("QUERY_STRING=\"%s\"", p); } if (pr->plength > 0) { ADDENV1("CONTENT_LENGTH=\"%u\"", pr->plength); p = pr->message ? pr->message : ""; ADDENV1("CONTENT_STRING=\"%s\"", p); } env[n] = '\0'; } void deal_cgi(struct request * pr) { int i; int n = 0; uint8 err; struct cgiinfo * pcf; int len; #ifdef _FLASHFS for(i=0;ipath+1,fms[i].filename,len)) /*在flash中找到对应cgi(lua) */ { memset(li.cgifile,0,IO_LOCAL); /*清空li.cgifile*/ memcpy(li.cgifile,(const void *)fms[i].addr,fms[i].len); /*拷贝flash内容到li.cgifile */ memset(li.env,0,CGI_ENV_MAX); setluaenv(pr, li.env); /*设置环境变量*/ sem_post(li.luasem); /*启动lua解析*/ sem_wait(li.wssem,2000,&err); /*等待解析结束*/ if(err == OS_TIMEOUT) { errstatus(pr,500,"CGI Error","","CGI Error"); } else { pr->io_local.readlen = _snprintf(pr->io_local.buf,IO_LOCAL,"HTTP/1.1 200 OK\r\n"); len = IO_SPACELEN(&pr->io_local); pr->io_local.readlen += _snprintf(pr->io_local.buf+pr->io_local.readlen,len,li.iobuf); pr->io_local.done ++; } return; } } #endif i = cginame2no(pr->path+1); /*获取静态cgi编号 */ /*加1是因为uri中第一个字符是'/' */ if(i!=-1) { pcf = &cgiinfos[i]; memset(pcf->env,0,CGI_ENV_MAX); setcgienv(pr, pcf->env); sem_post(pcf->cgisem); sem_wait(pcf->wssem,2000,&err); if(err == OS_TIMEOUT) { errstatus(pr,500,"CGI Error","","CGI Error"); } else { pr->io_local.readlen = _snprintf(pr->io_local.buf,IO_LOCAL,"HTTP/1.1 200 OK\r\n"); len = IO_SPACELEN(&pr->io_local); pr->io_local.readlen += _snprintf(pr->io_local.buf+pr->io_local.readlen,len,pcf->iobuf); pr->io_local.done ++; } } else { errstatus(pr, 404, "Bad Request","", "Bad Request"); } } static char * cgigetenv(char* env, const char* varname) { int len = strlen(varname); while(*env != NULL) { if(ncasecmp(env,varname,len) == 0) { return env+len+1; } env = strchr(env,'\0'); env ++; } return env; } #endif /************************************************************************ ** Function name: setcgienv ** Descriptions: 设置cgi环境变量 ** output parameters: pr:服务请求指针 ** env:保存环境变量的字符串 *************************************************************************/ void setcgienv(struct request * pr, char * env) { int n = 0; char * p; #define ADDENV(x) \ n += 1 + _snprintf(env + n, CGI_ENV_MAX-n-1, x) #define ADDENV1(x, y) if (y) \ n += 1 + _snprintf(env + n, CGI_ENV_MAX-n-1, x, y) ADDENV("SERVER_PROTOCOL=HTTP/1.1"); ADDENV("GATEWAY_INTERFACE=CGI/1.1"); ADDENV1("REQUEST_METHOD=%s", pr->method); if(pr->query) { p = *(pr->query) ? pr->query : ""; ADDENV1("QUERY_STRING=%s", p); } if (pr->plength > 0) { ADDENV1("CONTENT_LENGTH=%ui", pr->plength); p = pr->message ? pr->message : ""; ADDENV1("CONTENT_STRING=%s", p); } env[n] = '\0'; } #ifdef _UCOS int cginame2no(const char* name) { int i; int len; for(i=0;i