void load_mnist_dataset_blas(dataset_blas *train_set, dataset_blas *validate_set){ uint32_t N, nrow, ncol, magic_n; rio_t rio_train_x, rio_train_y; int train_x_fd, train_y_fd; int train_set_size = 50000, validate_set_size = 10000; int i, nlabel = 10; train_x_fd = open("../data/train-images-idx3-ubyte", O_RDONLY); train_y_fd = open("../data/train-labels-idx1-ubyte", O_RDONLY); if(train_x_fd == -1){ fprintf(stderr, "cannot open train-images-idx3-ubyte\n"); exit(1); } if(train_y_fd == -1){ fprintf(stderr, "cannot open train-labels-idx1-ubyte\n"); exit(1); } rio_readinitb(&rio_train_x, train_x_fd, 0); rio_readinitb(&rio_train_y, train_y_fd, 0); read_uint32(&rio_train_x, &magic_n); read_uint32(&rio_train_x, &N); read_uint32(&rio_train_x, &nrow); read_uint32(&rio_train_x, &ncol); read_uint32(&rio_train_y, &magic_n); read_uint32(&rio_train_y, &N); #ifdef DEBUG printf("magic number: %u\nN: %u\nnrow: %u\nncol: %u\n", magic_n, N, nrow, ncol); fflush(stdout); #endif init_dataset_blas(train_set, train_set_size, nrow, ncol, nlabel); init_dataset_blas(validate_set, validate_set_size, nrow, ncol, nlabel); load_dataset_blas_input(&rio_train_x, train_set); load_dataset_blas_output(&rio_train_y, train_set); for(i = 0; i < train_set->N; i++){ train_set->label[i*nlabel + train_set->output[i]] = 1; } load_dataset_blas_input(&rio_train_x, validate_set); load_dataset_blas_output(&rio_train_y, validate_set); //print_dataset(&validate_set); close(train_x_fd); close(train_y_fd); }
void echo(int connfd){ size_t n; char buf[MAXLINE]; rio_t rio; rio_readinitb(&rio, connfd); if((n = rio_readlineb(&rio, buf, MAXLINE)) < 0){ fprintf(stderr, "rio_readlineb error \n"); exit(0); } while(n != 0){ printf("server received %d bytes\n", n); if(rio_writen(connfd, buf, n) != n){ fprintf(stderr, "rio_writen error\n"); exit(0); } if((n = rio_readlineb(&rio, buf, MAXLINE)) < 0){ fprintf(stderr, "rio_readlineb error \n"); exit(0); } } }
/* * sends the request then it gets data from the outside server then sends to outside client */ void* doit(void * data){ struct treadInfo *thread=(struct doitInfo *)data; int portValue=0; int *port=&portValue; //ignore SIGPIPE singal signal(SIGPIPE, SIG_IGN); //builds the request from client struct requestInfo getRequest=request(thread,port); //connecting to server if fails closes //need to change to own function (*thread).serverfd=serverConnection((char *)getRequest.hostname,*getRequest.port,thread); //prints out the request will add to request function printf("Thread %d: Forwarding request to end server:\n",(*thread).ID); printf("%s",(char *)getRequest.request); printf("*** End of Request ***\n\n"); //set Rio rio_readinitb(&(*thread).rioWithServer,(*thread).serverfd); //send request rio_writen_w((*thread).serverfd,getRequest.request,strlen((const char *)getRequest.request),thread); //transfer recieved data from server to client transferData(thread); //should never reach this exit() exit(0); }
void add_client(int connfd, Pool *p) { int i; p->nready--; for(i = 0; i < FD_SETSIZE; i++){ if(p->clientfd[i] < 0){ /* add connected descriptor to the pool */ p->clientfd[i] = connfd; rio_readinitb(&p->clientrio[i], connfd); /* add the descriptor to descriptor set */ FD_SET(connfd, &p->read_set); if(connfd > p->maxfd) p->maxfd = connfd; if(i > p->maxi) p->maxi = i; break; } } if(i == FD_SETSIZE){ fprintf(stderr, "add_client error: too many clients!\n"); exit(1); } }
int forward_request(int client_fd, Request *request, Response *response) { rio_t server_rio; int server_fd; char hostname[MAXLINE]; int port = 80; port = extract_port_number(request->request_str); extract_hostname(request->host_str, hostname); #ifdef DEBUG printf("hostname:%s\n", hostname); printf("port:%d\n", port); #endif if ((server_fd = open_clientfd(hostname, port)) < 0) { fprintf(stderr, "Warning connection refused !\n"); return -1; } rio_readinitb(&server_rio, server_fd); #ifdef DEBUG printf("request_str:%s", request->request_str); #endif rio_writen(server_fd, request->request_str, strlen(request->request_str)); rio_writen(server_fd, request->host_str, strlen(request->host_str)); rio_writen(server_fd, "\r\n", strlen("\r\n")); forward_response(client_fd, server_fd, response); Close(server_fd); return 1; }
void doit(int fd) { int clientfd, port, size = 0; ssize_t linecounter; rio_t client_rio, server_rio; char buf[MAXLINE], method[MAXLINE], uri[MAXLINE], version[MAXLINE], serveraddr[MAXLINE], path[MAXLINE], message[MAXLINE]; //read the HTTP request rio_readinitb(&client_rio, fd); rio_readlineb(&client_rio, buf, MAXLINE); sscanf(buf, "%s %s %s", method, uri, version); if(strcasecmp(method, "GET") != 0) { clienterror(fd, method, "501", "Not Implemented", "Proxy does not implement this method"); return; } read_requesthdrs(&client_rio); //parse it to determine the name of the end server port = parse_uri(uri, serveraddr, path); //filter if(is_blocked_address(serveraddr)) { clienterror(fd, serveraddr, "403", "Forbidden", "Proxy does not access this server"); return; } //open a connection to the end server if((clientfd = open_clientfd(serveraddr, port)) < 0) { clienterror(fd, serveraddr, "404", "Not Found", "Proxy does not found this server"); return; } //send it the request sprintf(message, "GET %s HTTP/1.0\r\n", path); rio_writen(clientfd, message, strlen(message)); sprintf(message, "HOST: %s\r\n\r\n", serveraddr); rio_writen(clientfd, message, strlen(message)); //receive the reply, and forward the reply to the browser if the request is not blocked. rio_readinitb(&server_rio, clientfd); while((linecounter = rio_readlineb(&server_rio, message, MAXLINE)) != 0) { rio_writen(fd, message, linecounter); size += linecounter; } //log sem_wait(&mutex); log_report(serveraddr, size); sem_post(&mutex); }
void echo(int connfd){ size_t n; char buf[MAXLINE]; rio_t rio; rio_readinitb(&rio,connfd); while((n=rio_readlineb(&rio,buf,MAXLINE))!=0){ printf("server received %d bytes\n",n); rio_writen(connfd,buf,n); } }
void read_msg(int fd, char *recvbuf) { rio_t rp; int ret = 0; rio_readinitb(&rp,fd); int length = 1; length = rio_readlineb(&rp,recvbuf,MAX_MSG_LEN); if(length<=0) printf("end!!!"); return; }
/* miss_handler handles miss case. It passes client's request * to server and passes server's response to client. If the * response satisfies size requirements, store the response * into cache. */ void miss_handler(int clientfd, struct client_request *request) { int serverfd, length, response_size; char buf[MAXBUF], object_buf[MAX_OBJECT_SIZE]; struct cache_cell *cell; rio_t rio_server; response_size = length = 0; /* acts as a client and writes request to server */ Pthread_mutex_lock(&open_mutex); serverfd = open_serverfd_h(request, clientfd); Pthread_mutex_unlock(&open_mutex); rio_readinitb(&rio_server, serverfd); if (rio_writen(serverfd, request->request, request->request_length) != request->request_length) { write(2, "write error\n", strlen("write error\n")); close_connection(request, clientfd, serverfd); } /* passes server's response to client */ while (1) { if ((length = rio_readnb(&rio_server, buf, MAXBUF)) < 0) close_connection(request, clientfd, serverfd); if (response_size + length <= MAX_OBJECT_SIZE) memcpy(object_buf + response_size, buf, length); response_size += length; if (rio_writen(clientfd, buf, length) < length) break; if (length != MAXBUF) break; } /* if response satisfies size requirement, store the response * into cache */ if (response_size <= MAX_OBJECT_SIZE) { /* need a mutex to prevent inserting the same cell twice * into cache in race condition */ Pthread_mutex_lock(&dup_mutex); if (search_cell_variant(request->request_line) == 0) { cell = allocate_cell(); set_cell(cell, request->request_line, object_buf, response_size); add_to_list(cell); } Pthread_mutex_unlock(&dup_mutex); } close_connection(request, clientfd, serverfd); }
/* parse_request parses request from client and stores the * information in a client_request structure */ int parse_request(struct client_request *request, int clientfd) { char buf[MAXBUF], method[MAXLINE], uri[MAXLINE], port[MAXLINE], *ptr; rio_t rio; port[0] = 0; rio_readinitb(&rio, clientfd); rio_readlineb(&rio, buf, MAXLINE - 1); if (sscanf(buf, "%s %s %*s", method, uri) < 2) { printf("parsing error %s\n", buf); return -1; } strcpy(request->request_line, buf); if (sscanf(uri, "http://%[^:/]:%[^/]/%*s", request->host, port) < 1) return -1; if (*port == 0) request->server_port = 80; else request->server_port = atoi(port); if (strcmp(method, "GET")) return -2; sprintf(request->request, "GET %s HTTP/1.0\r\nHost: %s\r\n", uri, request->host); /* reads all headers */ while (1) { rio_readlineb(&rio, buf, MAXLINE - 1); /* need to change connection header to close */ if ((ptr = strstr(buf, "Connection:")) != NULL) { strcat(request->request, "Connection: close\n"); continue; } /* need to delete keep-alive header */ if ((ptr = strcasestr(buf, "keep-alive")) != NULL) continue; /* host is already in the header */ if ((ptr = strstr(buf, "Host:")) != NULL) continue; strcat(request->request, buf); if (*buf == '\r' && *(buf + 1) == '\n') break; } request->request_length = strlen(request->request); return 0; }
int main() { int n; rio_t rio; char buf[MAXLINE]; rio_readinitb(&rio, STDIN_FILENO); whle((n= rio_readn(&rio, buf, MAXBUF)) != 0) Rio_writen(STDOUT_FILENO, buf, MAXBUF); return 0; }
int main(int argc, char ** argv) { int n; rio_t rio; char buf[MAXBUF]; printf("%d\n",MAXBUF); rio_readinitb(&rio, STDIN_FILENO); while((n = rio_readnb(&rio, buf, MAXBUF)) != 0) { rio_writen(STDOUT_FILENO, buf, n); } return 0; }
void echo(int fd) { size_t n; char buf[MAXLINE]; rio_t rio; rio_readinitb(&rio, fd); while((n = rio_readlineb(&rio, buf, MAXLINE)) != 0) { printf("server received %d bytes\n", n); memset(buf, 0, MAXLINE); snprintf(buf, sizeof(buf), "server roger that\n"); rio_writen(fd, buf, strlen(buf)); } }
void *proxy(void *vargp) { Pthread_detach(Pthread_self()); int serverfd; int clientfd = *(int *)vargp; free(vargp); rio_t rio; rio_readinitb(&rio, clientfd); struct status_line status; char buf[MAXLINE]; int flag; #ifdef PROXY_CACHE char objectbuf[MAX_OBJECT_SIZE]; #endif if ((flag = rio_readlineb(&rio, buf, MAXLINE)) > 0) { if (parseline(buf, &status) < 0) fprintf(stderr, "parseline error: '%s'\n", buf); #ifdef PROXY_CACHE else if (cacheable(&status) && (flag = cache_find(status.line, objectbuf))) { if (rio_writen(clientfd, objectbuf, flag) < 0) log(cache_write); } #endif else if ((serverfd = open_clientfd(status.hostname, status.port)) < 0) log(open_clientfd); else { if ((flag = send_request(&rio, buf, &status, serverfd, clientfd)) < 0) log(send_request); else if (interrelate(serverfd, clientfd, buf, flag #ifdef PROXY_CACHE ,objectbuf, &status #endif ) < 0) log(interrelate); close(serverfd); } } close(clientfd); return NULL; }
/* * forward_request - send request from client to its destination server */ int forward_request(int client_fd, Request *request, Response *response) { rio_t server_rio; int server_fd; char hostname[MAXLINE]; int port = 80; extract_hostname_port(request->host_str, hostname, &port); #ifdef DEBUG printf("extract hostname:%s\n", hostname); printf("extract port:%d\n", port); #endif if ((server_fd = open_clientfd(hostname, port)) < 0) { sleep(2); if ((server_fd = open_clientfd(hostname, port)) < 0) { sleep(2); if ((server_fd = open_clientfd(hostname, port)) < 0) { proxy_error(strcat(hostname, " connection refuesed")); close(server_fd); return -1; } } } rio_readinitb(&server_rio, server_fd); #ifdef DEBUG printf("request_str:%s", request->request_str); #endif rio_writen(server_fd, request->request_str, strlen(request->request_str)); rio_writen(server_fd, request->host_str, strlen(request->host_str)); /* send cookie to server */ if (request->cookie_size != 0) { rio_writen(server_fd, request->cookie, request->cookie_size); } /* send user-agent info to server */ if (request->user_agent_size != 0) { rio_writen(server_fd, request->user_agent, request->user_agent_size); } rio_writen(server_fd, "\r\n", strlen("\r\n")); if (forward_response(client_fd, server_fd, response) < 0) { close(server_fd); return -1; } close(server_fd); return 1; }
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")) { clienterror(fd,method,"501","Not Implemented", "Tiny does not implement this method"); return; } read_requesthdrs(&rio); 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 could'n 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 could'nt run the CGI program"); return; } serve_dynamic(fd,filename,cgiargs); } }
void dump_model(crbm *m, char *filename){ rio_t rio_model; int fd_model; if((fd_model = open(filename, O_WRONLY | O_TRUNC | O_CREAT, S_IRWXU)) == -1){ printf("open %s failed\n", filename); } rio_readinitb(&rio_model, fd_model, 1); rio_writenb(&rio_model, &m->nvisible, sizeof(int)); rio_writenb(&rio_model, &m->nhidden, sizeof(int)); rio_writenb(&rio_model, &m->ncat, sizeof(int)); rio_writenb(&rio_model, m->w, m->nvisible * m->nhidden * sizeof(double)); rio_writenb(&rio_model, m->u, m->ncat * m->nhidden * sizeof(double)); rio_writenb(&rio_model, m->bv, m->nvisible * sizeof(double)); rio_writenb(&rio_model, m->bh, m->nhidden * sizeof(double)); rio_writenb(&rio_model, m->by, m->ncat * sizeof(double)); close(fd_model); }
void *nodeTalk(void* args){ int numBytes,clientfd,Bport; rio_t client; int num; clientfd = ((int*)args)[0]; Bport = ((int*)args)[1]; num = ((int*)args)[2]; rio_readinitb(&client,clientfd); char request[MAXLINE]; numBytes = rio_readp(clientfd,request,MAXLINE); printf("message received through listening port is %s\n",request); char ans[MAXLINE]; sprintf(ans,"hello client this is server"); rio_writen(clientfd,ans,sizeof(ans)); close(clientfd); return NULL; }
int read_blocked_address() { int fd, n, num_addr = 0; rio_t rio; char buf[MAXLINE]; if((fd = open(FILTER_FILE, O_RDONLY, 0)) < 0) { fprintf(stderr, "Proxy does not found filter file"); exit(1); } rio_readinitb(&rio, fd); while((n = rio_readlineb(&rio, buf, MAXLINE)) > 0) { strncpy(blocked_address[num_addr], buf, n - 1); /* 忽略结尾的换行符 */ num_addr++; } close(fd); return num_addr; }
/* * main - Main routine for the proxy program runs the proxy server */ int main(int argc, char **argv) { int listenfd, connfd, clientlen, ID=0; struct sockaddr_in clientaddr; struct sockaddr_in * passClientaddr=&clientaddr; struct hostent *hp; char *haddrp; pthread_t tid[MAXTREAD]; /* Check arguments */ if(argc != 2){ fprintf(stderr, "Usage: %s <port number>\n", argv[0]); exit(0); } signal(SIGPIPE, SIG_IGN); listenfd=Open_listenfd(atoi(argv[1])); while(1){ clientlen =sizeof(clientaddr); connfd = Accept(listenfd, (SA *)&clientaddr,(unsigned int *)&clientlen); //Determine the domain name and IP address of the client then send print statement hp=Gethostbyaddr((const char *)&clientaddr.sin_addr.s_addr, sizeof(clientaddr.sin_addr.s_addr), AF_INET); haddrp =inet_ntoa(clientaddr.sin_addr); printf("Thread %d: Receieved request from %s (%s):\n",ID,hp->h_name,haddrp); //make and set known data to thread struct treadInfo thread; thread.clientfd=connfd; rio_readinitb(&thread.rioWithClient,thread.clientfd); thread.ID=ID; thread.sockaddr=*passClientaddr; //create new thread Pthread_create(&tid[ID], NULL,doit,&(void *)thread); //add one to ID count ID++; } exit(0); }
void process(int fd, int efd, char *rstline, char *method, char *uri, char *protocol, char *filename, char *filetype, char *response) { rio_t rio; int err; struct stat sbuf; char *file; rio_readinitb(&rio, fd); if((err = rio_readlineb(&rio, rstline, MAXLEN)) <= 0) { if((err = epoll_ctl(efd, EPOLL_CTL_DEL, fd, NULL)) < 0) FATAL("PROCESS.EPOLL_CTL"); close(fd); } else { sscanf(rstline, "%s %s %s", method, uri, protocol); if(strcasecmp(method, "GET")) //TEST ERR(fd, efd); if(uri[0] != '/') ERR(fd, efd); process_rstheader(&rio); parse_uri(uri, filename, filetype); if(get_fileinfo(filename) < 0) call_403(fd); else { lstat(filename, &sbuf); err = open(filename, O_RDONLY, 0); file = mmap(0 ,sbuf.st_size, PROT_READ, MAP_PRIVATE, err, 0); close(err); sprintf(response, "HTTP/1.1 200 OK\r\n"); sprintf(response, "%sContent-length: %lu\r\n", response, sbuf.st_size); sprintf(response, "%sContent-type: %s\r\n\r\n", response, filetype); rio_writen(fd, response, strlen(response)); rio_writen(fd, file, sbuf.st_size); munmap(file, sbuf.st_size); } } }
/****************************************************************************** * subroutine: add_client * * purpose: add a new client to the pool and update pool attributes * * parameters: client_fd - the descriptor of new client * * p - pointer to pool instance * * return: 0 on success, -1 on failure * ******************************************************************************/ int add_client(int client_fd, pool *p) { int i; p->nready--; if (STATE.is_full) return -1; // only accept FD_SETSIZE - 5 clients to keep server from overloading for (i=0; i<(FD_SETSIZE - 5); i++) { if (p->clientfd[i] < 0) { // add client descriptor to the pool p->clientfd[i] = client_fd; // add the descriptor to the descriptor set FD_SET(client_fd, &p->read_set); // add read buf rio_readinitb(&p->clientrio[i], client_fd); // update max descriptor and pool highwater mark if (client_fd > p->maxfd) p->maxfd = client_fd; if (i > p->maxi) p->maxi = i; break; } } if (i == (FD_SETSIZE - 5)) { STATE.is_full = 1; Log ("Error: too many clients. \n"); return -1; } return 0; }
void parse_request_header(int client_fd, Request *request) { size_t n; rio_t client_rio; char buffer[MAXLINE]; rio_readinitb(&client_rio, client_fd); copy_single_line_str(&client_rio, request->request_str); copy_single_line_str(&client_rio, request->host_str); #ifdef DEBUG printf("request str:%s", request->request_str); printf("host str: %s", request->host_str); #endif while ((n = rio_readlineb(&client_rio, buffer, MAXLINE)) != 0) { #ifdef DEBUG printf("%s", buffer); #endif if (!strcmp(buffer, "\r\n")) { break; } } }
void home_page(char *host, char *fname) { int fd, n; char line[MAXLINE]; rio_t rio; fd = tcpConnect(host, SERV); /* blocking connect() */ n = snprintf(line, sizeof(line), GET_CMD, fname,host); rio_writen(fd, line, n); rio_readinitb(&rio, fd); while ((n = rio_readlineb(&rio, line, sizeof(line))) > 1) { if (strcmp(line,END_OF_HTML) == 0) { break; } parseUrl(line,host); } printf("end-of-file on home page\n"); close(fd); }
void load_model(crbm *m, char *filename){ rio_t rio_model; int fd_model; if((fd_model = open(filename, O_RDONLY)) == -1){ printf("open %s failed\n", filename); } rio_readinitb(&rio_model, fd_model, 0); rio_readnb(&rio_model, &m->nvisible, sizeof(int)); rio_readnb(&rio_model, &m->nhidden, sizeof(int)); rio_readnb(&rio_model, &m->ncat, sizeof(int)); m->w = (double*)malloc(m->nhidden * m->nvisible * sizeof(double)); m->u = (double*)malloc(m->nhidden * m->ncat * sizeof(double)); m->bv = (double*)malloc(m->nvisible * sizeof(double)); m->bh = (double*)malloc(m->nhidden * sizeof(double)); m->by = (double*)malloc(m->ncat * sizeof(double)); rio_readnb(&rio_model, m->w, m->nvisible * m->nhidden * sizeof(double)); rio_readnb(&rio_model, m->u, m->ncat * m->nhidden * sizeof(double)); rio_readnb(&rio_model, m->bv, m->nvisible * sizeof(double)); rio_readnb(&rio_model, m->bh, m->nhidden * sizeof(double)); rio_readnb(&rio_model, m->by, m->ncat * sizeof(double)); close(fd_model); }
void *do_get_read(void *vptr) { int fd, n; char line[MAXLINE]; struct file *fptr; rio_t rio; fptr = (struct file *) vptr; fd = tcpConnect(fptr->f_host, SERV); fptr->f_fd = fd; printf("do_get_read for name:%s host:%s, fd %d, thread %d\n", fptr->f_name,fptr->f_host, fd, fptr->f_tid); write_get_cmd(fptr); /* write() the GET command */ rio_readinitb(&rio,fd); while((n = rio_readlineb(&rio,line,sizeof(line))) > 1) { printf("read %d bytes from name:%s host:%s\n", n, fptr->f_name,fptr->f_host); if (strcmp(line, END_OF_HTML) == 0) { break; } parseUrl(line,fptr->f_host); } printf("end-of-file on name:%s host:%s\n", fptr->f_name,fptr->f_host); close(fd); fptr->f_flags = F_DONE; /* clears F_READING */ pthread_mutex_lock(&ndone_mutex); ndone++; pthread_cond_signal(&ndone_cond); pthread_mutex_unlock(&ndone_mutex); return(fptr); /* terminate thread */ }
/* * parse_request_header - parse request header extract useful information */ void parse_request_header(int client_fd, Request *request) { size_t n; rio_t client_rio; char buffer[MAXLINE]; rio_readinitb(&client_rio, client_fd); copy_single_line_str(&client_rio, request->request_str); copy_single_line_str(&client_rio, request->host_str); #ifdef DEBUG printf("request str:%s", request->request_str); printf("host str: %s", request->host_str); #endif request->cookie_size = 0; request->user_agent_size = 0; while ((n = rio_readlineb(&client_rio, buffer, MAXLINE)) != 0) { /* store cookie info for later use */ if (strstr(buffer, "Cookie:") != NULL) { strncpy(request->cookie, buffer, n); request->cookie_size = n; } /* store user-agent info for later use */ if (strstr(buffer, "User-Agent:") != NULL) { strncpy(request->user_agent, buffer, n); request->user_agent_size = n; } #ifdef DEBUG printf("%s", buffer); #endif if (!strcmp(buffer, "\r\n")) { break; } } }
// parse request to get url int parse_request(int fd, http_request *req){ // Rio (Robust I/O) Buffered Input Functions rio_t rio; rio_readinitb(&rio, fd); req->browser_index = -1; // read all char usrbuf[MAXLINE]; if (rio_readlineb(&rio, usrbuf, sizeof(usrbuf)) <= 0) { //no data in the socket or read error occurs printf("First line is invalid!\n"); return -1; } char *token = strtok(usrbuf, " "); if (0 != strncmp(token, "GET", strlen("GET"))) { //request method is not get printf("The method is not GET!\n"); return -1; } token = strtok(NULL, " "); if (0 == strncmp(token, "/favicon.ico", strlen("/favicon.ico"))) { //fake socket sent by Chrome printf("Additional socket!\n"); return -1; } // decode url char cwd[MAXLINE] = {0}; getcwd(cwd, MAXLINE); strcpy(req->filename, strcat(cwd, token)); //detect user agent to find out the type of browser while (-1 == req->browser_index && rio_readlineb(&rio, usrbuf, sizeof(usrbuf)) > 0) { if (0 == strncmp(usrbuf, "User-Agent", strlen("User-Agent"))) { token = strtok(usrbuf, " "); while ((token = strtok(NULL, " ")) != NULL) { if (-1 == req->browser_index) { int i; for (i = 0; i < browser_number; i++) { if (0 == strncmp(token, browser_name[i], strlen(browser_name[i]))) { // update recent browser data req->browser_index = i; } } } } } } if (-1 == req->browser_index) { //no browser type has been found printf("Browser type not identified!\n"); return -1; } return 0; }
void Rio_readinitb(rio_t *rp, int fd) { rio_readinitb(rp, fd); }
void forward_response(int client_fd, int server_fd, Response *response) { #ifdef DEBUG printf("enter forward_response\n"); #endif size_t n; int length = -1; char header_buffer[MAXLINE]; char content_buffer[MAX_OBJECT_SIZE]; int read_size; rio_t server_rio; int header_line = 0; int move_flag = 0; char move_new_address[MAXLINE]; rio_readinitb(&server_rio, server_fd); while ((n = rio_readlineb(&server_rio, header_buffer, MAXLINE)) != 0) { strcat(response->header, header_buffer); //parse response //if return status code is 3XX //address moved. //need to send another request to the indicated place //until get 2XX or 4XX or 5XX. header_line ++; //status code 3XX if((header_line == 1) && (header_buffer[state_offset] == '3')) { move_flag =1; } if((move_flag == 1) && strstr(header_buffer,"Location:")) { //moved to new address. //I suggest change the address in request and return. then send request again. strcat(move_new_address, (header_buffer+move_offset)); } //add exit here /* if (rio_writen(client_fd, header_buffer, n) < 0) { proxy_error("rio_writen in forward_response header error"); }*/ if (strstr(header_buffer, "Content-Length: ")) { sscanf(header_buffer + 16, "%d", &length); } if (!strcmp(header_buffer, "\r\n")) { break; } } if (length == -1) read_size = MAX_OBJECT_SIZE; else read_size = min(length, MAX_OBJECT_SIZE); #ifdef DEBUG printf("finish response header\n"); #endif int sum = 0; while ((n = rio_readnb(&server_rio, content_buffer, read_size)) != 0) { if (rio_writen(client_fd, content_buffer, n) < 0) { proxy_error("rio_writen in forward_response content error"); Close(client_fd); } sum += n; } #ifdef DEBUG printf("read byte size:%u\n", sum); #endif if (sum <= MAX_OBJECT_SIZE) { response->content = Malloc(sizeof(char) * sum); memcpy(response->content, content_buffer, sum * sizeof(char)); response->content_size = sum; } else { response->content_size = sum; } #ifdef DEBUG printf("leave forward_response\n"); #endif }