Beispiel #1
0
void
core_engine_run(void)
{
    for (; ;) {
        if (g_termin_service) {
            break;
        }
        web_log(WEB_LOG_DEBUG, "core event dispatch\n");
        event_dispatch();
        web_log(WEB_LOG_DEBUG, "core events processing\n");
        ev_process_all_events();
    }
}
Beispiel #2
0
/*
 * Add an handler to request data
 */
int web_server_addhandler(struct web_server *server,const char *mstr,void (*func)(void*),int flag, void* userdata) {
	_logfile=server->weblog;
	// xor?
	flag ^= (server->flags & WS_LOCAL); // global flag to handler flag
	flag ^= (server->flags & WS_DYNVAR); // global flag to handler flag
	flag ^= (server->flags & WS_USELEN); // global flag to handler flag
	web_log("[%s] Adding handler %s <--%s%s%s\n",__ILWS_date(time(NULL),"%d/%b/%Y:%H:%M:%S %z"),mstr, ((flag & WS_LOCAL) == WS_LOCAL && !((server->flags & WS_LOCAL) == WS_LOCAL))?"[LOCAL] ":"", ((flag & WS_DYNVAR) == WS_DYNVAR)?"[DYNVAR]":"", ((flag & WS_USELEN) == WS_USELEN)?"[USELEN]":"");
	return __ILWS_add_handler((struct gethandler *)server->gethandler,mstr,func,NULL,flag,GH_FUNCTION,userdata);
}
Beispiel #3
0
/*
 * Add an alias dir (new on 0.5.2)
 */
int web_server_aliasdir(struct web_server *server, const char *str, char *path,int flag) {
	char *mstr;
	int ret;
	mstr=__ILWS_malloc(strlen(str)+7);
	if(!strlen(str)) {
		snprintf(mstr,strlen(str)+7,"* /*");
	} else {
		snprintf(mstr,strlen(str)+7,"* /%s/*",str);
	};
	_logfile=server->weblog;
	flag ^= (server->flags & WS_LOCAL); // global flag to handler flag
	flag ^= (server->flags & WS_DYNVAR); // global flag to handler flag
	flag ^= (server->flags & WS_USELEN); // global flag to handler flag
	web_log("[%s] Adding directory %s <--%s%s%s\n",__ILWS_date(time(NULL),"%d/%b/%Y:%H:%M:%S %z"),mstr, ((flag & WS_LOCAL) == WS_LOCAL && !((server->flags & WS_LOCAL) == WS_LOCAL))?"[LOCAL] ":"", ((flag & WS_DYNVAR) == WS_DYNVAR)?"[DYNVAR]":"", ((flag & WS_USELEN) == WS_USELEN)?"[USELEN]":"");
	ret=__ILWS_add_handler((struct gethandler *)server->gethandler,mstr,NULL,path,flag,GH_DIRECTORY,NULL);
	__ILWS_free(mstr);
	return ret;
};
Beispiel #4
0
/* 
 * Read what client have to say
 */
void __ILWS_read_client(struct web_client *node) {
	int tmp,tmp1;
	char *tmp2,*tmp3=NULL;
	char readtemp[READMAX+1];
	unsigned long datasize=0;	

#ifdef HAVE_OPENSSL
	if(node->ssl!=NULL) {	
		tmp=SSL_read(node->ssl,readtemp,READMAX);		
	} else {
		tmp=__ILWS_read(node->socket,readtemp,READMAX);
	};
#else
	tmp=__ILWS_read(node->socket,readtemp,READMAX);
#endif
	//fprintf(stderr,"readed %d bytes\n",tmp);
	if(tmp<1) {
	
#ifdef WIN32
		if(WSAGetLastError()!=WSAEWOULDBLOCK) { 
#else			
		if(errno!=EAGAIN) { 
#endif
			node->stat=5;return;
		
		};
		//fprintf(stderr,"try: %d (%s)\n",node->newdata_try,node->rbuf);
		// check if it is over
		node->newdata_try++;
		//fprintf(stderr,"node->newdata_try:%d\n",node->newdata_try);
		if(node->rbufsize >0) {  //&& node->newdata_try>5) { 
			if(node->headersize==0) { // always reachs "\r\n\r\n"
				if((tmp3=strstr(node->rbuf,"\r\n\r\n"))) {
					node->headersize=(tmp3-node->rbuf);
				};
			} else {
				datasize=node->rbufsize-node->headersize;
				if(node->contentlength==0) { // well if it 0 read all at once
					__ILWS_init_clientinfo(); // always call this?
					node->contentlength=atol(ClientInfo->Header("Content-Length"));
					// range for resuming
					if((tmp3=strstr(ClientInfo->Header("Range"),"bytes="))) { // if it is in bytes (i hope, always)
						tmp3+=6; // go to end of "bytes="
						node->range=atol(tmp3);
						//printf("Range is %d - %s - %s\n",node->range,ClientInfo->Header("Range"),tmp3);
					};
					// end range
					__ILWS_free_clientinfo();
				};
				if(node->contentlength==datasize-4) {
					//fprintf(stderr,"client (%d) all readed (%d) (try's)-%d\n",node->socket,node->curcl-node->oldcl,node->newdata_try); 
					node->newdata_try=WEBTIMEOUT; // assume done reading
					//fprintf(stderr,"Ended naturaly\n");
					
				}
			};
			if((node->newdata_try>=WEBTIMEOUT)) { // All readed
				node->rbuf[node->rbufsize]='\0';
				node->stat=2; // Next state
				//fprintf(stderr,"%s\n",node->rbuf);
				//fprintf(stderr,"%d\n",node->rbufsize);
			}
		};	
	}else {
		tmp1=node->rbufsize;
		node->rbufsize+=tmp;
		tmp2=__ILWS_realloc(node->rbuf,node->rbufsize+1);
		if(tmp2==NULL) {
			LWSERR(LE_MEMORY);
			node->stat=5;
			
			return;
		}else {
			node->rbuf=tmp2;
		};
		memcpy(node->rbuf+tmp1,readtemp,tmp);
		node->newdata_try=0;
	};
}


/*********************************************************************************************************/
/*
 * Process headers w/ get handlers
 */
void __ILWS_process_client(struct web_client *node,struct gethandler *list) {
	struct gethandler *gettemp=list;
	time_t secs=time(NULL);
// for determining content length
#define RTMPMAX 400	
	struct outstream *tmpstream; // new on 0.5.1
	char rtmp[RTMPMAX+1];
	int rtmps=0;
	char *thead=NULL;
	char *tmpl;
///
	int tmp=0;
	int oumask=0; // old usermask
	char *tmp1=__ILWS_web_client_getreq();
	char matchbuf[MATCHMAX];	
	FILE *nfile;  // new file
	char *fname;  // new file name
	
	
	while(gettemp->next!=NULL && tmp==0) {
		gettemp=gettemp->next;
		snprintf(matchbuf,MATCHMAX,"%s",gettemp->str);
		if(!tmp1) {
			__ILWS_web_client_writef(node,"HTTP/1.1 400 Invalid request\r\n");
			__ILWS_web_client_writef(node,"Server: %s\r\n",_libwebserver_version);
			__ILWS_web_client_writef(node,"Date: %s\r\n",__ILWS_date(mktime(gmtime(&secs)),"%a, %d %b %Y %H:%M:%S GMT")); // Date header
			__ILWS_web_client_writef(node,"Content-type: text/html\r\n\r\n<HTML><title>Invalid request</title><body bgcolor=FFFFFF><font size=6>400 Invalid  request</font><BR><BR><small>Yout request doesn't match the requesits to be processed</small><BR><HR><small><i>%s</i></small></body></html>\n\r",_libwebserver_version);                                    
			tmpl=__ILWS_web_client_getreqline();
			web_log("%s - - [%s] \"%s\" 400 (invalid request)\n",inet_ntoa(node->sa.sin_addr),__ILWS_date(time(NULL),"%d/%b/%Y:%H:%M:%S %z"),tmpl); 
			__ILWS_free(tmpl);
			node->stat=5;
			return;
		};
		if(strlen(tmp1)>MAXURLSIZE) {
			__ILWS_web_client_writef(node,"HTTP/1.1 414 URL to large\r\n");
			__ILWS_web_client_writef(node,"Server: %s\r\n",_libwebserver_version);
			__ILWS_web_client_writef(node,"Date: %s\r\n",__ILWS_date(mktime(gmtime(&secs)),"%a, %d %b %Y %H:%M:%S GMT")); // Date header
			__ILWS_web_client_writef(node,"Content-type: text/html\r\n\r\n<HTML><title>URL to large</title><body bgcolor=FFFFFF><font size=6>414 Requested url to large</font><BR><BR><small>Wonder this... why is that so large?</small><BR><HR><small><i>%s</i></small></body></html>\n\r",_libwebserver_version);                                    
			tmpl=__ILWS_web_client_getreqline();
			web_log("%s - - [%s] \"%s\" 414 (url to large)\n",inet_ntoa(node->sa.sin_addr),__ILWS_date(time(NULL),"%d/%b/%Y:%H:%M:%S %z"),tmpl); 
			__ILWS_free(tmpl);
			node->stat=5;
			__ILWS_free(tmp1);
			return;
		};
		if(!fnmatch(matchbuf,tmp1,5)) {
			if((gettemp->flag & WS_LOCAL) == WS_LOCAL) {
				if(node->sa.sin_addr.s_addr!=0x0100007F) {
					__ILWS_web_client_writef(node,"HTTP/1.1 403 Forbidden\r\n");
					__ILWS_web_client_writef(node,"Server: %s\r\n",_libwebserver_version);
					__ILWS_web_client_writef(node,"Date: %s\r\n",__ILWS_date(mktime(gmtime(&secs)),"%a, %d %b %Y %H:%M:%S GMT")); // Date header
					__ILWS_web_client_writef(node,"Content-type: text/html\r\n\r\n<HTML><title>Forbidden</title><body bgcolor=FFFFFF><font size=6>403 Forbidden</font><BR><BR><small>only local host accepted</small><BR><HR><small><i>%s</i></small></body></html>\n\r",_libwebserver_version);
					tmpl=__ILWS_web_client_getreqline();
					web_log("%s - - [%s] \"%s\" 403 (Forbidden)\n",inet_ntoa(node->sa.sin_addr),__ILWS_date(time(NULL),"%d/%b/%Y:%H:%M:%S %z"),tmpl); 
					__ILWS_free(tmpl);
					node->stat=5;
					__ILWS_free(tmp1);
					return;
				};
			};                        
			tmp=1; // Was found
			node->outstream->flags=(gettemp->flag & WS_DYNVAR); // pass to outstreams
		};	
	};	
	__ILWS_free(tmp1);
	if(!tmp) { // Nothing found
		__ILWS_web_client_writef(node,"HTTP/1.1 404 Not Found\r\n");
		__ILWS_web_client_writef(node,"Server: %s\r\n",_libwebserver_version);
		__ILWS_web_client_writef(node,"Date: %s\r\n",__ILWS_date(mktime(gmtime(&secs)),"%a, %d %b %Y %H:%M:%S GMT")); // Date header
		__ILWS_web_client_writef(node,"Content-type: text/html\r\n\r\n<HTML><title>not found</title><body bgcolor=FFFFFF><font size=6>404 NOT FOUND</font><BR><BR><small>The requested content wasn't found</small><BR><HR><small><i>%s</i></small></body></html>\n\r",_libwebserver_version);                                    
		tmpl=__ILWS_web_client_getreqline();
		web_log("%s - - [%s] \"%s\" 404 (Not Found)\n",inet_ntoa(node->sa.sin_addr),__ILWS_date(time(NULL),"%d/%b/%Y:%H:%M:%S %z"),tmpl); 
		__ILWS_free(tmpl);
		node->stat=5;
	}else {
		
		// if cgi do something else, present headers
		oumask=umask(077);
		if(!(fname=__ILWS_tmpfname())) {
			libws_error(LE_FILESYS,": Error giving a temp filename\n");
			node->stat=5;
			return;
		};
		if((nfile=freopen(fname,"wb+",stdout))!=NULL) {
			flock(fileno(stdout),LOCK_EX);
			tmp=dup(fileno(stdout));
			nfile=fdopen(tmp,"wb+");
			if(!__ILWS_add_outstream(node->outstream,fname,nfile,1)) {
				node->stat=5; // (delete client)
				return; // ERROR reported by add_outstream
				
			};
// THE PROCESS
			
			// Setup Clientinfo before running function
			if(gettemp->type==GH_FUNCTION) {
				__ILWS_init_clientinfo();	 
				gettemp->hdl.func(gettemp->userdata); // changed (0.5.3) Access by named union (Hilobok Andrew ([email protected]) said that wasn't compile on freeBSD)
				__ILWS_free_clientinfo();        
			};
			// new on 0.5.2
			if(gettemp->type==GH_DIRECTORY) { // as builtin function for directory listing
				__ILWS_init_clientinfo();
				if(strcmp(gettemp->str,"* /*"))ClientInfo->request+=1;  // skip '/' if not equal to "* /*" (used by default)
				__ILWS_lws_list(gettemp->hdl.path); // changed (0.5.3) Access by named union (Hilobok Andrew ([email protected]) said that wasn't compile on freeBSD)
				__ILWS_free_clientinfo();
			};
			
			fflush(stdout);
			fclose(stdout); // it is a tempfile freopened 
			__ILWS_free(fname); // doesn't need anymore
#ifdef WIN32			
			freopen("con","w",stdout);
#else
			freopen("/dev/tty","w",stdout);
#endif
			if((gettemp->flag & WS_USELEN) == WS_USELEN) {
// determine writelength (for content-length: header) (new on 0.5.1)
				tmpstream=node->outstream;
				tmp=0;
				while(tmpstream->next!=NULL) { // end of header probably in the firsts outstream nodes check for that
					if(tmpstream->next->fname!=NULL) {
						if(tmpstream->next->fstream==NULL) {
							nfile=fopen(tmpstream->next->fname,"rb");
							tmpstream->next->fstream=nfile; // here (corrected on 0.5.3);
						} else {
							fflush(tmpstream->next->fstream); // <- flush tha thing
							nfile=tmpstream->next->fstream;
							fseek(nfile,0,SEEK_SET);
						};
						if(nfile!=NULL) {
							rtmps=0;
							while((!node->wheadersize) && (!feof(nfile))) { // wheadersize is 0, suposed to be fast, at least if is not malformed
								if(rtmps>0)	{tmp-=4;fseek(nfile,rtmps-4,SEEK_SET);}
								if((rtmps=fread(rtmp,1,RTMPMAX,nfile))>0) {
									rtmp[rtmps]=0;
									if((tmp1=strstr(rtmp,"\r\n\r\n"))) {
										node->wheadersize=(tmp+((tmp1+4)-rtmp));
										rtmps=((tmp1+4)-rtmp);
										
									}; 
									if(node->range>0) {
										tmp1=realloc(thead,tmp+rtmps+1);
										thead=tmp1;
										memcpy(thead+tmp,rtmp,rtmps);
										thead[tmp+rtmps]=0;
									};
									tmp+=rtmps;
								};
							};
							fseek(nfile,SEEK_END,SEEK_END);
							node->writelength+=(ftell(nfile)-2);
							//fclose(nfile); // <- don't worry they close the file later
						};
					};
					tmpstream=tmpstream->next;
					
				};
// end writelength
			} else {
				node->range=0; // no content-range
			};
			
			if(node->range>node->writelength-node->wheadersize && node->range>0) {
				__ILWS_web_client_writef(node,"HTTP/1.1 416 Requested Range Not Satisfiable\r\n");
				__ILWS_web_client_writef(node,"Server: %s\r\n",_libwebserver_version);
				__ILWS_web_client_writef(node,"Date: %s\r\n",__ILWS_date(mktime(gmtime(&secs)),"%a, %d %b %Y %H:%M:%S GMT")); // Date header
				__ILWS_web_client_writef(node,"Content-range: bytes */%d\r\n",node->writelength-node->wheadersize);
				__ILWS_web_client_writef(node,"Content-type: text/html\r\n\r\n<HTML><title>Requested Range Not Satisfiable</title><body bgcolor=FFFFFF><font size=6>416 Requested Range Not Satisfiable</font><BR><BR><small>You're trying to resume an content that is smaller than the requested range</small><BR><HR><small><i>%s</i></small></body></html>\n\r",_libwebserver_version);                                    
				tmpl=__ILWS_web_client_getreqline();
				web_log("%s - - [%s] \"%s\" 416 (Requested Range Not Satisfiable)\n",inet_ntoa(node->sa.sin_addr),__ILWS_date(time(NULL),"%d/%b/%Y:%H:%M:%S %z"),tmpl); 
				__ILWS_free(tmpl);
				node->stat=5;
				__ILWS_free(thead);
				umask(oumask);
				return;
			};
			if(node->range>0 && ((node->outstream->flags & WS_DYNVAR)==WS_DYNVAR)) { // if request range interval and dynvar on than produces not implemented
				__ILWS_web_client_writef(node,"HTTP/1.1 501 Not Implemented\r\n");
				__ILWS_web_client_writef(node,"Server: %s\r\n",_libwebserver_version);
				__ILWS_web_client_writef(node,"Date: %s\r\n",__ILWS_date(mktime(gmtime(&secs)),"%a, %d %b %Y %H:%M:%S GMT")); // Date header
				__ILWS_web_client_writef(node,"Content-type: text/html\r\n\r\n<HTML><title>Not implemented</title><body bgcolor=FFFFFF><font size=6>501 Not implemented</font><BR><BR><small>Your trying to resume an content that is not possible to resume(WS_DYNVAR fault)</small><BR><HR><small><i>%s</i></small></body></html>\n\r",_libwebserver_version);                                    
				tmpl=__ILWS_web_client_getreqline();
				web_log("%s - - [%s] \"%s\" 501 (Not Implemented)\n",inet_ntoa(node->sa.sin_addr),__ILWS_date(time(NULL),"%d/%b/%Y:%H:%M:%S %z"),tmpl); 
				__ILWS_free(tmpl);
				node->stat=5;
				__ILWS_free(thead);
				umask(oumask);
				return;
			};

		}else {
			LWSERR(LE_FILESYS);
			
		}; 
		node->stat=4;   
		if(node->HTTPdirective==NULL) {
			if(node->range>0) {
				__ILWS_web_client_writef(node,"HTTP/1.1 206 Partial Content\r\n");
				tmpl=__ILWS_web_client_getreqline();
				web_log("%s - - [%s] \"%s\" 206 (Partial Content)\n",inet_ntoa(node->sa.sin_addr),__ILWS_date(time(NULL),"%d/%b/%Y:%H:%M:%S %z"),tmpl); 
				__ILWS_free(tmpl);
			} else {
				__ILWS_web_client_writef(node,"HTTP/1.1 200 OK\r\n");
				tmpl=__ILWS_web_client_getreqline();
				web_log("%s - - [%s] \"%s\" 200 (OK)\n",inet_ntoa(node->sa.sin_addr),__ILWS_date(time(NULL),"%d/%b/%Y:%H:%M:%S %z"),tmpl); 
				__ILWS_free(tmpl);
			};

		} else {
			__ILWS_web_client_writef(node,"%s\r\n",node->HTTPdirective);
			tmpl=__ILWS_web_client_getreqline();
			web_log("%s - - [%s] \"%s\" XXX (User defined)\n",inet_ntoa(node->sa.sin_addr),__ILWS_date(time(NULL),"%d/%b/%Y:%H:%M:%S %z"),tmpl); 
			__ILWS_free(tmpl);
		};
		__ILWS_web_client_writef(node,"Server: %s\r\n",_libwebserver_version);
		__ILWS_web_client_writef(node,"Date: %s\r\n",__ILWS_date(mktime(gmtime(&secs)),"%a, %d %b %Y %H:%M:%S GMT")); // Date header
		__ILWS_web_client_writef(node,"Accept-Ranges: bytes\r\n");
		if((((node->writelength-node->wheadersize)-node->range)>0) && !((node->outstream->flags & WS_DYNVAR)==WS_DYNVAR))__ILWS_web_client_writef(node,"Content-length: %d\r\n",(node->writelength-node->wheadersize)-node->range);
		if(node->cookies!=NULL)__ILWS_web_client_writef(node,"%s",node->cookies); // new (0.5.1)
		if(node->range>0) {
			__ILWS_web_client_writef(node,"Content-range: bytes %d-%d/%d\r\n",node->range,(node->writelength-node->wheadersize)-1,node->writelength-node->wheadersize);
			__ILWS_web_client_writef(node,"%s",thead); // the rest of header
			__ILWS_free(thead);
		};
		umask(oumask);
		
	};

}
/*********************************************************************************************************/
/*
 * Process stream output
 */
void __ILWS_output_client(struct web_client *node) {
	struct outstream *tstream=node->outstream;
	char *tmp1,*tmp2,*tmp3;
	char writetemp[WRITEMAX+1];
	int beginsize=0;
	int endsize=0;
	int varsize=0;
	int namesize=0;
	if(tstream->next!=NULL) {
		if(tstream->next->fname!=NULL) {
			if(tstream->next->fstream==NULL) {
				if((tstream->next->fstream=fopen(tstream->next->fname,"rb"))==NULL) {
					LWSERR(LE_FILESYS);
					__ILWS_delete_next_outstream(tstream);
					//node->outstream->next=tstream->next;
					return;
				} 
			};

			// read part (must always read)
			if(tstream->next->rsize==0) {  // start from 0
				fseek(tstream->next->fstream,0,SEEK_SET); 
			};
			memset(writetemp,0,WRITEMAX);
			tstream->next->rsize=fread(writetemp,1,WRITEMAX,tstream->next->fstream);
			writetemp[tstream->next->rsize]=0;
			// if read make var changes on writetemp;
			// new on 0.5.1  -- UNDERDEV                               // FIX -
			if((node->outstream->flags & WS_DYNVAR) == WS_DYNVAR) {
				
				tmp1=writetemp;
				while(((tmp1=strstr(tmp1,"$")+1)!=(char*)1) && beginsize==0) {   // check var found
					for(namesize=0;namesize<50;namesize++) {
						if(tmp1[namesize]==';') {namesize++;break;}
						if((tmp1[namesize]<'a' || tmp1[namesize]>'z') && 
						   (tmp1[namesize]<'A' || tmp1[namesize]>'Z') &&
						   (tmp1[namesize]<'1' || tmp1[namesize]>'0') &&
						   tmp1[namesize]!='_') {namesize=0;break;};
						
					};
					if(namesize>0) {
						if(namesize==1) { // this is $; for sure
							if(!(tmp3=__ILWS_malloc(2))) {
								LWSERR(LE_MEMORY);
								node->stat=5;
								return;
							};
							memcpy(tmp3,"$",namesize);
							tmp3[namesize]=0;
						} else {
							if(!(tmp3=__ILWS_malloc(namesize))) {
								LWSERR(LE_MEMORY);
								node->stat=5;
								return;
							};
							memcpy(tmp3,tmp1,namesize-1);
							tmp3[namesize-1]=0;
						};
						
						tmp1-=1;
						
						beginsize=tmp1-writetemp;
						tmp1+=namesize;  // get var from whateverwhere (client node probably)
												
						endsize=strlen(tmp1);	
						
						//varsize=2;
												
						if((tmp2=__ILWS_malloc(beginsize+1))) {
							memcpy(tmp2,writetemp,beginsize);
							tmp2[beginsize]=0;
							if(namesize==1) {
								varsize=strlen(tmp3);
								snprintf(writetemp,WRITEMAX,"%s%s",tmp2,tmp3);
							} else {
								varsize=strlen(__ILWS_get_var(node->varlist,tmp3));
								snprintf(writetemp,WRITEMAX,"%s%s",tmp2,__ILWS_get_var(node->varlist,tmp3));
							};
							writetemp[strlen(tmp2)+varsize]=0;
							__ILWS_free(tmp2);
							__ILWS_free(tmp3);
							tstream->next->rsize=(beginsize+varsize);
							tstream->next->varsize+=(varsize-namesize)-1;
						} else {
							LWSERR(LE_MEMORY);
							__ILWS_free(tmp3);
							node->stat=5;
							return;
						};
					};
				};
			}; // dynvar 

			/* there is nothing more to read here */
			if(tstream->next->rsize<1){ // i guess rsize < 1 is eof (make sure that server writed last time)
				//only change if everything written
				if(feof(tstream->next->fstream) && (ftell(tstream->next->fstream)==tstream->next->wrotesize)) {
					//fclose(tstream->next->fstream);
					
					__ILWS_delete_next_outstream(tstream);
					//node->outstream->next=tstream->next; 
				}
				return;
			}
			node->readsize+=tstream->next->rsize;						
			if(!node->skipped && node->range>0) {
				tstream->next->wsize=tstream->next->rsize;
				tstream->next->wrotesize+=tstream->next->wsize;	
				if((node->readsize-node->wheadersize)<node->range) { // skip range bytes
					return; // do nothing
				}else {
					node->skipped=1;
					tstream->next->wrotesize-=(node->readsize-node->wheadersize)-node->range; // the right offset
					fseek(tstream->next->fstream,tstream->next->wrotesize,SEEK_SET);
					tstream->next->wsize=tstream->next->rsize;
					return;
				};
			};
			// write part

#ifdef HAVE_OPENSSL
			if(node->ssl!=NULL) {
				tstream->next->wsize=SSL_write(node->ssl,writetemp,tstream->next->rsize);
			} else {
				tstream->next->wsize=send(node->socket,writetemp,tstream->next->rsize,0);
			};
#else		
			tstream->next->wsize=send(node->socket,writetemp,tstream->next->rsize,0);
#endif
			if(tstream->next->wsize>0) {
				tstream->next->wrotesize+=tstream->next->wsize;	
				if(tstream->next->rsize!=tstream->next->wsize || beginsize>0) {	                     // FIX
					fseek(tstream->next->fstream,tstream->next->wrotesize-(tstream->next->varsize),SEEK_SET);       // FIX
				};
			};
#ifdef WIN32
			if((tstream->next->wsize<=0) && (WSAGetLastError()!=WSAEWOULDBLOCK)) {  // WIN32 only 
#else
			if(tstream->next->wsize<=0 && errno!=EAGAIN) {  // linux only // *nix i guess
#endif			
				//fclose(tstream->next->fstream);
				
				__ILWS_delete_next_outstream(tstream);
				//node->outstream->next=tstream->next; 
				return;
			}else { // broken pipe
				if(tstream->next->wsize<0) {
					fseek(tstream->next->fstream,tstream->next->wrotesize-(tstream->next->varsize),SEEK_SET);       //didn't read must back to where it was
				 };
			};
			
		}else { // filename is null
			
			__ILWS_delete_next_outstream(tstream);
			return;
		};
	}else { // End of streams
		
		current_web_client->stat=5; // done

	};
}

/*********************************************************************************************************/
/*
 * Set http directive
 */
void web_client_HTTPdirective(char *str) { 
	current_web_client->HTTPdirective=str;
}


/*********************************************************************************************************/
/*
 * GET request name
 */
char *__ILWS_web_client_getreq() {
	char *ret;
	char *tmp1=strstr(current_web_client->rbuf,"?");
	char *tmp2=strstr(current_web_client->rbuf," HTTP");
	char *tmp3=strstr(current_web_client->rbuf,"\r\n");
	int size;
	if(tmp1==NULL || tmp1>tmp2) {
		tmp1=tmp2;
	};
	if(tmp2>tmp3) {
		return NULL;
	};
	size=tmp1-current_web_client->rbuf;
	if(size<1) return NULL;
	
	if(!(ret=__ILWS_malloc(size+1))) {
		LWSERR(LE_MEMORY);
		return NULL;
	};
	memcpy(ret,current_web_client->rbuf,size);
	ret[size]=0;
	return ret;

};

/*********************************************************************************************************/
/*
 * GET request line
 */
char *__ILWS_web_client_getreqline() {
	char *ret;
	char *tmp1=strstr(current_web_client->rbuf,"\r\n");
	int size=0;
	if(tmp1==NULL) return NULL;
	size=tmp1-current_web_client->rbuf;
	if(size<1) return NULL;
	
	if(!(ret=__ILWS_malloc(size+1))) {
		LWSERR(LE_MEMORY);
		return NULL;
	};
	memcpy(ret,current_web_client->rbuf,size);
	ret[size]=0;
	return ret;
}
Beispiel #5
0
/*
 * Core function, return 2 if no client to process, 1 if some client processed, 0 if error
 */
int web_server_run(struct web_server *server) {
	struct web_client *client;
	int rt;
	int tsalen=0;
	int tsocket=0;
	struct sockaddr_in tsa;
	_logfile=server->weblog;
	current_web_server=server;
	if(server->client->next==NULL) {
		//if(__ILWS_newdata(server->socket)); // does nothing but act like usleep 
	};
// search for client		
	tsalen=sizeof(client->sa);
	tsocket=accept(server->socket,(struct sockaddr *)&tsa,&tsalen);
	if(tsocket==-1) {
#ifdef WIN32
		if(WSAGetLastError()!=WSAEWOULDBLOCK) { 
#else			
		if(errno!=EAGAIN) { 
#endif
			fprintf(stderr,"What kind of error is this?\n"); // REMOVE
			// client f****d up? warn somebody? (error or log or something?)
			return 0; // don't process nothing
		};
	} else {
		client=__ILWS_malloc(sizeof(struct web_client));
		if(client==NULL) {
			rt=shutdown(tsocket,SHUT_RDWR);
#ifdef WIN32
			rt=closesocket(tsocket); 
#else
			rt=close(tsocket); 
#endif
			LWSERR(LE_MEMORY);
			return 0;
		};
		client->salen=tsalen;
		client->socket=tsocket;
		client->sa=tsa;
#ifdef HAVE_OPENSSL
		if((server->flags & WS_USESSL) == WS_USESSL) {
			client->ssl = SSL_new(server->ctx);
			SSL_set_fd(client->ssl,client->socket);
			SSL_accept(client->ssl);
		//client->cert = SSL_get_peer_certificate (client->ssl);
		} else {
			client->ssl=NULL;
		};
#endif
		if(!__ILWS_add_client(server->client,client)) {
			fprintf(stderr,"No client?\n"); // REMOVE
			return 0;
		}else {
			web_log("%s - - [%s] Connected\n",inet_ntoa(client->sa.sin_addr),__ILWS_date(time(NULL),"%d/%b/%Y:%H:%M:%S %z")); //REMOBE			
		};
	};
	// end search for client
	client=server->client; // init list
	if(!client->next) { // think of Rocco Carbone ([email protected])
		return 2; // i don't need to process the list (nothing next) returns 2 if there is no client to process
	};
	while(client->next!=NULL) { // Process the client and swap to next;
		current_web_client=client->next;
		switch(client->next->stat) {
			case 1: {
				__ILWS_read_client(current_web_client);
			};break;
            case 2: {
				__ILWS_process_client(current_web_client,server->gethandler);
			};break;
			case 4: {
				__ILWS_output_client(current_web_client);	
			};break;
			case 5: {
				__ILWS_delete_next_client(client); 
				continue;
			};break;
		};
		client=client->next;
	
	};   
	return 1;  // return 1 if something processed
}
Beispiel #6
0
/*
 * This function initialize one web_server handler
 */
int web_server_init(struct web_server *server,int port,const char *logfile,int flags) {
#ifdef WIN32	
	unsigned long t=IOC_INOUT;
	WSADATA WSAinfo;
	WSAStartup(2,&WSAinfo); // Damn w32 sockets
#endif

	current_web_server=server;
	server->port=port;
	server->conffile=NULL;
	server->mimefile=NULL;
	server->weblog=NULL;
	server->usessl=0;
	server->flags=flags;
	server->dataconf="";
	if((flags & WS_USEEXTCONF) == WS_USEEXTCONF) {
		if(!(web_server_setup(server,logfile))) {
#ifdef WIN32		
			WSACleanup();
#endif
			return 0;
		};
		_logfile=server->weblog; // Set current log stream
		web_log("%s using config file %s\n",_libwebserver_version,logfile);
	};
	// Create a listen socket port 'port' and listen addr (0) (all interfaces)
	server->socket=__ILWS_listensocket((short)server->port,0);	
	if(server->socket==-1) {
		LWSERR(LE_NET);
#ifdef WIN32		
		WSACleanup();
#endif
		return 0;
	};
#ifdef WIN32
	ioctlsocket(server->socket,FIONBIO,&t);  //non blocking sockets for win32
#else
	fcntl(server->socket,F_SETFL,O_NONBLOCK);
#endif
	// Setup FILE structure of logfile
	if(logfile!=NULL && !((flags & WS_USEEXTCONF) == WS_USEEXTCONF)) {
		server->logfile=__ILWS_malloc(strlen(logfile)+1);
		memcpy(server->logfile,logfile,strlen(logfile));
		server->logfile[strlen(logfile)]=0;
		server->weblog=open_weblog(logfile); // Create File stream for log
	};
	
	web_log("\n[%s] Server started at port %d (%s)\n",__ILWS_date(time(NULL),"%d/%b/%Y:%H:%M:%S %z"),server->port,_libwebserver_version);
	
	// Setup Flags
	
	// openssl
#ifdef HAVE_OPENSSL	
	if((server->flags & WS_USESSL) == WS_USESSL) {
		web_log("[%s] (FLAG) Using SSL in connections\n",__ILWS_date(time(NULL),"%d/%b/%Y:%H:%M:%S %z"));	
		web_log("                       +-- %s certificate file\n",server->cert_file);
		SSL_load_error_strings();
		SSLeay_add_ssl_algorithms(); 	
		server->ctx=SSL_CTX_new (SSLv23_server_method());
		if (SSL_CTX_use_certificate_file(server->ctx, server->cert_file, SSL_FILETYPE_PEM) <= 0) {
			ERR_print_errors_fp(stderr);
			exit(3);
		}
		if (SSL_CTX_use_PrivateKey_file(server->ctx, server->cert_file, SSL_FILETYPE_PEM) <= 0) {
			ERR_print_errors_fp(stderr);
			exit(4);
		}                      
	 	if (SSL_CTX_check_private_key(server->ctx)<= 0)  	 {
			ERR_print_errors_fp(stderr);
			exit(4);
		};
		server->usessl=1;
	};
#endif
	if((server->flags & WS_LOCAL) == WS_LOCAL) {
		web_log("[%s] (FLAG) Accepting only local connections\n",__ILWS_date(time(NULL),"%d/%b/%Y:%H:%M:%S %z"));	
	};
	server->client=__ILWS_init_client_list();										// Initializate client list
	server->gethandler=__ILWS_init_handler_list();									// Initializate handlers list
	web_server_addhandler(server,"* /libwebserver.gif",_web_server_logo,0,NULL);	// Add logo default handler

#ifndef WIN32	
	signal(SIGPIPE,SIG_IGN);
#endif
	return 1;
}                            
Beispiel #7
0
/*
 *	Define config file to setup server (new on 0.5.0)
 */
int web_server_setup(struct web_server *server,const char *conffile) {
	FILE *tmpf;
	char *tmp3;
	//long tmpsize=0;
	long sizec;
	struct stat statf; // tested only on win

	if(!(server->conffile=__ILWS_malloc(strlen(conffile)+1))) {
		LWSERR(LE_MEMORY);
		return 0;
	};

	memcpy(server->conffile,conffile,strlen(conffile));
	server->conffile[strlen(conffile)]=0;
	
	tmpf=fopen(server->conffile,"r");
	if(tmpf==NULL) {
		printf("no config file found\r\n");
		server->dataconf="";
		return(0);
	};
	fseek(tmpf,SEEK_SET,SEEK_END);
	sizec=ftell(tmpf);
	fseek(tmpf,0,SEEK_SET);
	if(!(server->dataconf=__ILWS_malloc(sizec+1))) {
		LWSERR(LE_MEMORY);
		return 0;
	};
	fread(server->dataconf,sizec,1,tmpf);
	server->dataconf[sizec]=0; // Hilobok Andrew ([email protected]) said to remove the -9 :)
	fclose(tmpf);
	
	stat(server->conffile,&statf); // tested only on win
	server->conffiletime=statf.st_mtime; // tested only on win

	if((server->logfile=web_server_getconf(server,"LIBWEBSERVER","LOG"))) {
		web_log("\nUsing logfile [%s]\n",server->logfile);
		server->weblog=open_weblog(server->logfile);
	} else {
		web_log("\nLOG entry not found\r\n");
		server->weblog=NULL;
	};
	if((tmp3=web_server_getconf(server,"LIBWEBSERVER","PORT"))) {
		web_log("\nListen port [%s]\n",tmp3);
		server->port=atoi(tmp3);
		__ILWS_free(tmp3);
	} else {
		web_log("PORT entry not found\r\n");
		server->port=0;
	};
#ifdef HAVE_OPENSSL
	// Fetch SSL
	if((tmp3=web_server_getconf(server,"LIBWEBSERVER","USESSL"))) {
		if(tmp3[0]=='1') {
			server->flags = server->flags | WS_USESSL;
		}else if(tmp3[0]=='0') {
			server->flags = server->flags & ~WS_USESSL;
		} else {
			fprintf(stderr,"[USESSL=] argument invalid\n");
		};
		__ILWS_free(tmp3);
	} 
	// Fetch CERTFILE
	server->cert_file=web_server_getconf(server,"LIBWEBSERVER","CERTFILE");
	server->mimefile=web_server_getconf(server,"LIBWEBSERVER","MIMEFILE");
#endif
	// Fetch LOCAL
	if((tmp3=web_server_getconf(server,"LIBWEBSERVER","LOCAL"))) {
		if(tmp3[0]=='1') {
			server->flags = server->flags | WS_LOCAL;
		} else if(tmp3[0]=='0') {
			server->flags=server->flags & ~WS_LOCAL;
		}else {
			fprintf(stderr,"[LOCAL=] argument invalid\n");
		};
		__ILWS_free(tmp3);
	} 
	
	return 1;
};