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; }
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; }
void preRequestHandle(request* req) { int fd = req->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); 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; } 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; } req->ready = 1; req->sbuf = sbuf; req->is_static = is_static; req->cgiargs = cgiargs; /* TODO: Free req->filename in worker thread */ req->filename = malloc(sizeof(char)*MAXLINE); strncpy(req->filename, filename, MAXLINE); }
// handle a request void requestHandle(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); 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; } 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; } if (is_static) { if (!(S_ISREG(sbuf.st_mode)) || !(S_IRUSR & sbuf.st_mode)) { requestError(fd, filename, "403", "Forbidden", "CS537 Server could not read this file"); return; } requestServeStatic(fd, filename, sbuf.st_size); } else { if (!(S_ISREG(sbuf.st_mode)) || !(S_IXUSR & sbuf.st_mode)) { requestError(fd, filename, "403", "Forbidden", "CS537 Server could not run this CGI program"); return; } requestServeDynamic(fd, filename, cgiargs); } }
//For getting file information, needed to modify request.h for this to work server_request getFileStat(int fd){ server_request stats; 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); 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 stats; } 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 stats; } stats.is_static = is_static; stats.sbuf =sbuf; memcpy (stats.buf,buf,MAXLINE); memcpy (stats.method, method,MAXLINE); memcpy (stats.uri,uri,MAXLINE); memcpy (stats.version,version,MAXLINE); memcpy (stats.filename,filename,MAXLINE); memcpy (stats.cgiargs,cgiargs,MAXLINE); stats.rio=rio; return stats; }
int main(int argc, char *argv[]) { int listenfd, connfd, port, clientlen, numworkers; char *sched; struct sockaddr_in clientaddr; struct stat sbuf; pthread_mutex_init(&m, NULL); // lock for producer and consumer loops pthread_cond_init(&empty, NULL); // CV for master/producer to wait on pthread_cond_init(&fill, NULL); // CV for workers/consumers to wait on getargs(&port, &numworkers, &bufsize, &sched, argc, argv); // // CS537: Create some threads... // pthread_t threads[numworkers]; // array of worker threads int i; for (i = 0; i < numworkers; i++) { pthread_create(&threads[i], NULL, consumer, NULL); } listenfd = Open_listenfd(port); while (1) { clientlen = sizeof(clientaddr); connfd = Accept(listenfd, (SA *)&clientaddr, (socklen_t *) &clientlen); pthread_mutex_lock(&m); buff_t* newNode = malloc(sizeof(buff_t)); newNode->fd = connfd; Rio_readinitb(&((*newNode).rio), newNode->fd); Rio_readlineb(&((*newNode).rio), newNode->buf, MAXLINE); sscanf(newNode->buf, "%s %s %s", newNode->method, newNode->uri, newNode->version); requestReadhdrs(&((*newNode).rio)); newNode->is_static = requestParseURI(newNode->uri, newNode->filename, newNode->cgiargs); stat(newNode->filename, &sbuf); newNode->filesize = sbuf.st_size; newNode->filenamesize = strlen(newNode->filename); //newNode->cgiargs = cgiargs; while(numrequests == bufsize) { pthread_cond_wait(&empty, &m); } if (strcmp(sched, "FIFO") == 0) { fill_buff(newNode); } else if (strcmp(sched, "SFNF") == 0) { fill_buff2(newNode); } else if (strcmp(sched, "SFF") == 0) { fill_buff3(newNode); } pthread_cond_signal(&fill); pthread_mutex_unlock(&m); //fprintf(stderr, "numrequests: %d\n", numrequests); // // CS537: In general, don't handle the request in the main thread. // Save the relevant info in a buffer and have one of the worker threads // do the work. However, for SFF, you may have to do a little work // here (e.g., a stat() on the filename) ... // //requestHandle(connfd); //Close(connfd); } }