Response response_read(int fd) { rio_t rio; char buf[MAXLINE]; Rio_readinitb(&rio, fd); ssize_t r = Rio_readlineb(&rio, buf, MAXLINE); if (r == 0) { printf("Received empty response\n"); return NULL; } Response response = malloc(sizeof(struct Response)); sscanf(buf, "%s %d %s", response->version, &response->status_code, response->status_name); header_read(&rio, buf, &response->header); HeaderEntry* content_length_entry = header_find_entry(&response->header, "Content-Length"); int content_length = content_length_entry == NULL ? 0 : atoi(content_length_entry->value); response->content_length = content_length; response->content = malloc(response->content_length * sizeof(char)); char *content = response->content; while (content_length > 0) { r = Rio_readlineb(&rio, content, (size_t) content_length); if (r > 0) { content += r; content_length -= r; } } return response; }
/* Read a request from a connection socket and parses its information into a * req_t struct. * Initally based on csapp echo() p.911 * Allocates memory for request hdrs * returns -1 on failure, 1 if the content is local, and 0 if the content is * remote */ int process_request(int fd, req_t* req){ size_t n; char buf[MAXLINE]; rio_t rio; req->domain = NULL; req->path = NULL; req->hdrs = NULL; //Parse domain and path information Rio_readinitb(&rio, fd); if((n = Rio_readlineb(&rio, buf, MAXLINE)) != 0){ if(parse_req(buf, req) == -1) return -1; } else return -1; //parse header information while((n = Rio_readlineb(&rio, buf, MAXLINE)) != 0){ if(strcmp(buf, "\r\n") == 0) break; if(req->hdrs != NULL){ n = strlen(req->hdrs) + strlen(buf) + 1; req->hdrs = Realloc(req->hdrs,strlen(req->hdrs)+ n); strcat(req->hdrs, handle_hdr(buf)); } else { req->hdrs = Malloc(n+1); strcpy(req->hdrs, handle_hdr(buf)); } } return 0; }
void getInfo(int fd, rio_t client, int id){ char buf1[MAXLINE]; int jobID=id; int numBytes; char * saveptr=NULL; Rio_readinitb( &client,fd); while(true){ numBytes = Rio_readlineb(&client, buf1, MAXLINE); id1 = strtok_r(buf1, " \r\n",&saveptr); int fileStartID=atoi(id1); id2 = strtok_r(buf1, " \r\n",&saveptr); int fileEndID=atoi(id2); numBytes = Rio_readlineb(c, buf, MAXLINE); if(numBytes<0){ Close(fd); return ans; } buf[numBytes]=0; seperate(buf, &ans.pre); fd=Open_clientfd(ipAddress, atoi(port)); }
/* * Read the HTTP response and print it out */ void clientPrint(int fd) { rio_t rio; char buf[MAXBUF]; int length = 0; int n; Rio_readinitb(&rio, fd); /* Read and display the HTTP Header */ n = Rio_readlineb(&rio, buf, MAXBUF); while (strcmp(buf, "\r\n") && (n > 0)) { printf("Header: %s", buf); n = Rio_readlineb(&rio, buf, MAXBUF); /* If you want to look for certain HTTP tags... */ if (sscanf(buf, "Content-Length: %d ", &length) == 1) { printf("Length = %d\n", length); } } /* Read and display the HTTP Body */ n = Rio_readlineb(&rio, buf, MAXBUF); while (n > 0) { printf("%s", buf); n = Rio_readlineb(&rio, buf, MAXBUF); } }
/* $begin read_requesthdrs */ void read_requesthdrs(rio_t *rp) { char buf[MAXLINE]; Rio_readlineb(rp, buf, MAXLINE); while(strcmp(buf, "\r\n")) Rio_readlineb(rp, buf, MAXLINE); return; }
void read_requesthdrs(const rio_t *rp) { char buf[MAXLINE]; Rio_readlineb(rp, buf, MAXLINE); while(strcmp(buf, "\r\n")) { Rio_readlineb(rp, buf, MAXLINE); printf("%s", buf); } return; }
/* $begin read_requesthdrs */ void read_requesthdrs(rio_t *rp) { char buf[MAXLINE]; Rio_readlineb(rp, buf, MAXLINE); while(strcmp(buf, "\r\n")) { //line:netp:readhdrs:checkterm Rio_readlineb(rp, buf, MAXLINE); printf("%s", buf); } return; }
/* * read_requesthdrs - read and ignore HTTP request headers, Tiny Server * only need first line, like "GET / HTTP/1.0" */ void read_requesthdrs(rio_t *rp) { char buf[MAXLINE]; Rio_readlineb(rp, buf, MAXLINE); while(strcmp(buf, "\r\n")) { /* check temination */ Rio_readlineb(rp, buf, MAXLINE); printf("%s", buf); /* print out received header */ printf("i gess\n"); } return; }
/* * read_requesthdrs: just bypass the request headers * */ void read_requesthdrs(rio_t *rp) { char buf[MAXLINE]; Rio_readlineb(rp, buf, MAXLINE); while(strcmp(buf, "\r\n")) { Rio_readlineb(rp, buf, MAXLINE); #ifdef DEBUG printf("%s", buf); #endif } return; }
/* * forward_to_client - forward without write to cache * * used for non GET methods; * * return -1 on error * return 0 on success */ int forward_to_client(int to_client_fd, int to_server_fd) { rio_t rio_server; char buf[MAXLINE]; unsigned int length = 0, size = 0; Rio_readinitb(&rio_server, to_server_fd); // forward status line if (Rio_readlineb(&rio_server, buf, MAXLINE) == -1) { return -1; } if (Rio_writen(to_client_fd, buf, strlen(buf)) == -1) { return -1; } // forward response headers while (strcmp(buf, "\r\n") != 0 && strlen(buf) > 0) { if (Rio_readlineb(&rio_server, buf, MAXLINE) == -1) { return -1; } get_size(buf, &size); if (Rio_writen(to_client_fd, buf, strlen(buf)) == -1) { return -1; } } // forward response body if (size > 0) { while (size > MAXLINE) { if ((length = Rio_readnb(&rio_server, buf, MAXLINE)) == -1) { return -1; } if (Rio_writen(to_client_fd, buf, length) == -1) { return -1; } size -= MAXLINE; } if (size > 0) { if ((length = Rio_readnb(&rio_server, buf, size)) == -1) { return -1; } if (Rio_writen(to_client_fd, buf, length) == -1) { return -1; } } } else { while ((length = Rio_readnb(&rio_server, buf, MAXLINE)) > 0) { if (Rio_writen(to_client_fd, buf, length) == -1) { return -1; } } } return 0; }
void doit(int fd) { int clientfd; char buf[MAXLINE], method[MAXLINE], uri[MAXLINE]; char host[MAXLINE], port[MAXLINE]; char filename[MAXLINE]; char cache_buf[MAX_OBJECT_SIZE]; size_t buflen; struct cache *cache; int cache_size = 0, cache_flag = 1; rio_t c_rio, s_rio; /* Read request line and headers */ Rio_readinitb(&c_rio, fd); if (!Rio_readlineb(&c_rio, buf, MAXLINE)) return; printf("%s", buf); sscanf(buf, "%s %s", method, uri); if (strcasecmp(method, "GET")) { printf("this proxy can handle only \"GET\"\n"); return; } construct_requesthdrs(&c_rio, buf, filename, uri, host, port); if (find_cache(&cache, uri) == 1) { Rio_writen(fd, cache->data, strlen(cache->data)); } else { clientfd = Open_clientfd(host, port); if (clientfd < 0) { printf("there is no such server\n"); return; } Rio_readinitb(&s_rio, clientfd); Rio_writen(clientfd, buf, strlen(buf)); while ((buflen = Rio_readlineb(&s_rio, buf, MAXLINE)) != 0) { Rio_writen(fd, buf, buflen); if (cache_size + buflen > MAX_OBJECT_SIZE) { cache_flag = 0; } else { memcpy(cache_buf + cache_size, buf, buflen); cache_size += buflen; } } if (cache_flag == 1) create_cache(cache_buf, uri); Close(clientfd); } }
/* * doit - handle one HTTP request/response transaction */ 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_c, rio_h; /* Ren's Local Vars */ char host[MAXLINE], url[MAXLINE], request[MAXLINE], header[MAXLINE]; int hostfd; /* Ren's Local Vars END */ /* Read request line and headers */ Rio_readinitb(&rio_c, fd); Rio_readlineb(&rio_c, 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; } printf("STUFF FROM THE CLIENT:\n"); printf("%s\n",buf); read_requesthdrs(&rio_c); /* Ren's code */ parseURL(buf, host, uri, version); /* parse url for hostname and uri */ hostfd = Open_clientfd(host, PORT); /* connect to host as client */ Rio_readinitb(&rio_h, hostfd); /* set up host file discriptor */ /* generate and send request to host*/ genrequest(request, method, uri); genheader(host, header); strcat(request, header); printf("%s\n",request); Rio_writen(hostfd, request, strlen(request)); /* stream information from server to client */ printf("STUFF FROM THE SERVER:\n"); while(Rio_readlineb(&rio_h, buf, MAXLINE)){ printf("%s\n",buf); Rio_writen(fd, buf, MAXLINE); } printf("stream ended\n"); /* Ren's code */ }
/* $begin get_requesthdrs */ void get_requesthdrs(rio_t *rp) { char buf[MAXLINE]; Rio_readlineb(rp, buf, MAXLINE); writetime(); /* write access time in log file */ printf("%s", buf); while(strcmp(buf, "\r\n")) { Rio_readlineb(rp, buf, MAXLINE); writelog(buf); printf("%s", buf); } return; }
void read_requesthdrs(rio_t *rp) { char buf[MAXLINE]; runtimeLogFmt("arrive line : %d", __LINE__); printf("in read_requesthdrs\n"); Rio_readlineb(rp, buf, MAXLINE); runtimeLogFmt("arrive line : %d, buf is : %s\n", __LINE__, buf); while(strcmp(buf, "\r\n")) { Rio_readlineb(rp, buf, MAXLINE); printf("in strcmp"); runtimeLogFmt("arrive line : %d", __LINE__); printf("%s", buf); } runtimeLogFmt("arrive line : %d", __LINE__); return; }
int echoClient(int argc, char** argv) { int clientfd, port; char* host, buf[MAXLINE]; rio_t rio; if (argc != 3) { fprintf(stderr, "usage: %s <host> <port>\n", argv[0]); exit(0); } host = argv[1]; port = atoi(argv[2]); clientfd = Open_clientfd(host, port); Rio_readinitb(&rio, clientfd); while (Fgets(buf, MAXLINE, stdin) != NULL) { Rio_writen(clientfd, buf, strlen(buf)); // get response from server Rio_readlineb(&rio, buf, MAXLINE); //Fputs(buf, stdout); } Close(clientfd); exit(0); }
void check_client(pool *p) { int i, connfd, n; char buf[MAXLINE]; rio_t rio; for (i = 0; (i <= p->maxi) && (p->nready > 0); i++) { connfd = p->clientfd[i]; rio = p->clientrio[i]; /* If the descriptor is ready, echo a text line from it */ if ((connfd > 0) && (FD_ISSET(connfd, &p->ready_set))) { p->nready--; if ((n = Rio_readlineb(&rio, buf, MAXLINE)) != 0) { byte_cnt += n; printf("Server received %d (%d total) bytes on fd %d\n", n, byte_cnt, connfd); Rio_writen(connfd, buf, n); } /* EOF detected, remove descriptor from pool */ else { Close(connfd); FD_CLR(connfd, &p->read_set); p->clientfd[i] = -1; } } } }
int main(int argc, char **argv) { int clientfd, port; char *host, buf[MAXLINE]; rio_t rio; if (argc != 3) { fprintf(stderr, "usage: %s <host> <port>\n", argv[0]); exit(0); } host = argv[1]; port = atoi(argv[2]); clientfd = Open_clientfd(host, port); Rio_readinitb(&rio, clientfd); printf("type:"); fflush(stdout); while (Fgets(buf, MAXLINE, stdin) != NULL) { Rio_writen(clientfd, buf, strlen(buf)); Rio_readlineb(&rio, buf, MAXLINE); printf("echo:"); Fputs(buf, stdout); printf("type:"); fflush(stdout); } Close(clientfd); exit(0); }
int main(int argc, char **argv) { int clientfd, port; char *host, buf[MAXLINE]; rio_t rio; if (argc != 3) { fprintf(stderr, "usage: %s <host> <port>\n", argv[0]); exit(0); } host = argv[1]; port = atoi(argv[2]); clientfd = Open_clientfd(host, port); Rio_readinitb(&rio, clientfd); while (Fgets(buf, MAXLINE, stdin) != NULL) { printf("client get: %s\n",buf); Rio_writen(clientfd, buf, strlen(buf)); printf("client buf: %s\n",buf); Rio_readlineb(&rio, buf, MAXLINE); Fputs(buf, stdout); } // printf("outside\n"); Close(clientfd); //line:netp:echoclient:close exit(0); }
/* Return a pointer to request, the caller should free the buffer */ char *read_request(rio_t *rp) { char buf[MAXLINE]; char *request = NULL; for (;;) { Rio_readlineb(rp, buf, MAXLINE); /* * Firefox will sent \x16\x3. * \x16: Synchronous Idle, \x3: End of Text */ if (!strncmp(buf, "\x16\x3", 2)) { free(request); return NULL; } 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 NULL; } memmove(request+old_reqlen, buf, buflen+1); if (!strcmp(buf, "\r\n")) /* Copy before stop */ break; } return request; }
void reduceFunction::getInfo(int fd, rio_t client, int id){ char buf1[MAXLINE]; int numBytes; char * saveptr=NULL; while(true){ numBytes = Rio_readlineb(&client, buf1, MAXLINE); if(numBytes==0){ break; } printf("buf1 is %s\n", buf1); char* d1 = strtok_r(buf1, "*",&saveptr); char ip[20]; strcpy(ip,d1); char* d2 = strtok_r(NULL, "*",&saveptr); int port=atoi(d2); char* d3 = strtok_r(NULL, "* \r\n",&saveptr); int num=atoi(d3); mapNode mapWorker; strcpy(mapWorker.mapIp,ip); mapWorker.mapPort=port; mapAddress[num]=mapWorker; } getMapInfo(); sendInfo(); }
int main(int argc, char** argv) { int clientfd; char* hostname = argv[1]; char* filename = argv[2]; int port = atoi(argv[3]); char data[60]; strcpy(data, "GET /"); strcat(data, filename); strcat(data, " HTTP/1.1\r\nHost: "); strcat(data, hostname); strcat(data, "\r\n\r\n"); printf("Constructed Data: %s\n", data); char buffer[MAXLINE]; // Using MAXLINE from csapp bzero(buffer, MAXLINE); buffer[0] = 'x'; rio_t rio; clientfd = Open_clientfd(hostname, port); Rio_readinitb(&rio, clientfd); rio_writen(clientfd, data, strlen(data)); while (strlen(buffer)>0) { Rio_readlineb (&rio, buffer, MAXLINE); printf("%s\n", buffer); } close(clientfd); exit(0); }
int main(int argc, char **argv) { int n; rio_t rio; char buf[MAXLINE]; if (argc > 2) { fprintf(stderr, "usage: %s [filename]\n", argv[0]); return -1; } /* 这里将标准输入的文件描述符,重定位到输入文件的描述符 */ if (argc == 2) { char *filename = argv[1]; int fd = Open(filename, O_RDONLY, 0); int ret = dup2(fd, STDIN_FILENO); /* 将标准输入重定位到 fd */ if (ret < 0) { perror("dup2"); return -1; } } /* 没有输入文件名,将标准输入拷贝到标准输出 */ Rio_readinitb(&rio, STDIN_FILENO); while ((n = Rio_readlineb(&rio, buf, MAXLINE)) != 0) Rio_writen(STDOUT_FILENO, buf, n); return 0; }
void mapFunction::goMap(int fd, rio_t client, int ID){ pthread_mutex_lock(&mtx); char buf1[MAXLINE]; int jobID=ID; int numBytes; char * saveptr=NULL; char * id1; char * id2; //char * id3; //Rio_readinitb( &client,fd); numBytes = Rio_readlineb(&client, buf1, MAXLINE); if(numBytes<0) return; id1 = strtok_r(buf1, "*",&saveptr); int fileStartID=atoi(id1); id2 = strtok_r(NULL, "* \r\n",&saveptr); int fileEndID=atoi(id2); //id3 = strtok_r(NULL, "* \r\n",&saveptr); //jobID=atoi(id3); map<string,int> jobMap; for(int i=fileStartID;i<=fileEndID;i++){ imageInfo myImage=getImage(i); //printf("%dfile name %s\n", i, myImage.name.data()); if(circleDetect(myImage.myPic)==0) continue; else{ printf("found %d %s\n",i, myImage.name.data()); jobMap[myImage.name]=jobMap[myImage.name]+1; } } myMap[jobID]=jobMap; finished[jobID]=true; pthread_mutex_unlock(&mtx); //Close(fd); }
void receive_message(){ char buf[MAXLINE]; char header[MAXLINE]; char buf1[MAXLINE]; char buf2[MAXLINE]; char buf3[MAXLINE]; rio_t client; Rio_readinitb(&client, clientfd); while(1) { //rio_readp(clientfd,buf,MAXLINE); Rio_readlineb(&client,buf,MAXLINE); if (strcmp(buf,"error\r\n")==0){ printf("The file you want to download doesn't exist!\n"); close(clientfd); exit(1); } if (strcmp(buf, "finish\r\n") == 0){ break; } sscanf(buf, "%s %s %s %s", header, buf1, buf2, buf3); if (strcmp(header, "total") == 0){ total_num = atoi(buf1); user_list = malloc(sizeof(user_list)*total_num); } if (strcmp(header,"user")==0){ int i = atoi(buf1); user_list[i-1].IP = strdup(buf2); user_list[i-1].port = atoi(buf3); } //printf("buf is %s\n",buf); memset(buf, 0, strlen(buf)); } close(clientfd); }
int getSize(int fd) { //stats.req_arrival = id.req_arrival; int is_static; struct stat sbuf; char buf[MAXLINE], method[MAXLINE], uri[MAXLINE], version[MAXLINE]; char filename[MAXLINE], cgiargs[MAXLINE]; rio_t rio; //stats.size = -1; Rio_readinitb(&rio, fd); Rio_readlineb(&rio, buf, MAXLINE); sscanf(buf, "%s %s %s", method, uri, version); //close(fd); printf("%s %s %s\n", method, uri, version); if (strcasecmp(method, "GET")) { requestError(fd, method, "501", "Not Implemented", "CS537 Server does not implement this method"); return 0; } requestReadhdrs(&rio); is_static = requestParseURI(uri, filename, cgiargs); if (stat(filename, &sbuf) < 0) { requestError(fd, filename, "404", "Not found", "CS537 Server could not find this file"); return 0; } return sbuf.st_size; }
char* getInfo(int fd){ char* buf = (char*)malloc(MAXLINE); rio_t rio; Rio_readinitb(&rio, fd); Rio_readlineb(&rio, buf, MAXLINE); requestReadhdrs(&rio); return buf; }
void IoRead::getLineSpliteedByBlank(std::vector<std::string>&buf){ char innerBuf[MAX_LENGTH],method[MAX_LENGTH],uri[MAX_LENGTH],version[MAX_LENGTH]; Rio_readlineb(&rio,innerBuf,MAX_LENGTH); sscanf(innerBuf,"%s %s %s",method,uri,version); buf.push_back(method); buf.push_back(uri); buf.push_back(version); }
void read_thread(pt_s *pt) { WINDOW *show_win, *people_win; win_s show, people; int l = -1, y, x, mes_len = 0; int i = 0; for (i = 0; i < 128; ++i) { int j = 0; for (j = 0; j < 20; ++j) { pt->name_list[i][j] = 0; } } people.startx = COLS - 20; people.starty = 0; people.width = 20; people.height = LINES; people_win = create_newwin(people, "PEOPLE"); show.startx = show.starty = 0; show.height = LINES - 5; show.width = COLS - 20; show_win = create_newwin(show, "MESSAGE"); scrollok(show_win, true); wsetscrreg(show_win, 0, show.height - 3); while (Rio_readlineb(&(pt->rio), pt->rbuf, MAXLINE)) { int color_num = pt->rbuf[0] % 5; mes_len = strlen(pt->rbuf); if (pt->rbuf[mes_len - 2] == '#') { // 显示消息 pt->rbuf[mes_len - 2] = '\n'; pt->rbuf[mes_len - 1] = '\0'; if (l < show.height - 3) l++; wattron(show_win, COLOR_PAIR(color_num)); mvwprintw(show_win, l, 0, "%s", pt->rbuf); wattroff(show_win, COLOR_PAIR(color_num)); wrefresh(show_win); } else { // 打印在线列表 char pos = pt->rbuf[mes_len - 2]; if (pt->name_list[pos][0]) { pt->name_list[pos][0] = 0; } else { strncpy(pt->name_list[pos], pt->rbuf, mes_len - 2); } int i = 0, ll = 0; werase(people_win); for (i = 0; i < 128; ++i) { if (pt->name_list[i][0]) { wattron(people_win, COLOR_PAIR(pt->name_list[i][0] % 5)); mvwprintw(people_win, ll++, 0, "%s", pt->name_list[i]); wattroff(people_win, COLOR_PAIR(pt->name_list[i][0] % 5)); wrefresh(people_win); } } } } }
/* $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; }
request_t requestParse(request_t request) { int fd = request.connfd; int is_static; struct stat stat_buf; 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); printf("%s %s %s\n", method, uri, version); if (strcasecmp(method, "GET")) { requestError(fd, method, "501", "Not Implemented", "CS537 Server does not implement this method"); request.is_static = -1; return request; } requestReadhdrs(&rio); is_static = requestParseURI(uri, filename, cgiargs); if (stat(filename, &stat_buf) < 0) { requestError(fd, filename, "404", "Not found", "CS537 Server could not find this file"); request.is_static = -1; return request; } if (is_static) { if (!(S_ISREG(stat_buf.st_mode)) || !(S_IRUSR & stat_buf.st_mode)) { requestError(fd, filename, "403", "Forbidden", "CS537 Server could not read this file"); request.is_static = -1; return request; } } else { if (!(S_ISREG(stat_buf.st_mode)) || !(S_IXUSR & stat_buf.st_mode)) { requestError(fd, filename, "403", "Forbidden", "CS537 Server could not run this CGI program"); request.is_static = -1; return request; } } // save relevant information for handling the request later strcpy(request.filename, filename); strcpy(request.cgiargs, cgiargs); request.stat_buf = stat_buf; request.is_static = is_static; request.file_size = stat_buf.st_size; return request; }