void serve_file(dict_epoll_data *ptr, char *uri) { struct stat sbuf; int conn_sock = ptr->sock_fd; int ffd = open(uri, O_RDONLY); #ifdef DEBUG printf("sock_fd: %d, openfile: %s, fd: %d\n", ptr->sock_fd, uri, ffd); #endif if(ffd <= 0) { perror(uri); char *msg = "File not found"; client_error(conn_sock, 404, "Not found", msg); } else { fstat(ffd, &sbuf); if(S_ISREG(sbuf.st_mode)) { ptr->static_fd = ffd; ptr->file_offset = 0; ptr->file_cnt = sbuf.st_size; serve_static(ptr, uri, sbuf.st_size); // will close ffd } else if(S_ISDIR(sbuf.st_mode)) { char *msg = "Dir listing is not impleted"; client_error(conn_sock, 404, "Error", msg); close(ffd); } else { char *msg = "Unknow Error"; client_error(conn_sock, 400, "Error", msg); close(ffd); } } }
void do_get(int fd, char * uri) { int is_static; struct stat sbuf; char filename[MAXLINE], cgiargs[MAXLINE]; //read_request_headers(fd); /* 读取并忽略headers */ /* 从GET request 中解析 URI */ is_static = parse_uri(uri, filename, cgiargs); if (is_static) { printf("request filename: %s\n",filename); if (stat(filename, &sbuf) < 0) { send_error(fd, filename, "404", "Not Found"); return; } if (!(S_ISREG(sbuf.st_mode)) || !(S_IRUSR & sbuf.st_mode)) { send_error(fd, filename, "403", "Forbidden"); return; } serve_static(fd, filename, sbuf.st_size); } else { serve_wsgi(fd, uri); } close(fd); return; }
/** * Index route, serves a static file and handles a redirect. */ void route_index(evhtp_request_t *req, void *arg) { evhtp_uri_t *uri = req->uri; evhtp_query_t *query = uri->query; const char *parq = evhtp_kv_find(query, "q"); const char *pars = evhtp_kv_find(query, "s"); const char *parm = evhtp_kv_find(query, "m"); if (parq) { char *m = malloc(sizeof (char)*64); char *tmp = makelower(parq, strlen(parq)); char *md = md5((const char *) tmp, strlen(parq)); free(tmp); if (parm) { sprintf(m, "/meta/%s", md); } else if (pars) { sprintf(m, "/%s/%d", md, atoi(pars)); } else { sprintf(m, "/%s", md); } free(md); evhtp_headers_add_header(req->headers_out, evhtp_header_new("Location", m, 0, 1)); free(m); evhtp_send_reply(req, 301); } else { serve_static(req, "static/index.html", "text/html"); } }
void parse_request(request_b *rb) { int is_static; struct stat sbuf; char line[MAXLINE], method[MAXLINE], uri[MAXLINE], version[MAXLINE]; char filename[MAXLINE], cgiargs[MAXLINE]; int is_head = 0; if (verbose) { printf("the rb->buf start and end:%zu %zu\n", rb->pos, rb->last); } getlinefrombuf(rb, line); sscanf(line, "%s %s %s", method, uri, version); if (verbose) { printf("the firstline of request\n%s", line); } if (!strcasecmp(method, "GET")) { // read_requesthdrs(rb); is_static = parse_uri(uri, filename, cgiargs); } else if (!strcasecmp(method, "HEAD")) { read_requesthdrs(rb); is_static = parse_uri(uri, filename, cgiargs); is_head = 1; } else if (!strcasecmp(method, "POST")) { parse_post_request(rb, cgiargs, uri, filename); is_static = 0; // always dynamic follow by parse_uri printf("cgiargs parameter is %s\n", cgiargs); } else { clienterror(rb->fd, method, "501", "Not Implemented", "Tiny does not implement this method"); return; } if (stat(filename, &sbuf) < 0) { clienterror(rb->fd, filename, "404", "Not found", "Tiny couldn't find this file"); return; } if (is_static) { /* Serve static content */ if (!(S_ISREG(sbuf.st_mode)) || !(S_IRUSR & sbuf.st_mode)) { clienterror(rb->fd, filename, "403", "Forbidden", "Tiny couldn't read the file"); return; } serve_static(rb->fd, filename, sbuf.st_size, is_head); } else { /* Serve dynamic content */ if (!(S_ISREG(sbuf.st_mode)) || !(S_IXUSR & sbuf.st_mode)) { // line:netp:doit:executable clienterror(rb->fd, filename, "403", "Forbidden", "Tiny couldn't run the CGI program"); return; } serve_dynamic(rb->fd, filename, cgiargs, is_head); // line:netp:doit:servedynamic } }
/* $begin doit */ void * doit( void * fd_ptr) { int fd = * (int *)fd_ptr; printf("\nFile Desc = %d", fd); int is_static; struct stat sbuf; char buf[MAXLINE], method[MAXLINE], uri[MAXLINE], version[MAXLINE]; char filename[MAXLINE], cgiargs[MAXLINE]; rio_t rio; /* Read request line and headers */ Rio_readinitb(&rio, fd); if (!Rio_readlineb(&rio, buf, MAXLINE)) { //line:netp:doit:readrequest { pthread_exit(NULL); return NULL; } printf("%s", buf); sscanf(buf, "%s %s %s", method, uri, version); //line:netp:doit:parserequest if (strcasecmp(method, "GET")) { //line:netp:doit:beginrequesterr clienterror(fd, method, "501", "Not Implemented", "Tiny does not implement this method"); pthread_exit(NULL); return NULL; } //line:netp:doit:endrequesterr read_requesthdrs(&rio); //line:netp:doit:readrequesthdrs /* Parse URI from GET request */ is_static = parse_uri(uri, filename, cgiargs); //line:netp:doit:staticcheck if (stat(filename, &sbuf) < 0) { //line:netp:doit:beginnotfound clienterror(fd, filename, "404", "Not found", "Tiny couldn't find this file"); pthread_exit(NULL); return NULL; } //line:netp:doit:endnotfound if (is_static) { /* Serve static content */ if (!(S_ISREG(sbuf.st_mode)) || !(S_IRUSR & sbuf.st_mode)) { //line:netp:doit:readable clienterror(fd, filename, "403", "Forbidden", "Tiny couldn't read the file"); pthread_exit(NULL); return NULL; } serve_static(fd, filename, sbuf.st_size); //line:netp:doit:servestatic } else { /* Serve eynamic content */ if (!(S_ISREG(sbuf.st_mode)) || !(S_IXUSR & sbuf.st_mode)) { //line:netp:doit:executable clienterror(fd, filename, "403", "Forbidden", "Tiny couldn't run the CGI program"); pthread_exit(NULL); return NULL; } serve_dynamic(fd, filename, cgiargs); //line:netp:doit:servedynamic } Close(fd); pthread_exit(NULL); return NULL; }
// 处理HTTP事务 void doit(int fd) { int is_static; struct stat sbuf; char buf[LINE_MAX], method[LINE_MAX], uri[LINE_MAX], version[LINE_MAX]; char filename[LINE_MAX], cgiargs[LINE_MAX]; // 读入请求行 readline(fd, buf, sizeof(buf)); sscanf(buf, "%s %s %s", method, uri, version); // 读入请求报头,简单打印到标准输出 while (readline(fd, buf, sizeof(buf))) { printf("%s", buf); if (strcmp(buf, "\r\n") == 0) break; } if (strcmp(method, "GET")) { client_error(fd, method, "501", "Impelementd", "minihttp does not impelement this method"); return; } is_static = parse_uri(uri, filename, cgiargs); if (stat(filename, &sbuf) < 0) { client_error(fd, filename, "404", "Not found", "miniftp couldn't find this file"); return; } if (is_static) /* Serve static content */ { if (!(S_ISREG(sbuf.st_mode)) || !(S_IRUSR & sbuf.st_mode)) { client_error(fd, filename, "403", "Forbidden", "minihttp couldn't read the file"); return; } serve_static(fd, filename, sbuf.st_size); } else /* Serve dynamic content */ { if (!(S_ISREG(sbuf.st_mode)) || !(S_IRUSR & sbuf.st_mode)) { client_error(fd, filename, "403", "Forbidden", "minihttp couldn't run the CGI program"); return; } serve_dynamic(fd, filename, cgiargs); } }
/** @brief Handles HTTP GET requests. * Reads and parses the request, the uri, and dispatches the appropriate * functions to serve content. * @param conn_fd The connection file descriptor. * @return none. */ void handle_request(int conn_fd) { rio_t rio; char request[MAXLINE], uri[MAXLINE]; char file_name[MAXLINE], cgi_args[MAXLINE]; int is_static; struct stat st_buf; Rio_readinitb(&rio, conn_fd); /* Read first header line of incoming request. */ if (rio_readlineb(&rio, request, MAXLINE) < 0) { dbg_printf("rio_readlineb error\n"); return; } dbg_printf("Request: %s", request); if (parse_request_header(conn_fd, request, uri) != SUCCESS) { return; } if (read_request_headers(&rio) != SUCCESS) { return; } find_file(uri, file_name, cgi_args, &is_static); if (stat(file_name, &st_buf) < 0) { dbg_printf("404: File not found: %s\n", file_name); send_error_msg(conn_fd, "404", "File not found"); return; } /* Handle static content */ if (is_static) { if (!(S_ISREG(st_buf.st_mode)) || !(S_IRUSR & st_buf.st_mode)) { dbg_printf("403: Can't read the file: %s\n", file_name); send_error_msg(conn_fd, "403", "Can't read the file."); return; } serve_static(conn_fd, file_name, st_buf.st_size); } /* Handle dynamic content */ else { if (!(S_ISREG(st_buf.st_mode)) || !(S_IXUSR & st_buf.st_mode)) { dbg_printf("403: Can't run the CGI program: %s\n", file_name); send_error_msg(conn_fd, "403", "Can't run the CGI program."); return; } serve_dynamic(conn_fd, file_name, cgi_args); } }
/* $begin ServeClient */ void ServeClient(int fd) { int is_static; struct stat sbuf; char buf[MAXLINE], method[MAXLINE], uri[MAXLINE], version[MAXLINE]; char filename[MAXLINE], cgiargs[MAXLINE]; rio_t rio; cgiargs[0] = 0; /* Read request line and headers */ Rio_readinitb(&rio, fd); Rio_readlineb(&rio, buf, MAXLINE); sscanf(buf, "%s %s %s", method, uri, version); if ( strcasecmp(method, "GET") == 0 ) { is_static = parse_uri(uri, filename, cgiargs); } else if ( strcasecmp(method, "POST") == 0 ) { is_static = parse_uri(uri, filename, cgiargs); } else { clienterror(fd, method, "501", "Not Implemented", "Server does not implement this method"); return; } if (stat(filename, &sbuf) < 0) { clienterror(fd, filename, "404", "Not found", "Tiny couldn't find this file"); return; } if (is_static) /* Serve static content */ { if (!(S_ISREG(sbuf.st_mode)) || !(S_IRUSR & sbuf.st_mode)) { clienterror(fd, filename, "403", "Forbidden", "Tiny couldn't read the file"); return; } serve_static(fd, filename, sbuf.st_size); } else /* Serve dynamic content */ { if (!(S_ISREG(sbuf.st_mode)) || !(S_IXUSR & sbuf.st_mode)) { clienterror(fd, filename, "403", "Forbidden", "Tiny couldn't run the CGI program"); return; } serve_dynamic(fd, filename, cgiargs, &rio); } }
/* return 0 if success */ int serve_request(int fd, Req_info *req){ struct stat sbuf; if(stat(req->uri, &sbuf) < 0){ req->status = 404; sws_response(fd, req); return 1; } if (check_modified_since(req, &sbuf)) { req->status = 304; sws_response(fd, req); return 1; } if(req->cgi == NO_CGI){ /* static */ if( (S_ISREG(sbuf.st_mode)) && (S_IRUSR & sbuf.st_mode)) { return serve_static(fd, req, sbuf.st_size); } else if ((S_ISDIR(sbuf.st_mode)) && (S_IRUSR & sbuf.st_mode)) { return serve_dir(fd, req); } else { req->status = 403; sws_response(fd, req); return 1; } } else { /* dynamic */ if(!(S_ISREG(sbuf.st_mode)) || !(S_IXUSR & sbuf.st_mode)) { req->status = 403; sws_response(fd, req); return 1; } /* req' uri*/ if (req->method == GET) return serve_GET_dynamic(fd, req); else if (req->method == POST) { if (req->contLen==0) { req->status=400; sws_response(fd, req); return 1; } return serve_POST_dynamic(fd, req); } } return 0; }
// handle one HTTP request/response transaction void process(int fd, struct sockaddr_in *clientaddr){ printf("Accept Request, fd is %d, pid is %d\n", fd, getpid()); http_request req; memset(&req, 0, sizeof(req)); if (-1 == parse_request(fd, &req)) { //bad socket, don't record printf("Invalid socket!\n"); return; } //update recent visited client information char browser[10][100]; char ip[10][100]; memset(browser, 0, 1000); memset(ip, 0, 1000); strcpy(browser[0], browser_name[req.browser_index]); strcpy(ip[0], inet_ntoa(clientaddr->sin_addr)); update(browser, ip); struct stat sbuf; int status = 200; //server status init as 200 int ffd = open(req.filename, O_RDONLY, 0); if(ffd <= 0){ // detect 404 error and print error log status = 404; client_error(fd, status, "Not Found", "File Not Found"); } else { // get descriptor status fstat(ffd, &sbuf); if(S_ISREG(sbuf.st_mode)){ // server serves static content serve_static(fd, ffd, &req, status); } else if(S_ISDIR(sbuf.st_mode)){ // server handle directory request handle_directory_request(fd, status, browser, ip); } else { // detect 400 error and print error log status = 400; client_error(fd, status, "Bad Request", "Bad Request"); } close(ffd); } // print log/status on the terminal log_access(status, clientaddr, &req); }
void doit(int fd) { int is_static; struct stat sbuf; char buf[MAXLINE], method[MAXLINE], uri[MAXLINE], version[MAXLINE]; char filename[MAXLINE], cgiargs[MAXLINE]; rio_t rio; Rio_readinitb(&rio, fd); Rio_readlineb(&rio, buf, MAXLINE); sscanf(buf, "%s %s %s", method, uri, version); if (strcasecmp(method, "GET"))//仅支持GET方法 { clienterror(fd, method, "501", "Not Implemented", "Tiny does not implement this method"); return; } read_requesthdrs(&rio);//忽略任何请求报头 is_static = parse_uri(uri, filename, cgiargs);//URI解析(动态或是静态) if (stat(filename, &sbuf) < 0) { clienterror(fd, filename, "404", "Not found", "Tiny couldn't find this file"); return; } if (is_static) { if(!(S_ISREG(sbuf.st_mode)) || !(S_IRUSR & sbuf.st_mode)) { clienterror(fd, filename, "403", "Forbidden", "Tiny couldn't read this file"); return; } serve_static(fd, filename, sbuf.st_size); } else { if(!(S_ISREG(sbuf.st_mode)) || !(S_IXUSR & sbuf.st_mode)) { clienterror(fd, filename, "403", "Forbidden", "Tiny couldn't run the CGI program"); return; } serve_dynamic(fd, filename, cgiargs); } }
/* * doit - 处理http请求 */ void doit(int fd) { int is_static; struct stat sbuf; char buf[MAXLINE], method[MAXLINE], uri[MAXLINE], version[MAXLINE]; char filename[MAXLINE], cgiargs[MAXLINE]; rio_t rio; /* 读取请求行和报头 */ Rio_readinitb(&rio, fd); if (!Rio_readlineb(&rio, buf, MAXLINE)) return; printf("%s", buf); sscanf(buf, "%s %s %s", method, uri, version); if (strcasecmp(method, "GET")) { //判断是否是GET方法 clienterror(fd, method, "501", "Not Implemented", "Tiny does not implement this method"); return; } read_requesthdrs(&rio); //处理报头 /* 解析uri */ is_static = parse_uri(uri, filename, cgiargs); if (stat(filename, &sbuf) < 0) { clienterror(fd, filename, "404", "Not found", "Tiny couldn't find this file"); return; } if (is_static) { /* 服务静态内容 */ if (!(S_ISREG(sbuf.st_mode)) || !(S_IRUSR & sbuf.st_mode)) { clienterror(fd, filename, "403", "Forbidden", "Tiny couldn't read the file"); return; } serve_static(fd, filename, sbuf.st_size); } else { /*服务动态内容 */ if (!(S_ISREG(sbuf.st_mode)) || !(S_IXUSR & sbuf.st_mode)) { clienterror(fd, filename, "403", "Forbidden", "Tiny couldn't run the CGI program"); return; } serve_dynamic(fd, filename, cgiargs); //line:netp:doit:servedynamic } }
void doit (int fd) { bool is_static; struct stat sbuf; char buf[MAXLINE], method[MAXLINE], uri[MAXLINE], version[MAXLINE]; char filename[MAXLINE], cgiargs[MAXLINE]; wp_rio_t *rio; rio = wp_rio_new (fd); wp_rio_readlineb (rio, buf, sizeof (buf)); sscanf (buf, "%s %s %s", method, uri, version); if (strcasecmp (method, "GET") != 0) { clienterror (fd, method, "501", "not Implemented", "Tiny does not implement this method"); return; } read_requesthdrs (rio); is_static = parse_uri (uri, filename, cgiargs); if (wp_stat(filename, &sbuf) < 0) { clienterror (fd, filename, "404", "Not found", "Tiny couldn't find this file"); return; } if (is_static) { if (!(S_ISREG(sbuf.st_mode)) || !(S_IRUSR & sbuf.st_mode)) { clienterror (fd, filename, "403", "Forbidden", "Tiny couldn't read the file"); return; } serve_static (fd, filename, sbuf.st_size); } else { if (!(S_ISREG(sbuf.st_mode)) || !(S_IXUSR & sbuf.st_mode)) { clienterror (fd, filename, "403", "Forbidden", "Tiny couldn't run the CGI program"); return; } serve_dynamic (fd, filename, cgiargs); } }
/* * doit - handle an HTTP transaction */ void doit(int connfd) { char buf[MAXLINE], method[MAXLINE], uri[MAXLINE], version[MAXLINE]; char filename[MAXLINE], cgiargs[MAXLINE]; rio_t rio; int is_static; struct stat filestat; /* parse request, for Tiny Server, it's typically "GET / HTTP/1.0" */ Rio_readinitb(&rio, connfd); /* subsequent read will read from connfd */ Rio_readlineb(&rio, buf, MAXLINE); /* read first line of HTTP request */ sscanf(buf, "%s %s %s", method, uri, version); /* format */ if (strcasecmp(method, "GET")) { /* Tiny Server can only handle GET method */ clienterror(connfd, method, "501", "Not Implemented", "Tiny does not support the method "); return; } read_requesthdrs(&rio); /* parse uri, put requested file name into `filename`, and put arguments */ /* into cgiargs if any */ is_static = parse_uri(uri, filename, cgiargs); if (stat(filename, &filestat) < 0) { clienterror(connfd, filename, "404", "Not Found", "Tiny couldn't find the file "); return; } if (is_static) { /* serve static content */ if (!S_ISREG(filestat.st_mode) || !(S_IRUSR & filestat.st_mode)) { clienterror(connfd, filename, "403", "Forbidden", "Tiny couldn't read the file "); return; } serve_static(connfd, filename, filestat); } else { if (!S_ISREG(filestat.st_mode) || !(S_IXUSR & filestat.st_mode)) { clienterror(connfd, filename, "403", "Forbidden", "Tiny couldn't execute the cgi file "); return; } serve_dynamic(connfd, filename, cgiargs); } }
void doit(int fd) { int is_static; struct stat sbuf; char buf[MAXLINE], method[MAXLINE], uri[MAXLINE], version[MAXLINE]; char filename[MAXLINE], cgiargs[MAXLINE]; rio_t rio; // read request line and headers Rio_readinitb(&rio, fd); Rio_readlineb(&rio, buf, MAXLINE); sscanf(buf, "%s %s %s", method, uri, version); if (strcasecmp(method, "GET")) { clienterror(fd, method, "501", "Not Implemented", "Tiny does not implement this method"); return; } Rio_writen(rio.rio_fd, "OK!\n", 4); read_requesthdrs(&rio); Rio_writen(rio.rio_fd, "OK!\n", 4); // parse uri from GET request is_static = parse_uri(uri, filename, cgiargs); if (stat(filename, &sbuf) < 0) { clienterror(fd, filename, "404", "Not found", "Tiny couldn't find the file"); return; } if (is_static) { // server static content if (!(S_ISREG(sbuf.st_mode)) || !(S_IRUSR & sbuf.st_mode)) { clienterror(fd, filename, "403", "Forbidden", "Tiny could't read the file"); return; } runtimeLogFmt("arrive line : %d", __LINE__); serve_static(fd, filename, sbuf.st_size); } else { // serve dynamic content if (!(S_ISREG(sbuf.st_mode)) || !(S_IXUSR & sbuf.st_mode)) { clienterror(fd, filename, "403", "Forbidden", "Tiny couldn't run the CGI program"); return; serve_dynamic(fd, filename, cgiargs); } } }
void doit(int fd) { rio_t rio; Rio_readinitb(&rio, fd); char *request = read_request(&rio); if (request == NULL) return; write_to_file(request); char method[MAXLINE], uri[MAXLINE], version[MAXLINE]; sscanf(request, "%s %s %s", method, uri, version); free(request); if (strcasecmp(method, "GET") && strcasecmp(method, "HEAD")) { clienterror(fd, method, "501", "Not implemented", "Tiny does not implement this method"); return; } char filename[MAXLINE], cgiargs[MAXLINE]; int is_static = parse_uri(uri, filename, cgiargs); struct stat sbuf; if (stat(filename, &sbuf) < 0) { clienterror(fd, filename, "404", "Not found", "Tiny couldn't read the file"); return; } if (is_static) { /* Serve static content */ if (!(S_ISREG(sbuf.st_mode)) || !(S_IRUSR & sbuf.st_mode)) { clienterror(fd, filename, "403", "Forbidden", "Tiny couldn't read the filetype"); return; } serve_static(fd, filename, sbuf.st_size, method); } else { /* Serve dynamic content */ if (!(S_ISREG(sbuf.st_mode)) || !(S_IXUSR & sbuf.st_mode)) { clienterror(fd, filename, "403", "Forbidden", "Tiny couldn't run the CGI program"); return; } serve_dynamic(fd, filename, cgiargs, method); } }
int serve_dir(int fd, Req_info * req) { DIR *dp; char index[256]; char buf[MAXBUF]; char content[MAXBUF]; char date[256]; struct stat sbuf; struct stat sb; struct dirent *dirp; char last_modified[256]; char path[256]; if (req->uri[strlen(req->uri)-1]!='/') strcat(req->uri,"/"); sprintf(index, "%sindex.html",req->uri); if( !lstat(index, &sbuf)){ strncpy(req->uri,index,strlen(index)+1); return serve_static(fd, req,sbuf.st_size); } if ((dp = opendir(req->uri)) == NULL ) { req->status = 403; sws_response(fd, req); return 1; } sprintf(content,"<!DOCTYPE><html><head><title>Four0Four sws</title></head><body><h1>Index of %s:</h1><br/><table><tr><th align='left'>Name:</th><th align='right'>Last_Modified:</th></tr><tr><th colspan='5'><hr></th></tr>",basename(req->uri)); while ((dirp = readdir(dp)) != NULL ) { if (dirp->d_name[0] != '.') { sprintf(path,"%s%s",req->uri,dirp->d_name); if (stat(path, &sb) == -1) { if (lstat(path, &sb) == -1) { strcpy(last_modified,"Cannot stat\0"); } } else { struct tm * tmp; tmp = gmtime(&sb.st_mtime); char *Wday[]={"Sun","Mon","Tue","Wed","Thu","Fri","Sat"}; char *Mth[]={"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"}; sprintf(last_modified,"%s, %d %s %d %d:%d:%d GMT",Wday[tmp->tm_wday],(tmp->tm_mday),Mth[tmp->tm_mon],(1900+tmp->tm_year),(tmp->tm_hour),(tmp->tm_min),(tmp->tm_sec)); } sprintf(content, "%s<tr><td align='left'>%s</td><td align='right'>%s</td></tr>",content,dirp->d_name,last_modified); } } sprintf(content, "%s<tr><th colspan='5'><hr></th></tr></table><br/><span>Four0Four Server page</span></body></html>",content); closedir(dp); if (_simple_response !=1 ) { sprintf(buf, "HTTP/1.0 200 OK\r\n"); get_timestamp(date); sprintf(buf, "%sDate: %s\r\n",buf,date); sprintf(buf, "%sServer: Four0Four\r\n", buf); sprintf(buf, "%sContent-type: text/html\r\n", buf); sprintf(buf, "%sContent-length: %d\r\n\r\n", buf, (int)strlen(content)); Send(fd, buf, strlen(buf), 0); } if (_head_response != 1) Send(fd, content, strlen(content), 0); req->contLen = (int)strlen(content); logging(req); return 0; }
/* $begin doit */ void *doit(void *_fd) { int fd = (int)_fd; int is_static; struct stat sbuf; char buf[MAXLINE], method[MAXLINE], uri[MAXLINE], version[MAXLINE]; char filename[MAXLINE], cgiargs[MAXLINE]; rio_t rio; fprintf(stderr," %d\n",fd); /* Read request line and headers */ Rio_readinitb(&rio, fd); Rio_readlineb(&rio, buf, MAXLINE); //line:netp:doit:readrequest sscanf(buf, "%s %s %s", method, uri, version); //line:netp:doit:parserequest if (strcasecmp(method, "GET") && strcasecmp(method,"POST")) { //line:netp:doit:beginrequesterr clienterror(fd, method, "501", "Not Implemented", "Tiny does not implement this method"); goto ext; } //line:netp:doit:endrequesterr read_requesthdrs(&rio); //line:netp:doit:readrequesthdrs /* Parse URI from GET request */ fprintf(stderr,"URI: %s \n",uri); fprintf(stderr,"FILENAME: %s \n",filename); is_static = parse_uri(uri, filename, cgiargs); //line:netp:doit:staticcheck if(!strcasecmp(method,"POST")){ Rio_readlineb(&rio, cgiargs, MAXLINE); cgiargs[strlen(cgiargs)-2]=0; } fprintf(stderr,"ARG: %s \n",cgiargs); fprintf(stderr,"URI: %s \n",uri); fprintf(stderr,"FILENAME: %s \n",filename); if (is_static) { /* Serve static content */ if (stat(filename, &sbuf) < 0 ) { //line:netp:doit:beginnotfound clienterror(fd, filename, "404", "Not found", "Tiny couldn't find this file"); goto ext; } //line:netp:doit:endnotfound if (!(S_ISREG(sbuf.st_mode)) || !(S_IRUSR & sbuf.st_mode)) { //line:netp:doit:readable clienterror(fd, filename, "403", "Forbidden", "Tiny couldn't read the file"); goto ext; } serve_static(fd, filename, sbuf.st_size); //line:netp:doit:servestatic } else { /* Serve dynamic content */ if (stat(filename, &sbuf) < 0 ) { //line:netp:doit:beginnotfound clienterror(fd, filename, "404", "Not found", "Tiny couldn't find this file"); goto ext; } //line:netp:doit:endnotfound if (!(S_ISREG(sbuf.st_mode)) || !(S_IXUSR & sbuf.st_mode)) { //line:netp:doit:executable clienterror(fd, filename, "403", "Forbidden", "Tiny couldn't run the CGI program"); goto ext; } serve_dynamic(fd, filename, cgiargs); //line:netp:doit:servedynamic } ext: Close(fd); return 0; }
void doit(int fd) { int is_static; struct stat sbuf; char buf[MAXLINE], method[MAXLINE], uri[MAXLINE], version[MAXLINE]; char filename[MAXLINE], cgiargs[MAXLINE]; rio_t rio; /* Read request line and headers, put them into a file */ char *request = NULL; Rio_readinitb(&rio, fd); for (;;) { Rio_readlineb(&rio, buf, MAXLINE); /* * Firefox will sent \x16\x3. * \x16: Synchronous Idle, \x3: End of Text */ if (!strncmp(buf, "\x16\x3", 2)) { free(request); return; } int buflen = strlen(buf); char *old_request = request; int old_reqlen = old_request==NULL ? 0 : strlen(old_request); request = realloc(old_request, buflen + old_reqlen + 1); if (request == NULL) { fprintf(stderr, "realloc: run out of memory\n"); free(old_request); return; } memmove(request+old_reqlen, buf, buflen+1); if (!strcmp(buf, "\r\n")) /* Copy before stop */ break; } sscanf(request, "%s %s %s", method, uri, version); if (strcasecmp(method, "GET")) { clienterror(fd, method, "501", "Not implemented", "Tiny does not implement this method"); return; } FILE *out = fopen("tiny-request.txt", "w+"); if (out == NULL) { perror("fopen"); free(request); return; } fprintf(out, "%s", request); fflush(out); fclose(out); free(request); /* Parse URI from GET request */ is_static = parse_uri(uri, filename, cgiargs); if (stat(filename, &sbuf) < 0) { clienterror(fd, filename, "404", "Not found", "Tiny couldn't read the file"); return; } if (is_static) { /* Serve static content */ if (!(S_ISREG(sbuf.st_mode)) || !(S_IRUSR & sbuf.st_mode)) { clienterror(fd, filename, "403", "Forbidden", "Tiny couldn't read the filetype"); return; } serve_static(fd, filename, sbuf.st_size); } else { /* Serve dynamic content */ if (!(S_ISREG(sbuf.st_mode)) || !(S_IXUSR & sbuf.st_mode)) { clienterror(fd, filename, "403", "Forbidden", "Tiny couldn't run the CGI program"); return; } serve_dynamic(fd, filename, cgiargs); } }
// // name: 未知 // @param // @return // void doit(int fd) { printf("-------------------doit-----------------\n"); int is_static; struct stat sbuf; int n; char buf[MAXLINE] = {0}; char method[MAXLINE] = {0}; char uri[MAXLINE] = {0}; char version[MAXLINE] = {0}; char filename[MAXLINE] = {0}; char cgiargs[MAXLINE] = {0}; rio_t rio; rio_readinitb(&rio, fd); n = rio_readlineb(&rio, buf, MAXLINE); if(n > 0) { printf("Read [%d] bytes data from cache\n",n); } else printf("No data or Error\n"); sscanf(buf, "%s %s %s", method, uri, version); printf("Method is [%s]\nUri is [%s]\nVersion is [%s]",method,uri,version); if(strcasecmp(method, "GET") != 0) { clienterror(fd, method, "501", "Not Implemented", "Tiny does not implement this method"); return; } /* read msg, and print*/ read_requesthdrs(&rio); is_static = parse_uri(uri, filename, cgiargs); if(stat(filename, &sbuf) < 0) { printf("Can't find %s\n",filename); clienterror(fd, filename, "404", "Not found", "Tiny couldn't find this file"); return; } if(is_static) { if(!(S_ISREG(sbuf.st_mode))||!(S_IRUSR & sbuf.st_mode)) { clienterror(fd, filename, "403", "Forbidden", "Tiny couldn't read the file"); return; } serve_static(fd, filename, sbuf.st_size); } else { if(!(S_ISREG(sbuf.st_mode))||!(S_IXUSR & sbuf.st_mode)) { clienterror(fd, filename, "403", "Forbidden", "Tiny couldn't run the CGI program"); return; } serve_dynamic(fd, filename, cgiargs); } }
void doit (int fd) { int is_static; struct stat sbuf; char buf[MAXLINE], method[MAXLINE], uri[MAXLINE], version[MAXLINE]; char filename[MAXLINE], cgiargs[MAXLINE]; rio_t rio; Rio_readinitb(&rio, fd); Rio_readlineb(&rio, buf, MAXLINE); sscanf(buf, "%s %s %s", method, uri, version); // get request // e.g. GET / HTTP/1.1 if (!strcasecmp(method, "GET") || !strcasecmp(method, "HEAD")) { read_requesthdrs(&rio); int head = strcasecmp(method, "HEAD") ? 0 : 1; is_static = parse_uri(uri, filename, cgiargs); if (stat(filename, &sbuf) < 0) { clienterror(fd, filename, "404", "Not found", "Tiny couldn't find this file"); return; } if (is_static) { //serve static content if (!(S_ISREG(sbuf.st_mode)) || !(S_IRUSR & sbuf.st_mode)) { clienterror(fd, filename, "403", "Forbidden", "Tiny couldn't read the file"); return; } serve_static(fd, filename, sbuf.st_size, head); } else { // serve dynamic content if(!(S_ISREG(sbuf.st_mode)) || !(S_IXUSR & sbuf.st_mode)) { clienterror(fd, filename, "403", "Forbidden", "Tiny couldn't run the CGI program"); return; } serve_dynamic(fd, filename, cgiargs, head); } } else if (!strcmp(method, "POST")) { read_requesthdrs(&rio); parse_uri(uri, filename, cgiargs); Rio_readlineb(&rio, cgiargs, MAXLINE); Rio_readlineb(&rio, buf, MAXLINE); if (stat(filename, &sbuf) < 0) { clienterror(fd, filename, "404", "Not found", "Tiny couldn't find this file"); return; } if(!(S_ISREG(sbuf.st_mode)) || !(S_IXUSR & sbuf.st_mode)) { clienterror(fd, filename, "403", "Forbidden", "Tiny couldn't run the CGI program"); return; } serve_dynamic(fd, filename, cgiargs, 0); } else { clienterror(fd, method, "501", "Not Implemented", "Tiny does not implement this method"); return; } }
// 处理HTTP事务 void* doit(void *arg) { int fd = *((int *)arg); int is_static; struct stat sbuf; char buf[LINE_MAX] = {0}, method[LINE_MAX] = {0}, uri[LINE_MAX] = {0}, version[LINE_MAX] = {0}; char filename[LINE_MAX] = {0}, cgiargs[LINE_MAX] = {0}; do { // 读入请求行 if (readline(fd, buf, sizeof(buf)) > 0) { if (sscanf(buf, "%s %s %s", method, uri, version) != 3) { client_error(fd, "GET", "501", "Not Impelemented", "error request line"); break; } } // 读入请求报头,简单打印到标准输出 while (readline(fd, buf, sizeof(buf)) > 0) { if (strcmp(buf, "\r\n") == 0) break; } /* 过滤所有非GET请求*/ if (strcmp(method, "GET")) { client_error(fd, method, "501", "Not Impelementd", "minihttp does not impelement this method"); break; } is_static = parse_uri(uri, filename, cgiargs); if (stat(filename, &sbuf) < 0) { client_error(fd, filename, "404", "Not found", "miniftp couldn't find this file"); break; } if (is_static) /* Serve static content */ { if (!(S_ISREG(sbuf.st_mode)) || !(S_IRUSR & sbuf.st_mode)) { client_error(fd, filename, "403", "Forbidden", "minihttp couldn't read the file"); break; } serve_static(fd, filename, sbuf.st_size); } else /* Serve dynamic content */ { if (!(S_ISREG(sbuf.st_mode)) || !(S_IRUSR & sbuf.st_mode)) { client_error(fd, filename, "403", "Forbidden", "minihttp couldn't run the CGI program"); break; } serve_dynamic(fd, filename, cgiargs); } } while (0); close(fd); free((int *)arg); return NULL; }
/** * Serves the favicon file. */ void route_favicon(evhtp_request_t *req, void *arg) { evhtp_headers_add_header(req->headers_out, evhtp_header_new("Cache-Control", "max-age=90000, public", 0, 0)); serve_static(req, "static/favicon.ico", "image/x-icon"); }
/* $begin doit */ void doit(int fd) { int is_static,contentLength=0,isGet=1; struct stat sbuf; char buf[MAXLINE], method[MAXLINE], uri[MAXLINE], version[MAXLINE]; char filename[MAXLINE], cgiargs[MAXLINE],httpspostdata[MAXLINE]; rio_t rio; memset(buf,0,MAXLINE); if(ishttps) { ssl=SSL_new(ssl_ctx); SSL_set_fd(ssl,fd); if(SSL_accept(ssl)==0) { ERR_print_errors_fp(stderr); exit(1); } SSL_read(ssl,buf,sizeof(buf)); printf(".............\n"); printf("%s",buf); printf(".............\n"); } else { /* Read request line and headers */ Rio_readinitb(&rio, fd); Rio_readlineb(&rio, buf, MAXLINE); } sscanf(buf, "%s %s %s", method, uri, version); /* if (strcasecmp(method, "GET")!=0&&strcasecmp(method,"POST")!=0) { clienterror(fd, method, "501", "Not Implemented", "Tiny does not implement this method"); return; } */ /* Parse URI from GET request */ is_static = parse_uri(uri, filename, cgiargs); if (lstat(filename, &sbuf) < 0) { clienterror(fd, filename, "404", "Not found", "Tiny couldn't find this file"); return; } if(S_ISDIR(sbuf.st_mode)&&isShowdir) serve_dir(fd,filename); if (strcasecmp(method, "POST")==0) isGet=0; if (is_static) { /* Serve static content */ if(!ishttps) get_requesthdrs(&rio); /* because https already read the headers -> SSL_read() */ if (!(S_ISREG(sbuf.st_mode)) || !(S_IRUSR & sbuf.st_mode)) { clienterror(fd, filename, "403", "Forbidden", "Tiny couldn't read the file"); return; } serve_static(fd, filename, sbuf.st_size); } else { /* Serve dynamic content */ if (!(S_ISREG(sbuf.st_mode)) || !(S_IXUSR & sbuf.st_mode)) { clienterror(fd, filename, "403", "Forbidden", "Tiny couldn't run the CGI program"); return; } if(isGet) { if(!ishttps) get_requesthdrs(&rio); /* because https already read headers by SSL_read() */ get_dynamic(fd, filename, cgiargs); } else { printf("ishttps:%d\n",ishttps); if(ishttps) https_getlength(buf,&contentLength); else post_requesthdrs(&rio,&contentLength); post_dynamic(fd, filename,contentLength,&rio); } } }
//************************************************* void *handle_http(void *arg) { http_request_t *request = (http_request_t *)arg; int fd = request->fd; int rcode = 0; int is_static; struct stat sbuf; char buf[MAXLINE], method[MAXLINE], uri[MAXLINE], version[SHORTLINE], header_key[MAXLINE], header_value[MAXLINE]; char filename[MAXLINE], cgiargs[MAXLINE]; int n; /* Read request line and headers */ while (1) { printf("[INFO] read from fd %d\n", fd); n = read(fd, request->last, (uint64_t)request->buf + MAX_BUF - (uint64_t)request->last); printf("[INFO] n = %d\n", n); if (n == 0) { goto err; } if (n < 0) { if (errno != EAGAIN) { log_err("read error, errno = %d", errno); goto err; } break; } request->last += n; rcode = http_parse_request_line(request); if (rcode == SERVER_AGAIN) { continue; } else if (rcode != SERVER_OK) { log_err("parse request line error, rcode = %d", rcode); goto err; } strncpy(method, request->request_start, request->method_end - request->request_start); strncpy(uri, request->uri_start, request->uri_end - request->uri_start); sprintf(version, "%d.%d", request->http_major, request->http_minor); if (request->method != HTTP_GET) { debug("error method: %s\n", method); debug("error uri: %s\n", uri); debug("error version: %s\n", version); clienterror(fd, method, "501", "Not Implemented", "Server does not implement this method"); return NULL; } debug("http request line"); debug("method = %s", method); debug("uri = %s", uri); debug("version = %s", version); rcode = http_parse_request_body(request); if (rcode == SERVER_AGAIN) { continue; } else if (rcode != SERVER_OK) { log_err("parse request body error, rcode = %d", rcode); goto err; } debug("number of headers = %d", request->num_headers); if (request->num_headers > 0) { list_node_t *head = request->head->next; int i; for (i = 0; i < request->num_headers; i++) { http_header_t *header = (http_header_t *)head->ptr; memset(header_key, 0, sizeof(header_key)); memset(header_value, 0, sizeof(header_value)); memcpy(header_key, header->key_start, header->key_end - header->key_start); memcpy(header_value, header->value_start, header->value_end - header->value_start); debug("%s: %s", header_key, header_value); head = head->next; } } is_static = parse_uri(uri, filename, cgiargs); if (stat(filename, &sbuf) < 0) { clienterror(fd, filename, "404", "Not found", "Server couldn't find this file"); continue; } if (is_static) { if (!(S_ISREG(sbuf.st_mode)) || !(S_IRUSR & sbuf.st_mode)) { clienterror(fd, filename, "403", "Forbidden", "Server couldn't read the file"); continue; } serve_static(fd, filename, sbuf.st_size); } goto close; } return NULL; err: close: debug("closing fd %d", fd); close(fd); }