📄 miniweb.c
字号:
///////////////////////////////////////////////////////////////////////////////// miniweb.c//// MiniWeb start-up code///////////////////////////////////////////////////////////////////////////////#include <stdio.h>#include <string.h>#include "httppil.h"#include "httpapi.h"#include "revision.h"int uhMpd(UrlHandlerParam* param);int uhStats(UrlHandlerParam* param);int uhWebCounter(UrlHandlerParam* param);int uhVod(UrlHandlerParam* param);int uhVodStream(UrlHandlerParam* param);int uhVodInit(void* arg);UrlHandler urlHandlerList[]={ {"~stats",uhStats,NULL},#ifdef MPD {"mplayer/",uhMpd,NULL},#endif#ifdef VOD {"vod/",uhVod,(PFNURLINIT)uhVodInit}, {"vodstream",uhVodStream,NULL},#endif {NULL}, {NULL},};HttpParam *httpParam;int nInst=0;const char *pageHead="<html><body class='body'><table border=1 cellpadding=0 cellspacing=0 width=280 class='body'>";const char *pageCellBegin="<tr><td width=140>%s</td><td width=140>";const char *pageCellEnd="</td></tr>";const char *pageTail="</body></html>";extern FILE *fpLog;//////////////////////////////////////////////////////////////////////////// callback from the web server whenever a valid request comes in//////////////////////////////////////////////////////////////////////////int uhStats(UrlHandlerParam* param){ unsigned char *p; char buf[30]; HttpStats *stats=&((HttpParam*)param->hp)->stats; HttpRequest *req=param->request; int ret=FLAG_DATA_RAW; mwGetHttpDateTime(time(NULL),buf); if (stats->clientCount>4) { param->pucBuffer=(char*)malloc(stats->clientCount*256+1024); ret=FLAG_DATA_RAW | FLAG_TO_FREE; } p=param->pucBuffer; //generate page p+=sprintf(p,pageHead); p+=sprintf(p,pageCellBegin,"Your IP address:"); p+=sprintf(p,"%d.%d.%d.%d%s", req->ipAddr.caddr[3], req->ipAddr.caddr[2], req->ipAddr.caddr[1], req->ipAddr.caddr[0], pageCellEnd); p+=sprintf(p,pageCellBegin,"Current time:"); p+=sprintf(p,"%s%s",buf,pageCellEnd); p+=sprintf(p,pageCellBegin,"Server uptime:",time(NULL)-stats->startTime); p+=sprintf(p,"%d sec(s)%s",time(NULL)-stats->startTime,pageCellEnd); p+=sprintf(p,pageCellBegin,"Connected clients:"); p+=sprintf(p,"%d%s",stats->clientCount,pageCellEnd); p+=sprintf(p,pageCellBegin,"Maximum clients:"); p+=sprintf(p,"%d%s",stats->clientCountMax,pageCellEnd); p+=sprintf(p,pageCellBegin,"Requests:"); p+=sprintf(p,"%d%s",stats->reqCount,pageCellEnd); p+=sprintf(p,pageCellBegin,"Files sent:"); p+=sprintf(p,"%d%s",stats->fileSentCount,pageCellEnd); p+=sprintf(p,pageCellBegin,"Bytes sent:"); p+=sprintf(p,"%d bytes%s</table>",stats->fileSentBytes,pageCellEnd); p+=sprintf(p,"<br>Connected peers:<hr>"); { HttpSocket *phsSocketCur; time_t curtime=time(NULL); for (phsSocketCur=((HttpParam*)param->hp)->phsSocketHead; phsSocketCur; phsSocketCur=phsSocketCur->next) { IP ip=phsSocketCur->request.ipAddr; p+=sprintf(p,"<br>Socket %d: %d.%d.%d.%d / Reqs: %d / Expire in %d ", phsSocketCur->socket,ip.caddr[3],ip.caddr[2],ip.caddr[1],ip.caddr[0],phsSocketCur->siRequestCount,phsSocketCur->tmExpirationTime-curtime); if (phsSocketCur->request.pucPath) p+=sprintf(p,"(%d/%d)",phsSocketCur->response.iSentBytes,phsSocketCur->response.iContentLength); else p+=sprintf(p,"(idle)"); } } p+=sprintf(p,pageTail); //return data to server param->iDataBytes=(int)(p-(param->pucBuffer)); param->fileType=HTTPFILETYPE_HTML; return ret;}#define TOTAL_COUNTERS 8static unsigned long counter[TOTAL_COUNTERS];char *pchCounterFile=NULL;void saveWebCounter(){ int fd; if (!pchCounterFile) return; printf("Saving counter data...\n"); fd=open(pchCounterFile,O_WRONLY|O_CREAT); if (fd<=0) return; write(fd,counter,sizeof(counter)); close(fd);}int loadWebCounter(){ int fd; memset(&counter,0,sizeof(counter)); if (!pchCounterFile) return -1; fd=open(pchCounterFile,O_RDONLY); if (fd<=0) { return -1; } read(fd,counter,sizeof(counter)); close(fd); return 0;}int itoc(int num, char *pbuf, int type){ static const char *chNum[]={"零","一","二","三","四","五","六","七","八","九"}; static const char *chUnit[]={"亿","万","千","百","十","",NULL}; char *p=pbuf; int c=1000000000,unit=4,d,last=0; if (num==0) return sprintf(pbuf,chNum[0]); if (num<0) { p+=sprintf(pbuf,"负"); num=-num; } d=num; for (;;) { do { int tmp=d/c; if (tmp>0) { p+=sprintf(p,"%s%s",(unit==2 && tmp==1)?"":chNum[tmp],chUnit[unit]); d%=c; } else if (last!=0 && c>=10 && d>0) { p+=sprintf(p,chNum[0]); } last=tmp; c/=10; } while(chUnit[++unit]); if (c==0) break; if (c==1000 && num>=10000) p+=sprintf(p,chUnit[1]); else if (c==10000000 && num>=100000000) p+=sprintf(p,chUnit[0]); unit=2; } return (int)(p-pbuf);}int uhWebCounter(UrlHandlerParam* param){ static int visitCount=0; int idx,mode=0; char *p; p=strchr(param->pucRequest,'&'); if (p) { *(p++)=0; if (GETDWORD(p)==DEFDWORD('m','o','d','e')) { mode=atoi(p+5); } } p=strchr(param->pucRequest,'='); if (p) *p=0; idx=atoi(param->pucRequest); if (idx>=TOTAL_COUNTERS) return 0; counter[idx]++; if (p) counter[idx]=atoi(p+1); p=param->pucBuffer; if ((mode & 4)==0) { p+=sprintf(p,"document.write('"); } switch (mode & 3) { case 0: p+=sprintf(p,"%d",counter[idx]); break; case 1: p+=itoc(counter[idx],p,0); break; case 2: p+=itoc(counter[idx],p,1); break; } if ((mode & 4)==0) { p+=sprintf(p,"');"); } param->iDataBytes=(int)p-(int)param->pucBuffer; param->fileType=HTTPFILETYPE_TEXT; if (((++visitCount) & 0xf)==0) { saveWebCounter(); } return FLAG_DATA_RAW;}//////////////////////////////////////////////////////////////////////////// callback from the web server whenever it needs to substitute variables//////////////////////////////////////////////////////////////////////////int DefaultWebSubstCallback(SubstParam* sp){ // the maximum length of variable value should never exceed the number // given by sp->iMaxValueBytes if (!strcmp(sp->pchParamName,"mykeyword")) { return sprintf(sp->pchParamValue, "%d", time(NULL)); } return -1;}//////////////////////////////////////////////////////////////////////////// callback from the web server whenever it recevies posted data//////////////////////////////////////////////////////////////////////////int DefaultWebPostCallback(PostParam* pp){ int iReturn=WEBPOST_OK; // by default redirect to config page strcpy(pp->chFilename,"index.htm"); return iReturn;}//////////////////////////////////////////////////////////////////////////// callback from the web server whenever it receives a multipart // upload file chunk//////////////////////////////////////////////////////////////////////////int DefaultWebFileUploadCallback(char *pchFilename, OCTET oFileuploadStatus, OCTET *poData, DWORD dwDataChunkSize){ // Do nothing with the data printf("Received %lu bytes for multipart upload file %s\n", dwDataChunkSize, pchFilename); return 0;}int MiniWebQuit(int arg) { int i; if (arg) printf("\nCaught signal (%d). MiniWeb shutting down...\n",arg); for (i=0;i<nInst;i++) { (httpParam+i)->bKillWebserver=1; } return 0;}int main(int argc,char* argv[]){ printf("MiniWeb %d.%d.%d (C)2005 Written by Stanley Huang\n\n",VER_MAJOR,VER_MINOR,BUILD_NO);#ifdef WIN32 SetConsoleCtrlHandler( (PHANDLER_ROUTINE) MiniWebQuit, TRUE );#else signal(SIGINT, (void *) MiniWebQuit); signal(SIGTERM, (void *) MiniWebQuit); signal(SIGPIPE, SIG_IGN);#endif#ifndef NOTHREAD //get the number of instances { int i; for (i=1;i<argc;i++) { if (!strcmp(argv[i],"-n")) nInst=atoi(argv[++i]); } }#endif if (!nInst) nInst=1; //initialize HTTP parameter structure { int iParamBytes=nInst*sizeof(HttpParam); httpParam=malloc(iParamBytes); if (!httpParam) { printf("Out of memory\n"); return -1; } memset(httpParam,0,iParamBytes); } //fill in default settings { int i; for (i=0;i<nInst;i++) { (httpParam+i)->siMaxClients=32; (httpParam+i)->siMaxReqPerConn=99; (httpParam+i)->pchWebPath="webroot"; (httpParam+i)->pxUrlHandler=urlHandlerList; } } //parsing command line arguments { int inst=0; int i; for (i=1;i<argc;i++) { if (argv[i][0]=='-') { switch (argv[i][1]) { case 'i': if ((++i)<argc) { int n=atoi(argv[i]); if (n<nInst) inst=n;; } break; case 'p': if ((++i)<argc) (httpParam+inst)->siHttpPort=atoi(argv[i]); break; case 'r': if ((++i)<argc) (httpParam+inst)->pchWebPath=argv[i]; break; case 'l': if ((++i)<argc) fpLog=freopen(argv[i],"w",stderr); break; case 'm': if ((++i)<argc) (httpParam+inst)->siMaxClients=atoi(argv[i]); break; case 'k': if ((++i)<argc) (httpParam+inst)->siMaxReqPerConn=atoi(argv[i]); break; case 'c': if ((i<argc-1 && argv[i+1][0]!='-')) pchCounterFile=argv[++i]; else pchCounterFile="counters.dat"; break; case 'd': (httpParam+inst)->flags |= FLAG_DIR_LISTING; break; } } } } //adjust port setting { int i; short int port=80; for (i=0;i<nInst;i++) { if ((httpParam+i)->siHttpPort) port=(httpParam+i)->siHttpPort+1; else (httpParam+i)->siHttpPort=port++; } } if (pchCounterFile) { int i; //load counter values from file loadWebCounter(); printf("Counter enabled (%s)\n",pchCounterFile); for (i=0;urlHandlerList[i].pchUrlPrefix;i++); urlHandlerList[i].pchUrlPrefix="counter/"; urlHandlerList[i].pfnUrlHandler=&uhWebCounter; } InitSocket(); if (nInst>1) printf("Number of instances: %d\n",nInst); { int i; int error=0; for (i=0;i<nInst;i++) { int n; if (nInst>1) printf("\nInstance %d\n",i); printf("Listening port: %d\n",(httpParam+i)->siHttpPort); printf("Web root: %s\n",(httpParam+i)->pchWebPath); printf("Max clients: %d\n",(httpParam+i)->siMaxClients); for (n=0;urlHandlerList[n].pchUrlPrefix;n++); printf("URL handlers: %d\n",n); if ((httpParam+i)->flags & FLAG_DIR_LISTING) printf("Dir listing: on\n"); //register page variable substitution callback //(httpParam+i)->pfnSubst=DefaultWebSubstCallback; //start server if (mwServerStart(&httpParam[i])) { DEBUG("Error starting instance #%d\n",i); error++; } } if (error<nInst) { #ifndef NOTHREAD ThreadWait(httpParam[0].tidHttpThread,NULL); #endif } else { printf("Failed to launch miniweb\n"); } } //shutdown server { saveWebCounter(); if (nInst>1) { int i; for (i=0;i<nInst;i++) { printf("Shutting down instance %d\n",i); mwServerShutdown(&httpParam[i]); } } else { mwServerShutdown(&httpParam[0]); } fclose(fpLog); } UninitSocket(); return 0;}////////////////////////////// END OF FILE //////////////////////////////
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -