/* respond fdo_virtual_responce(filename)or a file GET request */ int do_http_get(struct tcp_pcb *pcb, char *req, int rlen) { int BUFSIZE = 1400; char filename[MAX_FILENAME]; /* unsigned char buf[BUFSIZE]; signed int fsize, hlen, n; int fd; char *fext; err_t err; / * determine file name */ extract_file_name(filename, req, rlen, MAX_FILENAME); if(filename[0]== 'a') //we have a virtual action so parse it { return do_virtual_responce(pcb,filename); } /* respond with 404 if not present * / if (mfs_exists_file(filename) != 1) { */ xil_printf("requested file %s not found, returning 404\r\n", filename); do_404(pcb, req, rlen); return -1; // } return 0; }
void process_rq(char* rq , int fd) { char cmd[BUFSIZ] , arg[BUFSIZ] ; if(fork() != 0) return ; strcpy(arg , "./"); if(sscanf(rq , "%s %s" , cmd , arg+2) != 2) return ; if(strcmp(cmd , "GET") != 0) { if(strcmp(cmd , "HEAD") != 0) cannot_do(fd); else if(not_exist(arg)) do_404(arg , fd); else { if(isadir(arg)) { strcat(arg , "index.html"); printf("modified arg : %s\n" ,arg); if(not_exist(arg)) do_404(arg , fd); } do_process_head(arg , fd); } } else if(not_exist(arg)) do_404(arg , fd); else if(isadir(arg)) do_ls(arg , fd); else if(ends_in_cgi(arg)) do_exec(arg ,fd); else do_cat(arg , fd); }
/* generate and write out an appropriate response for the http request */ int generate_response(int sd, char *http_req, int http_req_len) { enum http_req_type request_type = decode_http_request(http_req, http_req_len); switch(request_type) { case HTTP_GET: return do_http_get(sd, http_req, http_req_len); case HTTP_POST: return do_http_post(sd, http_req, http_req_len); default: return do_404(sd, http_req, http_req_len); } }
void dispatcher(Request *req, char *result) { if ( strcmp(req->http_verb,"GET") != 0 ) { logger_info("Do not implement this operation yet\n"); do_501(result); } else if (not_exist(req->path)) { printf("Can't find request path %s\n", req->path); do_404(req->path, result); } else { printf("Find request path %s\n", req->path); do_cat_file(req->path, result); } }
/* this assumes that tcp_sndbuf is high enough to send atleast 1 packet */ int generate_response(struct tcp_pcb *pcb, char *http_req, int http_req_len) { enum http_req_type request_type = decode_http_request(http_req, http_req_len); switch(request_type) { case HTTP_GET: return do_http_get(pcb, http_req, http_req_len); case HTTP_POST: return do_http_post(pcb, http_req, http_req_len); default: xil_printf("request_type != GET|POST\r\n"); dump_payload(http_req, http_req_len); return do_404(pcb, http_req, http_req_len); } }
extern void process_rq(char *request, int sock_fd) { char cmd[BUFSIZ], arg[BUFSIZ]; strcpy(arg, "./"); sscanf(request, "%s %s", cmd, arg + 2); if (fork() != 0) return ; if (strcmp(cmd, "GET") != 0) { cannot_do(sock_fd); } else if (not_exist(arg)) { do_404(arg, sock_fd); } else if (is_dir(arg)) { do_ls(arg, sock_fd); } else if (ends_in_cgi(arg)) { do_exec(arg, sock_fd); } else { do_cat(arg, sock_fd); } }
/* ------------------------------------------------------ * process_rq( char *rq, int fd ) do what the request asks for and write reply to fd handles request in a new process rq is HTTP command: GET /foo/bar.html HTTP/1.0 ------------------------------------------------------ */ process_rq( char *rq, int fd) { char cmd[BUFSIZ], arg[BUFSIZ]; if ( sscanf(rq, "%s%s", cmd, arg) != 2 ) return; sanitize(arg); printf("sanitized version is %s\n", arg); if ( strcmp(cmd,"GET") != 0 ) not_implemented(); else if ( built_in(arg, fd) ) ; else if ( not_exist( arg ) ) do_404(arg, fd); else if ( isadir( arg ) ) do_ls( arg, fd ); else do_cat( arg, fd ); }
void process_rq(char *rq, int fd) { char cmd[BUFSIZ], arg[BUFSIZ]; if (fork() != 0) return; strcpy(arg, "./"); if (sscanf(rq, "%s%s", cmd, arg+2) != 2) return; if (strcmp(cmd, "GET") != 0) cannot_do(fd); else if (not_exist(arg)) do_404(arg, fd); else if (isadir(arg)) do_ls(arg, fd); else if (ends_in_cgi(arg)) do_exec(arg, fd); else do_cat(arg, fd); }
process_rq( char *rq, int fd ) { char cmd[BUFSIZ], arg[BUFSIZ]; /* create a new process and return if not the child */ if ( fork() != 0 ) return; strcpy(arg, "./"); /* precede args with ./ */ if ( sscanf(rq, "%s%s", cmd, arg+2) != 2 ) return; if ( strcmp(cmd,"GET") != 0 ) cannot_do(fd); else if ( not_exist( arg ) ) do_404(arg, fd ); else if ( isadir( arg ) ) do_ls( arg, fd ); else if ( ends_in_cgi( arg ) ) do_exec( arg, fd ); else do_cat( arg, fd ); }
/* respond for a file GET request */ int do_http_get(struct tcp_pcb *pcb, char *req, int rlen) { int BUFSIZE = 1400; char filename[MAX_FILENAME]; char buf[BUFSIZE]; int fsize, hlen, n; int fd; char *fext; err_t err; /* determine file name */ extract_file_name(filename, req, rlen, MAX_FILENAME); /* respond with 404 if not present */ if (mfs_exists_file(filename) != 1) { xil_printf("requested file %s not found, returning 404\r\n", filename); do_404(pcb, req, rlen); return -1; } /* respond with correct file */ /* debug statement on UART */ xil_printf("http GET: %s\r\n", filename); /* get a pointer to file extension */ fext = get_file_extension(filename); fd = mfs_file_open(filename, MFS_MODE_READ); /* obtain file size, * note that lseek with offset 0, MFS_SEEK_END does not move file pointer */ fsize = mfs_file_lseek(fd, 0, MFS_SEEK_END); /* write the http headers */ hlen = generate_http_header(buf, fext, fsize); if ((err = tcp_write(pcb, buf, hlen, 1)) != ERR_OK) { xil_printf("error (%d) writing http header to socket\r\n", err); xil_printf("attempted to write #bytes = %d, tcp_sndbuf = %d\r\n", hlen, tcp_sndbuf(pcb)); xil_printf("http header = %s\r\n", buf); return -1; } /* now write the file */ while (fsize) { int sndbuf; sndbuf = tcp_sndbuf(pcb); if (sndbuf < BUFSIZE) { /* not enough space in sndbuf, so send remaining bytes when there is space */ /* this is done by storing the fd in as part of the tcp_arg, so that the sent callback handler knows to send data */ http_arg *a = (http_arg *)pcb->callback_arg; a->fd = fd; a->fsize = fsize; return 0; } n = mfs_file_read(fd, buf, BUFSIZE); if ((err = tcp_write(pcb, buf, n, 1)) != ERR_OK) { xil_printf("error writing file (%s) to socket, remaining unwritten bytes = %d\r\n", filename, fsize - n); xil_printf("attempted to lwip_write %d bytes, tcp write error = %d\r\n", n, err); break; } fsize -= n; } mfs_file_close(fd); return 0; }
/* * handle one request * * This loop gets called once for every HTTP connection made to WebCit. At * this entry point we have an HTTP socket with a browser allegedly on the * other end, but we have not yet bound to a WebCit session. * * The job of this function is to locate the correct session and bind to it, * or create a session if necessary and bind to it, then run the WebCit * transaction loop. Afterwards, we unbind from the session. When this * function returns, the worker thread is then free to handle another * transaction. */ void context_loop(ParsedHttpHdrs *Hdr) { int isbogus = 0; wcsession *TheSession; struct timeval tx_start; struct timeval tx_finish; int session_may_be_reused = 1; time_t now; gettimeofday(&tx_start, NULL); /* start a stopwatch for performance timing */ /* * Find out what it is that the web browser is asking for */ isbogus = ReadHTTPRequest(Hdr); Hdr->HR.dav_depth = 32767; /* TODO: find a general way to have non-0 defaults */ if (!isbogus) { isbogus = AnalyseHeaders(Hdr); } if ( (isbogus) || ((Hdr->HR.Handler != NULL) && ((Hdr->HR.Handler->Flags & BOGUS) != 0)) ) { wcsession *Bogus; Bogus = CreateSession(0, 1, NULL, Hdr, NULL); do_404(); syslog(LOG_WARNING, "HTTP: 404 [%ld.%06ld] %s %s", ((tx_finish.tv_sec*1000000 + tx_finish.tv_usec) - (tx_start.tv_sec*1000000 + tx_start.tv_usec)) / 1000000, ((tx_finish.tv_sec*1000000 + tx_finish.tv_usec) - (tx_start.tv_sec*1000000 + tx_start.tv_usec)) % 1000000, ReqStrs[Hdr->HR.eReqType], ChrPtr(Hdr->this_page) ); session_detach_modules(Bogus); session_destroy_modules(&Bogus); return; } if ((Hdr->HR.Handler != NULL) && ((Hdr->HR.Handler->Flags & ISSTATIC) != 0)) { wcsession *Static; Static = CreateSession(0, 1, NULL, Hdr, NULL); Hdr->HR.Handler->F(); /* How long did this transaction take? */ gettimeofday(&tx_finish, NULL); if (verbose) syslog(LOG_DEBUG, "HTTP: 200 [%ld.%06ld] %s %s", ((tx_finish.tv_sec*1000000 + tx_finish.tv_usec) - (tx_start.tv_sec*1000000 + tx_start.tv_usec)) / 1000000, ((tx_finish.tv_sec*1000000 + tx_finish.tv_usec) - (tx_start.tv_sec*1000000 + tx_start.tv_usec)) % 1000000, ReqStrs[Hdr->HR.eReqType], ChrPtr(Hdr->this_page) ); session_detach_modules(Static); session_destroy_modules(&Static); return; } if (Hdr->HR.got_auth == AUTH_BASIC) { CheckAuthBasic(Hdr); } if (Hdr->HR.got_auth) { session_may_be_reused = 0; } /* * See if there's an existing session open with any of: * - The desired Session ID * - A matching http-auth username and password * - An unbound session flagged as reusable */ TheSession = FindSession(&SessionList, Hdr, &SessionListMutex); /* * If there were no qualifying sessions, then create a new one. */ if ((TheSession == NULL) || (TheSession->killthis != 0)) { TheSession = CreateSession(1, 0, &SessionList, Hdr, &SessionListMutex); } /* * Reject transactions which require http-auth, if http-auth was not provided */ if ( (StrLength(Hdr->c_username) == 0) && (!Hdr->HR.DontNeedAuth) && (Hdr->HR.Handler != NULL) && ((XHTTP_COMMANDS & Hdr->HR.Handler->Flags) == XHTTP_COMMANDS) ) { syslog(LOG_DEBUG, "http-auth required but not provided"); OverrideRequest(Hdr, HKEY("GET /401 HTTP/1.0")); Hdr->HR.prohibit_caching = 1; } /* * A future improvement might be to check the session integrity * at this point before continuing. */ /* * Bind to the session and perform the transaction */ now = time(NULL);; CtdlLogResult(pthread_mutex_lock(&TheSession->SessionMutex)); pthread_setspecific(MyConKey, (void *)TheSession); TheSession->inuse = 1; /* mark the session as bound */ TheSession->lastreq = now; /* log */ TheSession->Hdr = Hdr; /* * If a language was requested via a cookie, select that language now. */ if (StrLength(Hdr->c_language) > 0) { if (verbose) syslog(LOG_DEBUG, "Session cookie requests language '%s'", ChrPtr(Hdr->c_language)); set_selected_language(ChrPtr(Hdr->c_language)); go_selected_language(); } /* * do the transaction */ session_attach_modules(TheSession); session_loop(); /* How long did this transaction take? */ gettimeofday(&tx_finish, NULL); if (verbose || strstr(ChrPtr(Hdr->this_page), "sslg") == NULL) { syslog(LOG_INFO, "HTTP: 200 [%ld.%06ld] %s %s", ((tx_finish.tv_sec*1000000 + tx_finish.tv_usec) - (tx_start.tv_sec*1000000 + tx_start.tv_usec)) / 1000000, ((tx_finish.tv_sec*1000000 + tx_finish.tv_usec) - (tx_start.tv_sec*1000000 + tx_start.tv_usec)) % 1000000, ReqStrs[Hdr->HR.eReqType], ChrPtr(Hdr->this_page) ); } session_detach_modules(TheSession); /* If *this* very transaction did not explicitly specify a session cookie, * and it did not log in, we want to flag the session as a candidate for * re-use by the next unbound client that comes along. This keeps our session * table from getting bombarded with new sessions when, for example, a web * spider crawls the site without using cookies. */ if ((session_may_be_reused) && (!TheSession->logged_in)) { TheSession->wc_session = 0; /* flag as available for re-use */ TheSession->selected_language = -1; /* clear any non-default language setting */ } TheSession->Hdr = NULL; TheSession->inuse = 0; /* mark the session as unbound */ CtdlLogResult(pthread_mutex_unlock(&TheSession->SessionMutex)); }