diff --git a/src/sbbs3/websrvr.c b/src/sbbs3/websrvr.c index ae8a93a76507369a6431a91c24d05f9e554feb9c..df250059e00abb12cd94d5054395620ab1708cbd 100644 --- a/src/sbbs3/websrvr.c +++ b/src/sbbs3/websrvr.c @@ -35,6 +35,10 @@ * Note: If this box doesn't appear square, then you need to fix your tabs. * ****************************************************************************/ +#if defined(__unix__) + #include <sys/wait.h> /* waitpid() */ +#endif + #include "sbbs.h" #include "sockwrap.h" /* sendfilesocket() */ #include "threadwrap.h" /* _beginthread() */ @@ -48,6 +52,8 @@ extern const uchar* nular; #define TIMEOUT_THREAD_WAIT 60 /* Seconds */ #define MAX_MIME_TYPES 128 #define MAX_REQUEST_LINE 1024 +#define CGI_ENVIRON_BLOCK_SIZE 10 +#define CGI_HEADS_BLOCK_SIZE 5 static scfg_t scfg; static BOOL scfg_reloaded=TRUE; @@ -72,14 +78,25 @@ typedef struct { BOOL keep_alive; char ars[256]; char auth[128]; /* UserID:Password */ - BOOL send_location; + char host[128]; /* The requested host. (virtual hosts) */ + int send_location; + char** cgi_env; + DWORD cgi_env_size; + DWORD cgi_env_max_size; + char** cgi_heads; + DWORD cgi_heads_size; + DWORD cgi_heads_max_size; + char cgi_infile[128]; + char cgi_location[MAX_REQUEST_LINE]; + char cgi_status[MAX_REQUEST_LINE]; } http_request_t; typedef struct { SOCKET socket; SOCKADDR_IN addr; http_request_t req; - char host[128]; /* What's this for? */ + char host_ip[64]; + char host_name[128]; /* Resolved remote host */ int http_ver; /* HTTP version. 0 = HTTP/0.9, 1=HTTP/1.0, 2=HTTP/1.1 */ BOOL finished; /* Do not accept any more imput from client */ } http_session_t; @@ -108,6 +125,7 @@ enum { static char* methods[] = { "HEAD" ,"GET" + ,"POST" ,NULL /* terminator */ }; @@ -130,6 +148,7 @@ enum { ,HEAD_WWWAUTH ,HEAD_CONNECTION ,HEAD_HOST + ,HEAD_STATUS }; static struct { @@ -154,9 +173,16 @@ static struct { { HEAD_WWWAUTH, "WWW-Authenticate" }, { HEAD_CONNECTION, "Connection" }, { HEAD_HOST, "Host" }, + { HEAD_STATUS, "Status" }, { -1, NULL /* terminator */ }, }; +enum { + NO_LOCATION + ,MOVED_TEMP + ,MOVED_PERM +}; + static char *days[]={"Sun","Mon","Tue","Wed","Thu","Fri","Sat"}; static char *months[]={"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"}; @@ -165,6 +191,8 @@ static const char * base64alphabet = static DWORD monthdays[12] = {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334}; +static void respond(http_session_t * session); + static time_t time_gm( struct tm* ti ) { time_t t; @@ -181,7 +209,6 @@ static time_t time_gm( struct tm* ti ) { return t; } - static int lprintf(char *fmt, ...) { va_list argptr; @@ -261,6 +288,135 @@ static void thread_down(void) startup->thread_up(FALSE, FALSE); } +static void grow_enviro(http_session_t *session) { + char **new_cgi_env; + + new_cgi_env=session->req.cgi_env; + new_cgi_env=realloc(session->req.cgi_env, + sizeof(void*)*(CGI_ENVIRON_BLOCK_SIZE+session->req.cgi_env_max_size)); + if(new_cgi_env != NULL) { + session->req.cgi_env=new_cgi_env; + memset(session->req.cgi_env+sizeof(void*)*session->req.cgi_env_max_size,0, + sizeof(void*)*(CGI_ENVIRON_BLOCK_SIZE)); + session->req.cgi_env_max_size+=CGI_ENVIRON_BLOCK_SIZE; + } else { + lprintf("%04d Cannot enlarge environment",session->socket); + } + return; +} + +static void add_env(http_session_t *session, const char *name,const char *value) { + char newname[128]; + char *p; + + if(name==NULL || value==NULL) { + lprintf("%04d Attempt to set NULL env variable", session->socket); + return; + } + SAFECOPY(newname,name); + + for(p=newname;*p;p++) { + *p=toupper(*p); + if(*p=='-') + *p='_'; + } + if(session->req.cgi_env_size==session->req.cgi_env_max_size-1) + grow_enviro(session); + + if(session->req.cgi_env_size<session->req.cgi_env_max_size) { + session->req.cgi_env[session->req.cgi_env_size]= + malloc(sizeof(char)*(strlen(newname)+strlen(value)+2)); + if(session->req.cgi_env[session->req.cgi_env_size] != NULL) { + sprintf(session->req.cgi_env[session->req.cgi_env_size++],"%s=%s", + newname,value); + session->req.cgi_env[session->req.cgi_env_size]=NULL; + lprintf("%04d Set env: %s to %s",session->socket,newname,value); + } + } +} + +static void init_enviro(http_session_t *session) { + char str[128]; + + session->req.cgi_env=malloc(sizeof(void*)*CGI_ENVIRON_BLOCK_SIZE); + if(session->req.cgi_env != NULL) { + memset(session->req.cgi_env,0,sizeof(void*)*CGI_ENVIRON_BLOCK_SIZE); + session->req.cgi_env_max_size=CGI_ENVIRON_BLOCK_SIZE; + } else { + lprintf("%04d Cannot create environment",session->socket); + session->req.cgi_env_max_size=0; + } + /* Need a better way of doing this! */ + add_env(session,"SERVER_SOFTWARE",VERSION_NOTICE); + sprintf(str,"%d",startup->port); + add_env(session,"SERVER_PORT",str); + add_env(session,"GATEWAY_INTERFACE","CGI/1.1"); + if(!strcmp(session->host_name,"<no name>")) + add_env(session,"REMOTE_HOST",session->host_name); + add_env(session,"REMOTE_ADDR",session->host_ip); + return; +} + +static void grow_heads(http_session_t *session) { + char **new_cgi_heads; + + new_cgi_heads=session->req.cgi_heads; + new_cgi_heads=realloc(session->req.cgi_heads, + sizeof(void*)*(CGI_HEADS_BLOCK_SIZE+session->req.cgi_heads_max_size)); + if(new_cgi_heads != NULL) { + session->req.cgi_heads=new_cgi_heads; + memset(session->req.cgi_heads+sizeof(void*)*session->req.cgi_heads_max_size,0, + sizeof(void*)*(CGI_HEADS_BLOCK_SIZE)); + session->req.cgi_heads_max_size+=CGI_HEADS_BLOCK_SIZE; + } else { + lprintf("%04d Cannot enlarge headroom",session->socket); + } + return; +} + +static void add_head(http_session_t *session, const char *value) { + if(value==NULL) { + lprintf("%04d Attempt to set NULL header", session->socket); + return; + } + + if(session->req.cgi_heads_size==session->req.cgi_heads_max_size-1) + grow_heads(session); + + if(session->req.cgi_heads_size<session->req.cgi_heads_max_size) { + session->req.cgi_heads[session->req.cgi_heads_size]= + malloc(sizeof(char)*(strlen(value))); + if(session->req.cgi_heads[session->req.cgi_heads_size] != NULL) { + sprintf(session->req.cgi_heads[session->req.cgi_heads_size++],"%s",value); + session->req.cgi_heads[session->req.cgi_heads_size]=NULL; + lprintf("%04d Added header: %s",session->socket,value); + } + } +} + +static void init_heads(http_session_t *session) { + session->req.cgi_heads=malloc(sizeof(void*)*CGI_HEADS_BLOCK_SIZE); + if(session->req.cgi_heads != NULL) { + memset(session->req.cgi_heads,0,sizeof(void*)*CGI_HEADS_BLOCK_SIZE); + session->req.cgi_heads_max_size=CGI_HEADS_BLOCK_SIZE; + } else { + lprintf("%04d Cannot create headers",session->socket); + session->req.cgi_heads_max_size=0; + } + return; +} + +static BOOL is_cgi(http_session_t *session) { + +#ifdef __unix__ + /* NOTE: (From the FreeBSD man page) + "Access() is a potential security hole and should never be used." */ + if(!access(session->req.request,X_OK)) + return(TRUE); +#endif + return(FALSE); +} + static int sockprintf(SOCKET sock, char *fmt, ...) { int len; @@ -467,6 +623,29 @@ static int close_socket(SOCKET sock) static void close_request(http_session_t * session) { + int i; + + + if(session->req.cgi_heads_size) { + for(i=0;session->req.cgi_heads_size>i;i++) { + lprintf("%04d Freeing header: %s",session->socket,session->req.cgi_heads[i]); + free(session->req.cgi_heads[i]); + } + lprintf("%04d Freeing header array",session->socket); + free(session->req.cgi_heads); + session->req.cgi_heads_size=0; + } + + if(session->req.cgi_env_size) { + for(i=0;i<session->req.cgi_env_size;i++) { + free(session->req.cgi_env[i]); + lprintf("%04d Freeing the environment %s",session->socket,session->req.cgi_env[i]); + } + lprintf("%04d Freeing the environment array",session->socket); + free(session->req.cgi_env); + session->req.cgi_env_size=0; + } + if(!session->req.keep_alive) { close_socket(session->socket); session->socket=INVALID_SOCKET; @@ -532,12 +711,18 @@ BOOL send_headers(http_session_t *session, const char *status) send_file=FALSE; lprintf("%04d Not modified",session->socket); } - if(session->req.send_location) { + if(session->req.send_location==MOVED_PERM) { SAFECOPY(status_line,"301 Moved Permanently"); ret=-1; send_file=FALSE; lprintf("%04d Moved Permanently",session->socket); } + if(session->req.send_location==MOVED_TEMP) { + SAFECOPY(status_line,"302 Moved Temporarily"); + ret=-1; + send_file=FALSE; + lprintf("%04d Moved Temporarily",session->socket); + } /* Status-Line */ sockprintf(session->socket,"%s %s",http_vers[session->http_ver],status_line); @@ -556,10 +741,13 @@ BOOL send_headers(http_session_t *session, const char *status) /* Should be dynamic to allow POST for CGIs */ sockprintf(session->socket,"%s: %s",get_header(HEAD_ALLOW),"GET, HEAD"); if(session->req.send_location) { - location_offset=strlen(root_dir); - if(session->host[0]) - location_offset+=strlen(session->host)+1; - sockprintf(session->socket,"%s: %s",get_header(HEAD_LOCATION),session->req.request+location_offset); + if(*session->req.request=='/') { + location_offset=strlen(root_dir); + if(session->req.host[0]) + location_offset+=strlen(session->req.host)+1; + sockprintf(session->socket,"%s: %s",get_header(HEAD_LOCATION),session->req.request+location_offset); + } else + sockprintf(session->socket,"%s: %s",get_header(HEAD_LOCATION),session->req.request); } if(!ret) { sockprintf(session->socket,"%s: %d",get_header(HEAD_LENGTH),stats.st_size); @@ -599,7 +787,7 @@ static void send_error(http_session_t * session, char *message) char error_code[4]; lprintf("%04d !ERROR %s",session->socket,message); - session->req.send_location=FALSE; + session->req.send_location=NO_LOCATION; SAFECOPY(error_code,message); sprintf(session->req.request,"%s%s.html",error_dir,error_code); if(session->http_ver > HTTP_0_9) @@ -654,8 +842,12 @@ static BOOL check_ars(http_session_t * session) if(ar!=NULL && ar!=nular) free(ar); - if(authorized) + if(authorized) { + add_env(session,"AUTH_TYPE","Basic"); + /* Should use name if set to do so somewhere ToDo */ + add_env(session,"REMOTE_USER",user.alias); return(TRUE); + } /* Should go to the hack log? */ lprintf("%04d !AUTHORIZATION FAILURE for user %s, ARS: %s" @@ -738,14 +930,16 @@ static int sockreadline(http_session_t * session, char *buf, size_t length) start=time(NULL); for(i=0;TRUE;) { if(!socket_check(session->socket,&rd)) { - close_socket(session->socket); + session->req.keep_alive=FALSE; + close_request(session); session->socket=INVALID_SOCKET; return(-1); } if(!rd) { if(time(NULL)-start>startup->max_inactivity) { - close_socket(session->socket); + session->req.keep_alive=FALSE; + close_request(session); session->socket=INVALID_SOCKET; return(-1); /* time-out */ } @@ -784,6 +978,10 @@ static BOOL parse_headers(http_session_t * session) char *value; char *p; int i; + int content_len=0; + char cgi_infilename[128]; + char env_name[128]; + FILE* fp; lprintf("%04d Parsing headers",session->socket); while(!sockreadline(session,req_line,sizeof(req_line))&&strlen(req_line)) { @@ -811,10 +1009,11 @@ static BOOL parse_headers(http_session_t * session) /* Not implemented - POST */ break; case HEAD_LENGTH: - /* Not implemented - POST */ + add_env(session,"CONTENT_LENGTH",value); + content_len=atoi(value); break; case HEAD_TYPE: - /* Not implemented - POST */ + add_env(session,"CONTENT_TYPE",value); break; case HEAD_DATE: /* Not implemented - Who really cares what time the client thinks it is? */ @@ -837,8 +1036,8 @@ static BOOL parse_headers(http_session_t * session) } break; case HEAD_HOST: - if(session->host[0]==0) { - SAFECOPY(session->host,value); + if(session->req.host[0]==0) { + SAFECOPY(session->req.host,value); lprintf("%04d Grabbing from virtual host: %s" ,session->socket,value); } @@ -846,8 +1045,29 @@ static BOOL parse_headers(http_session_t * session) /* Should store for HTTP_* env variables in CGI */ break; } + sprintf(env_name,"HTTP_%s",req_line); + add_env(session,env_name,value); } } + sprintf(cgi_infilename,"%s/SBBSCGI.%d",startup->cgi_temp_dir,session->socket); + lprintf("%04d Creating input file %s",session->socket,cgi_infilename); + if((fp=fopen(cgi_infilename,"w"))!=NULL) { + lprintf("%04d Created input file %s",session->socket,cgi_infilename); + if(content_len) { + p=malloc(content_len); + if(p!=NULL) { + read(session->socket,p,content_len); + fwrite(p,content_len,1,fp); + lprintf("%04d Freeing input buffer"); + free(p); + } + } + fclose(fp); + SAFECOPY(session->req.cgi_infile,cgi_infilename); + } else { + lprintf("%04d FAILED! Creating input file",session->socket); + } + add_env(session,"SERVER_NAME",session->req.host[0] ? session->req.host : startup->host_name ); lprintf("%04d Done parsing headers",session->socket); return TRUE; } @@ -899,15 +1119,18 @@ static char *get_request(http_session_t * session, char *req_line) SAFECOPY(session->req.request,req_line); strtok(session->req.request," \t"); retval=strtok(NULL," \t"); + strtok(session->req.request,"?"); + p=strtok(NULL,""); + add_env(session,"QUERY_STRING",p); unescape(session->req.request); if(!strnicmp(session->req.request,"http://",7)) { /* Set HOST value... ignore HOST header */ - SAFECOPY(session->host,session->req.request+7); + SAFECOPY(session->req.host,session->req.request+7); strtok(session->req.request,"/"); p=strtok(NULL,"/"); if(p==NULL) { /* Do not allow host values larger than 128 bytes just to be anal */ - session->host[0]=0; + session->req.host[0]=0; p=session->req.request+7; } offset=p-session->req.request; @@ -928,6 +1151,7 @@ static char *get_method(http_session_t * session, char *req_line) send_error(session,"400 Bad Request"); return(NULL); } + add_env(session,"REQUEST_METHOD",methods[i]); return(req_line+strlen(methods[i])+1); } } @@ -950,6 +1174,8 @@ static BOOL get_req(http_session_t * session) lprintf("%04d Request: %s" ,session->socket,session->req.request); session->http_ver=get_version(p); + add_env(session,"SERVER_PROTOCOL",session->http_ver ? + http_vers[session->http_ver] : "HTTP/0.9"); lprintf("%04d Version: %s" ,session->socket,http_vers[session->http_ver]); return(TRUE); @@ -965,16 +1191,17 @@ static BOOL check_request(http_session_t * session) char str[MAX_PATH+1]; char last_ch; char* last_slash; + int location_offset; FILE* file; lprintf("%04d Validating request: %s" ,session->socket,session->req.request); if(!(startup->options&WEB_OPT_VIRTUAL_HOSTS)) - session->host[0]=0; - if(session->host[0]) { - sprintf(path,"%s%s",root_dir,session->host); + session->req.host[0]=0; + if(session->req.host[0]) { + sprintf(path,"%s%s",root_dir,session->req.host); if(isdir(path)) - sprintf(path,"%s%s%s",root_dir,session->host,session->req.request); + sprintf(path,"%s%s%s",root_dir,session->req.host,session->req.request); } else sprintf(path,"%s%s",root_dir,session->req.request); @@ -988,7 +1215,7 @@ static BOOL check_request(http_session_t * session) if(last_ch!='/' && last_ch!='\\') strcat(path,"/"); strcat(path,startup->index_file_name); - session->req.send_location=TRUE; + session->req.send_location=MOVED_PERM; } if(strnicmp(path,root_dir,strlen(root_dir))) { lprintf("%04d path = '%s'",session->socket,path); @@ -1002,6 +1229,10 @@ static BOOL check_request(http_session_t * session) return(FALSE); } SAFECOPY(session->req.request,path); + add_env(session,"PATH_TRANSLATED",path); + location_offset=strlen(root_dir); + location_offset+=strlen(session->req.host); + add_env(session,"SCRIPT_NAME",session->req.request+location_offset); /* Set default ARS to a 0-length string */ session->req.ars[0]=0; @@ -1045,10 +1276,211 @@ static BOOL check_request(http_session_t * session) return(TRUE); } +static BOOL parse_cgi_headers(http_session_t *session,FILE *output) { + char str[MAX_REQUEST_LINE]; + char header[MAX_REQUEST_LINE]; + char *directive; + char *value; + int i; + + if(fgets(str,MAX_REQUEST_LINE,output)==NULL) + str[0]=0; + truncsp(str); + while(str[0]) { + SAFECOPY(header,str); + directive=strtok(header,":"); + if(directive != NULL) { + value=strtok(NULL,""); + i=get_header_type(directive); + switch (i) { + case HEAD_TYPE: + add_head(session,str); + break; + case HEAD_LOCATION: + SAFECOPY(session->req.cgi_location,value); + if(*value=='/') { + unescape(value); + SAFECOPY(session->req.request,value); + if(check_request(session)) { + respond(session); + } + } else { + SAFECOPY(session->req.request,value); + session->req.send_location=MOVED_TEMP; + send_headers(session,"302 Moved Temporarily"); + } + return(FALSE); + case HEAD_STATUS: + SAFECOPY(session->req.cgi_status,value); + break; + default: + add_head(session,str); + } + } + if(fgets(str,MAX_REQUEST_LINE,output)==NULL) + str[0]=0; + truncsp(str); + } + lprintf("%04d Done with da headers",session->socket); + return(TRUE); +} + +static void send_cgi_response(http_session_t *session,FILE *output) { + int i; + long filepos; + char * content; + struct stat stats; + time_t ti; + struct tm *t; + + init_heads(session); + /* Support nph-* scripts ToDo */ + if(!parse_cgi_headers(session,output)) + return; + + lprintf("%04d STILL with da headers",session->socket); + filepos=ftell(output); + fstat(fileno(output),&stats); + lprintf("%04d Sending CGI response",session->socket); + if(session->http_ver) { + if(*session->req.cgi_status) + sockprintf(session->socket,"%s %s",http_vers[session->http_ver],session->req.cgi_status); + else + sockprintf(session->socket,"%s %s",http_vers[session->http_ver],"200 Ok"); + + /* General Headers */ + ti=time(NULL); + t=gmtime(&ti); + sockprintf(session->socket,"%s: %s, %02d %s %04d %02d:%02d:%02d GMT",get_header(HEAD_DATE),days[t->tm_wday],t->tm_mday,months[t->tm_mon],t->tm_year+1900,t->tm_hour,t->tm_min,t->tm_sec); + if(session->req.keep_alive) + sockprintf(session->socket,"%s: %s",get_header(HEAD_CONNECTION),"Keep-Alive"); + + /* Response Headers */ + sockprintf(session->socket,"%s: %s",get_header(HEAD_SERVER),VERSION_NOTICE); + + /* Entity Headers */ + sockprintf(session->socket,"%s: %s",get_header(HEAD_ALLOW),"GET, HEAD, POST"); + sockprintf(session->socket,"%s: %d",get_header(HEAD_LENGTH),stats.st_size-filepos+1); + + /* CGI-generated headers */ + for(i=0;session->req.cgi_heads[i]!=NULL;i++) { + sockprintf(session->socket,"%s",session->req.cgi_heads[i]); + lprintf("%04d Sending header: %s",session->req.cgi_heads[i]); + } + + sendsocket(session->socket,newline,2); + } + for(i=0;session->req.cgi_heads_size>i;i++) { + lprintf("%04d Freeing header: %s",session->socket,session->req.cgi_heads[i]); + free(session->req.cgi_heads[i]); + } + lprintf("%04d Freeing header array",session->socket); + free(session->req.cgi_heads); + session->req.cgi_heads_size=0; + + content=malloc(stats.st_size-filepos+1); + if(content!=NULL) { + fread(content,stats.st_size-filepos+1,1,output); + write(session->socket,content,stats.st_size-filepos+1); + lprintf("%04d Freeing reply content",session->socket); + free(content); + } +} + +static BOOL exec_cgi(http_session_t *session) +{ + int status; + char cmdline[MAX_PATH+256]; + char *args[4]; + int i; + char *comspec; + FILE *output; +#ifdef __unix__ + pid_t child; +#endif + + SAFECOPY(cmdline,session->req.request); + sprintf(cmdline,"%s < %s > %s.out",session->req.request,session->req.cgi_infile,session->req.cgi_infile); + sprintf(session->req.request,"%s.out",session->req.cgi_infile); + + comspec=getenv( +#ifdef __unix__ + "SHELL" +#else + "COMSPEC" +#endif + ); + if(comspec==NULL) { + lprintf("%04d Could not get comspec",session->socket); + return(FALSE); + } + + args[0]=comspec; + args[1]="-c"; + args[2]=cmdline; + args[3]=NULL; + +#ifdef __unix__ + + lprintf("Executing %s -c %s",comspec,cmdline); + session->req.cgi_env[session->req.cgi_env_size]=NULL; + if((child=fork())==0) { + execve(comspec,args,session->req.cgi_env); + lprintf("FAILED! execve()"); + exit(EXIT_FAILURE); /* Should never happen */ + } + /* Free() the environment */ + for(i=0;i<session->req.cgi_env_size;i++) { + free(session->req.cgi_env[i]); + lprintf("%04d Freeing the environment %s",session->socket,session->req.cgi_env[i]); + } + lprintf("%04d Freeing the environment array",session->socket); + free(session->req.cgi_env); + session->req.cgi_env_size=0; + + if(child>0) { + waitpid(child,&status,0); + lprintf("%04d Child exited",session->socket); + unlink(session->req.cgi_infile); + if(WIFEXITED(status)) { + /* Parse headers */ + output=fopen(session->req.request,"r"); + if(output!=NULL) { + lprintf("%04d Opened response file: %s",session->socket,session->req.request); + send_cgi_response(session,output); + lprintf("%04d Sent response file.",session->socket); + fclose(output); + unlink(session->req.request); + return(WEXITSTATUS(status)==EXIT_SUCCESS); + } + else { + lprintf("%04d FAILED! To open response file: %s",session->socket,session->req.request); + return(FALSE); + } + } + return(FALSE); + } + return(FALSE); +#else + sprintf(cmdline,"%s /C %s < %s > %s",comspec,cmdline,session->req.cgi_infile,session->req.request); + system(cmdline); + return(TRUE); +#endif +} + static void respond(http_session_t * session) { BOOL send_file=TRUE; + if(is_cgi(session)) { + if(!exec_cgi(session)) { + send_error(session,"500 Internal Server Error"); + return; + } + close_request(session); + return; + } + if(session->http_ver > HTTP_0_9) send_file=send_headers(session,"200 OK"); if(send_file) @@ -1058,7 +1490,6 @@ static void respond(http_session_t * session) void http_session_thread(void* arg) { - char host_ip[64]; char* host_name; HOSTENT* host; SOCKET socket; @@ -1083,12 +1514,15 @@ void http_session_thread(void* arg) else host_name="<no name>"; - if(!(startup->options&BBS_OPT_NO_HOST_LOOKUP)) + if(!(startup->options&BBS_OPT_NO_HOST_LOOKUP)) { lprintf("%04d Hostname: %s", session.socket, host_name); + SAFECOPY(session.host_name,host_name); + } - if(trashcan(&scfg,host_ip,"ip")) { + /* host_ip wasn't defined in http_session_thread */ + if(trashcan(&scfg,session.host_ip,"ip")) { close_socket(session.socket); - lprintf("%04d !CLIENT BLOCKED in ip.can: %s", session.socket, host_ip); + lprintf("%04d !CLIENT BLOCKED in ip.can: %s", session.socket, session.host_ip); thread_down(); return; } @@ -1105,6 +1539,7 @@ void http_session_thread(void* arg) while(!session.finished && server_socket!=INVALID_SOCKET) { memset(&(session.req), 0, sizeof(session.req)); + init_enviro(&session); if(get_req(&session)) { lprintf("%04d Got request %s method %d version %d" ,session.socket @@ -1199,7 +1634,6 @@ void DLLCALL web_server(void* arg) time_t t; time_t initialized=0; char* p; - char host_ip[32]; char compiler[32]; http_session_t * session; struct timeval tv; @@ -1421,12 +1855,11 @@ void DLLCALL web_server(void* arg) break; } - strcpy(host_ip,inet_ntoa(client_addr.sin_addr)); host_port=ntohs(client_addr.sin_port); lprintf("%04d HTTP connection accepted from: %s port %u" ,client_socket - ,host_ip, host_port); + ,inet_ntoa(client_addr.sin_addr), host_port); if(startup->socket_open!=NULL) startup->socket_open(TRUE); @@ -1440,6 +1873,7 @@ void DLLCALL web_server(void* arg) } memset(session, 0, sizeof(http_session_t)); + SAFECOPY(session->host_ip,inet_ntoa(client_addr.sin_addr)); session->addr=client_addr; session->socket=client_socket;