Ejemplo n.º 1
0
int main(int argc, char **argv) 
{   
    if(!(argc >=2) ) //If commandline args are not provided
    {
      printf("No file provided\n");
      return -1;
    }
    
    //Use csapp Open to get fd number (creates files)
    int fd = Open(argv[1],O_CREAT | O_WRONLY,0);
  
    int n; //Number of bytes
    rio_t rio; //RIO type that contains file info
    char buf[MAXLINE]; //Character buffer with max size defined by csapp

    //Associate a descriptor with a read buffer and reset buffer 
    //the POSIX <unistd.h> definition is STDIN_FILENO
    Rio_readinitb(&rio,STDIN_FILENO); 
    
    while((n = rio_readnb(&rio, buf, MAXLINE)) != 0) //While it has read more than zero bytes
    {
	Rio_writen(fd, buf, n);//Write n bytes from buf
    }
    
    Close(fd);
    
    exit(0);
}
Ejemplo n.º 2
0
ssize_t Rio_readnb(rio_t *rp, void *usrbuf, size_t n) {
	ssize_t rc;

	if ((rc = rio_readnb(rp, usrbuf, n)) < 0)
		unix_error("Rio_readnb error");
	return rc;
}
Ejemplo n.º 3
0
ssize_t Rio_readnb_s(rio_t *rp, void *usrbuf, size_t n){
    ssize_t rc;
    if ((rc = rio_readnb(rp, usrbuf, n)) < 0){
		printf("Rio_readnb error\n");
		rc = 0;
	}
    return rc;	
}
Ejemplo n.º 4
0
void load_dataset_output(rio_t *rp, dataset *d){
    int i;
    uint8_t label;
    
    for(i = 0; i < d->N; i++){
        rio_readnb(rp, &d->output[i], sizeof(uint8_t));
    }
}
Ejemplo n.º 5
0
ssize_t Rio_readnb(rio_t *rp, void *usrbuf, size_t n)
{
	ssize_t rt;
	rt = rio_readnb(rp, usrbuf, n);
	if (rt == -1)
		unix_error("Rio_readnb error");
	return rt;
}
Ejemplo n.º 6
0
void load_dataset_blas_output(rio_t *rp, dataset_blas *d){
    int i;
    uint8_t label;
    
    for(i = 0; i < d->N; i++){
        rio_readnb(rp, &d->output[i], sizeof(uint8_t));
        d->label[i*d->nlabel + d->output[i]] = 1;
    }
}
Ejemplo n.º 7
0
ssize_t Rio_readnb(rio_t *rp, void *usrbuf, size_t n) 
{
    ssize_t rc;

    if ((rc = rio_readnb(rp, usrbuf, n)) < 0) {
        if (errno != ECONNRESET)
	    unix_error("Rio_readnb error");
    }
    return rc;
}
Ejemplo n.º 8
0
/* 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);
}
Ejemplo n.º 9
0
ssize_t Rio_readnb(rio_t *rp, void *usrbuf, size_t n) {
	ssize_t rc;
	int max=3;
	while (((rc = rio_readnb(rp, usrbuf, n)) < 0)) {
		sleep(1);
		max--;	
		if (max==0){
			return -1;
		}
	}
	return rc;
}
Ejemplo n.º 10
0
Archivo: 11.7.c Proyecto: 0x0nil/csapp
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;
}
Ejemplo n.º 11
0
ssize_t Rio_readnb(rio_t *rp, void *usrbuf, size_t n) 
{
    ssize_t rc;

    if ((rc = rio_readnb(rp, usrbuf, n)) < 0) {
	// we ran into an error
	if (errno == ECONNRESET) {
	    printf("The Connection was reset\n");
	    pthread_exit(NULL);
	    return 0;
	    //return rc;
	}
	unix_error("Rio_readnb error");
    }
    return rc;
}
Ejemplo n.º 12
0
void load_dataset_blas_input(rio_t *rp, dataset_blas *d){
    int i, j, k;
    int idx;
    uint8_t pixel;

#ifdef DEBUG
    printf("loading input data...\n");
#endif
    for(i = 0; i < d->N; i++){
        for(j = 0; j < d->nrow * d->ncol; j++){
            idx = i * d->nrow * d->ncol + j;
            rio_readnb(rp, &pixel, sizeof(uint8_t));
            d->input[idx] = (double)pixel / 255.0;
        }
    }
#ifdef DEBUG
    printf("data loaded\n");
    fflush(stdout);
#endif
}
Ejemplo n.º 13
0
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);
}
Ejemplo n.º 14
0
int write_cache_and_client (char *request, size_t size)
{
  int value = -1;
  cache_object *cur_object;
  
  P(&nowrite);
  P(&noread);
  if (size <= MAX_OBJECT_SIZE)
  {
    if (rio_readnb(clientrio, buf, size) != -1)
    {
      cur_object = Malloc(sizeof(cur_object));
      cur_object->buf = buf;
      strcpy(cur_object->request, request);
      cur_object->size = size;
      cur_object->next = my_cache->front;
      cur_object->prev = NULL;
      insert(cur_object);
      value = 0;
    }
  }
  V(&noread);
  V(&nowrite)
}
Ejemplo n.º 15
0
/*forward response (lines/headers/body) to client*/
int forward_response(rio_t *rio_server, char *uri, char *resp_buf, int connfd)
{
    char response[MAX_OBJECT_SIZE];
    char resp_body[MAX_OBJECT_SIZE];
    char resp_line[MAXLINE];
    int resp_size = 0;
    int length = 0;
    int body_size = 0;
    int content_len = -1;
    int cont_size = 0;
#if 1
    if((web_load(uri, response)) == 0)
	{
		printf("Cache hit!\n");
		if(rio_writen(connfd, response, sizeof(response)) < 0)
    	{
        		fprintf(stderr, "rio_writen send cache response error\n");
        		return -1;
    	}
    	memset(response, 0, sizeof(response));
        return 0;
	}
#endif
    /*send reponse line and headers to client*/
    while((length = rio_readlineb(rio_server, resp_line, MAXLINE)) > 0)
    {
        strcat(response, resp_line);
        /* send headers to clinet*/
        if (rio_writen(connfd, resp_line, length) < 0) {
            fprintf(stderr, "Error: rio_writen() in forward_response header:  %s\n", strerror(errno));  
            DEBUG_PRINT("Error: rio_writen() in forward_response header\n");
            return -1;
        }
        
        /*empty line between headers and body*/
        if(strcmp(resp_line, "\r\n") == 0)
            break;
        
        /* get size of response body from response header: Content-Length */
        if (strstr(resp_line, "Content-Length: ")) {
            content_len = parse_num(resp_line);
            if(content_len < 0)
            {
                fprintf(stderr, "Error get Content-Length: %s", resp_line);
                DEBUG_PRINT("Error get Content-Length\n");
                Close(connfd);
                return -1;
            }
        }

        memset(resp_line, 0, sizeof(resp_line));
        resp_size += length;
    }



    /*w/o content length in response headers*/
    if(content_len == -1)
        content_len = MAX_OBJECT_SIZE;
    
    cont_size = MIN(content_len, MAX_OBJECT_SIZE);
    
    /* Send response body to client */
#if DEBUG
    /* send fake response body */
    Rio_writen(connfd, test, strlen(test));
#else

    while((length = rio_readnb(rio_server, resp_body, cont_size)) > 0)
    {
        strcat(response, resp_body);
        if (rio_writen(connfd, resp_body, length) < 0) {
            fprintf(stderr, "rio_writen in forward_response body error: %s!", strerror(errno));
            DEBUG_PRINT("rio_writen in forward_response body error!");
            return -1;
        }
        body_size += length;
    }
#endif

#if 1
    resp_size += body_size;
    if(resp_size <= MAX_OBJECT_SIZE)
    {
        if(web_store(uri, response) < 0) //store response in cache
        {
            printf("web_store, cache error!\n");
            return -1;
        }
    }
#endif

#if 0
    srcfd = Open(filename, O_RDONLY, 0);
    srcp = Mmap(0, filesize, PROT_READ, MAP_PRIVATE, srcfd, 0);
    Close(srcfd);
    Rio_writen(fd, srcp, filesize);
    Munmap(srcp, filesize);
#endif
    
    return 0;
}
Ejemplo n.º 16
0
/*
 * Listens for incoming connections on a port number specified on the command 
 * line. Once a connection is established, it reads the entirety of the 
 * request from the client and parse the request. It determines whether the 
 * client has sent a valid HTTP request; if so, it then establishes its own
 * connection to the appropriate web server then requests the object the client
 * specified. Finally, the proxy reads the server’s response and forwards it to 
 * the client.
 */
void doit(int fd)
{
	int isnot_safe;
	char buf[MAXLINE], method[MAXLINE], uri[MAXLINE], version[MAXLINE], 
	temp[MAXLINE], host[MAXLINE], clientheaders[MAXLINE], readRequests[MAXLINE],
	path[MAXLINE];
	char *data = malloc(MAX_OBJECT_SIZE*sizeof(char));
	size_t sizeOfTotalData = 0;
	char *dataBuffer = malloc(MAX_OBJECT_SIZE*sizeof(char));
  char *temporaryData = dataBuffer;
	char* port_pointer;
	int port = 80, len, len2;
	rio_t rio, rio1;
	int serverConn_fd;
  cache_node *fileObj = NULL;
  //cache_node *addFile = malloc(sizeof(cache_node));

	//associates rio with the descriptor
	Rio_readinitb(&rio, fd);
	//reads and flushes the buf with the request
	Rio_readlineb(&rio, buf, MAXLINE);
	
	//parsing the initial request
	isnot_safe = safe_scan(sscanf(buf, "%s %s %s\r\n", method, uri, version));

	if (isnot_safe)
		return;

	//cannot perform if it is not a Get method
    if (strcasecmp(method, "GET")) {
		printf("501 Not Implemented Proxy does not handle this method");
		return;
    }
    //printf("Does it reach here after Get?\n");

    //Parse the URL properly
    if (strstr(uri, "http://"))
    {
        isnot_safe = safe_scan(sscanf(uri, "%[^'/']%s", temp,  uri));

        if (isnot_safe)
        	return;

        memmove(uri, uri+2, strlen(uri));
    }

    //printf("%s\n", uri);
    if(strchr(uri, '/') != NULL) {
		isnot_safe = safe_scan(sscanf(uri, "%[^'/']%s", host, path));

        if (isnot_safe)
        	return;
    }
    else {
    	//if no path is specified then it is just "/".
		strcpy(path, "/");
		strcpy(host, uri);
    }
    //printf("HOST %s\n", host);
    //Get the port if it is specified
    if ((port_pointer = strchr(host, ':')) != NULL){
		isnot_safe = safe_scan(sscanf(port_pointer, ":%d", &port));

        if (isnot_safe)
        	return;

		isnot_safe = safe_scan(sscanf(host, "%[^0-9:]", host));

        if (isnot_safe)
        	return;
    }

    //Look up the object in the cache
    if ((fileObj = find(uri)) != NULL)
    {
      rio_writen(fd, fileObj->file, fileObj->size);
      return;
    }    
    //flush the readRequests associated with the path and host
    sprintf(readRequests, "GET %s HTTP/1.0\r\nHost: %s\r\n", path, host);

    //open a server connection with the host and port
    serverConn_fd = Open_clientfd(host, port);

    //associate the file descriptor and write to it from readRequests
    
    Rio_readinitb(&rio1, serverConn_fd);
    isnot_safe = safe_rio(rio_writen(serverConn_fd, readRequests, 
    						strlen(readRequests)));

    if (isnot_safe)
        return;

    //Send in all necessary headers
    isnot_safe = safe_rio(rio_writen(serverConn_fd, (void *) user_agent_hdr, 
                                                  strlen(user_agent_hdr)));

    if (isnot_safe)
        return;

    isnot_safe = safe_rio(rio_writen(serverConn_fd, (void *) accept_hdr, 
                                                  strlen(accept_hdr)));

    if (isnot_safe)
        return;

    isnot_safe = safe_rio(rio_writen(serverConn_fd, 
                (void *) accept_encoding_hdr, strlen(accept_encoding_hdr)));

    if (isnot_safe)
        return;

    isnot_safe = safe_rio(rio_writen(serverConn_fd,
      "Proxy-Connection: close\r\nConnection:\tclose\r\n\r\n", 52));

    if (isnot_safe)
        return;


    //Get additional requests by clients that are not already passed and 
    //pass them through without changing them
    while((len = rio_readlineb(&rio, readRequests, MAXBUF)) && 
    			strcmp(readRequests, "\r\n"))
    {
      //Get the headers
	    isnot_safe = safe_scan(sscanf(readRequests, "%s ",clientheaders));

        if (isnot_safe)
        	return;

        //see if the headers are not the ones we already passed.
	    if(!strstr(clientheaders, "Host:")&& !strstr(clientheaders,"Connection:")
        && !strstr(clientheaders, "User-Agent:") && !strstr(clientheaders,
          "Accept-Encoding:") && !strstr(clientheaders,"Accept:") && 
        !strstr(clientheaders,"Proxy-Connection:"))

	    {

	        isnot_safe = safe_rio(rio_writen(serverConn_fd, readRequests, len));
			
        	if (isnot_safe)
        		return;	   	
    	}
  	}


  //Finally write to the client desciptor what the server responds with
  while((len2 = rio_readnb(&rio1, data, MAXLINE))){
    sizeOfTotalData += len2;

    //Keep writing to the memory at temporaryData as long as size of the data 
    //so far is less than max object size
    if (sizeOfTotalData < MAX_OBJECT_SIZE){
      memcpy(temporaryData,data,len2);
      temporaryData += len2;
    }
    rio_writen(fd, data, len2);
  }

  //We shouldn't add the object to the cache if the size of the
  //data exceeds the max object size or is 0
  if(sizeOfTotalData <= MAX_OBJECT_SIZE && sizeOfTotalData != 0)
  {
    pthread_rwlock_wrlock(&lock);
    addToFront(uri, dataBuffer, sizeOfTotalData);
    pthread_rwlock_unlock(&lock);
  }

  free(data);

  return;

}
Ejemplo n.º 17
0
void doit(int fd) 
{
    char buf[MAXLINE], method[MAXLINE], uri[MAXLINE], version[MAXLINE];
    char hostname[MAXLINE], path[MAXLINE], port[MAXLINE];
    char host_header[MAXLINE], remaining_headers[MAXLINE];
    char request[MAXLINE], server_buf[MAXLINE];
    rio_t rio;
    rio_t server_rio;
    memset(buf, 0, MAXLINE);
    memset(method, 0, MAXLINE);
    memset(uri, 0, MAXLINE);
    memset(version, 0, MAXLINE);
    memset(hostname, 0, MAXLINE);
    memset(path, 0, MAXLINE);
    memset(port, 0, MAXLINE);
    memset(host_header, 0, MAXLINE);
    memset(remaining_headers, 0, MAXLINE);
    memset(request, 0, MAXLINE);
    memset(server_buf, 0, MAXLINE);
    
  	
    /* 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;
    }

    cache_node *cache_hit = check_for_hit(proxy_cache, uri);
    if (cache_hit != NULL){
    	if(rio_writen(fd, cache_hit->data, cache_hit->data_size) < 0){
   		    pthread_rwlock_unlock(&lock);
    		return;
    	}
    }
	pthread_rwlock_unlock(&lock);

    if (cache_hit == NULL) {
    	char *response_data = Malloc(sizeof(char));
    	unsigned int data_size = 0;
    	read_requesthdrs(&rio, host_header, remaining_headers);
    	/* Parse URI from GET request */
   		if (parse_uri(uri, hostname, path, port) < 0) {
   			return;
   		}
   		if (strncmp(host_header, "Host: ", strlen("Host: ")) != 0){
   			sprintf(host_header, "Host: %s\r\n", hostname);
   		}
   		// printf("%s %s %s\n", hostname, path, port);
   		compile_request(request, host_header, path, remaining_headers);
    	int port_num = atoi(port);

    	int server_fd = Open_clientfd_r(hostname, port_num);
    	if (rio_writen(server_fd, request, strlen(request)) < 0){
    		return;
    	}
    
    	Rio_readinitb(&server_rio, server_fd);
    	int len;
    	while ((len = rio_readnb(&server_rio, server_buf, MAXLINE)) > 0){
    		if (rio_writen(fd, server_buf, len) < 0){
    			return;
    		}
    		response_data = Realloc(response_data, data_size + len);
    		memcpy(response_data + data_size, server_buf, len);
    		data_size += len;
    	}

    	add_to_cache(proxy_cache, uri, response_data, data_size);
    
    	Close(server_fd);
    	Free(response_data);
    	return; 
    } 
}
Ejemplo n.º 18
0
void read_uint32(rio_t *rp, uint32_t *data){
    rio_readnb(rp, data, sizeof(uint32_t));
    *data = ntohl(*data);
}
Ejemplo n.º 19
0
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
}
Ejemplo n.º 20
0
void *thread(void *vargp){
	struct connfd_timed *clientconnfd = (struct connfd_timed *)vargp;
	int connfd = clientconnfd->connfd;
	int timestamp = clientconnfd->timestamp;
	rio_t rio;
	char buf[MAX_LINE], method[MAX_LINE], version[MAX_LINE], url[MAX_LINE];
	char host[MAX_LINE], port[MAX_LINE], query[MAX_LINE];
	char *response;
	int clientfd;
	int count;
	int content_length;
	
	
	/* read socket */
    rio_readinitb(&rio, connfd);
    rio_readlineb(&rio, buf, MAX_LINE);
    sscanf(buf, "%s %s %s", method, url, version);

	/* only GET */
    if(strcasecmp(method, "GET")){
        Close(connfd);
        return NULL;
    }
	
    /* cache hit */
	response=(char*)Malloc(MAX_OBJECT_SIZE);
	response[0]='\0';
	if (cache_read(url, response, timestamp)){
		rio_writen(connfd, response, strlen(response));
		Close(connfd);
		free(response);
		return NULL;
	}
	
	/* cache miss, create http request to real server*/
	
	/* illegal url */
    if (parse_url(url, host, port, query)){
		Close(connfd);
		return NULL;
	}
	
	/* connect server failed */
    if((clientfd = connect_server(host, port, query)) < 0){
        Close(connfd);
        return NULL;
    }

	/* read http response head, store content length */
	response = (char*)Malloc(MAX_OBJECT_SIZE);
    rio_readinitb(&rio, clientfd);
    content_length = 0;
	while ((count = rio_readlineb(&rio, buf, MAX_LINE)) > 0){
		rio_writen(connfd, buf, count);
		strncat(response, buf, count);
		if(strstr(buf, "Content-length")){
            sscanf(buf, "Content-length: %d\r\n", &content_length);
		}
		if (strcmp(buf,"\r\n") == 0){
			break;
		}
	}
	
	/* too big to cache */
    if(content_length + strlen(response) >= MAX_OBJECT_SIZE){
		while ((count = rio_readnb(&rio, buf, MAX_LINE)) > 0){
			rio_writen(connfd, buf, count);
		}
		Close(clientfd);
		Close(connfd);
		free(response);
		return NULL;
	}
	
	/* add to cache */
	while ((count = rio_readnb(&rio, buf, MAX_LINE)) > 0){
		strncat(response, buf, count);
		rio_writen(connfd, buf, count);
	}
	cache_write(response, url, timestamp);
	Close(clientfd);
    Close(connfd);
    free(response);
    return NULL;
}
Ejemplo n.º 21
0
/* Wrapper for read (buffered) */
ssize_t Rio_readnb(rio_t *rp, void *usrbuf, size_t n) 
{
    ssize_t rc;
    rc = rio_readnb(rp, usrbuf, n);
    return rc;
}
Ejemplo n.º 22
0
/* 
 * forward_response - send request to server, then store resposne content
 * in cache if necessary 
 */
int forward_response(int client_fd, int server_fd, Response *response) {
    #ifdef DEBUG
    printf("enter forward_response\n");
    #endif
    size_t  n;
    int     length = -1;
    int     read_size;
    rio_t   server_rio;
    char header_buffer[MAXLINE];
    char temp_buffer[MAX_OBJECT_SIZE];
    char  buffer[10 * MAX_OBJECT_SIZE];
    char content_buffer[10 * MAX_OBJECT_SIZE];

    rio_readinitb(&server_rio, server_fd);
    int buffer_pos = 0;
    while ((n = rio_readlineb(&server_rio, header_buffer, MAXLINE)) != 0) { 
        memcpy(response->header + buffer_pos, 
                header_buffer, sizeof(char) * n);      
        buffer_pos += n;
        
        /*specify content-length info if header has this info */
        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, temp_buffer, read_size)) != 0) { 
        memcpy(content_buffer + sum, temp_buffer, sizeof(char) * n);      
        sum += n;
    }

    memcpy(buffer, response->header, sizeof(char) * buffer_pos);
    memcpy(buffer + buffer_pos, content_buffer,  sizeof(char) * sum);
    if (rio_writen(client_fd, buffer, buffer_pos + sum) < 0) {
            sleep(1);
            if (rio_writen(client_fd, buffer, buffer_pos + sum) < 0) {
                sleep(2);
                if (rio_writen(client_fd, buffer, buffer_pos + sum) < 0)
                    proxy_error("rio_writen in forward_response" 
                            " header content error");
                    return -1;
            }
    }

    #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
    return 1;
}
Ejemplo n.º 23
0
/*
 *  * doit - handle one HTTP request/response transaction
 *
 */
void* doit(void* pt1) 
{
	//signal(SIGPIPE, SIG_IGN);
	pt_helper* pt = (pt_helper*)pt1;
	int fd = pt->connfd;
    int serverFile, amountRead;
    char buf[MAXLINE], method[MAXLINE], uri[MAXLINE], version[MAXLINE],
		request[MAXLINE];
    char *host, *website, *filename;
	int port;
    rio_t rio, tmprio;
  
	counter++;

	website = uri;
	
    /* Read request line and headers */
    Rio_readinitb(&rio, fd);
    Rio_readlineb(&rio, buf, MAXLINE);
    sscanf(buf, "%s %s %s", method, uri, version);
	//some error checking.
	if(strcasecmp(method, "GET"))
	{
		clienterror(fd, method, "501", "Not Implemented",
			"FoxyProxy does not implement this method");
		Close(pt->connfd);
		free(pt);
		return NULL;
	}
	
	port = parse_website(&website,&filename,&host);
	int n; int found=0;
	for(n = 0; n < CACHEL; n++)
	{
		if(names[n] != NULL){
//		printf("blah blah %s\n",names[n]);
//		printf("foo foo %s\n",website);
		}
		if(names[n] != NULL && !strcmp(website, names[n]))
		{
			found = 1;
			break;
		}
	}
	if(found)
	{
		P(&mut);
		readLock++;
		if(readLock == 1)
		{
			P(&writeLock);
		}
		V(&mut);
	
		times[n] = counter;//time(NULL);
		rio_writen(fd, pages[n], sizes[n]);
		//close(serverFile);
		printf("cached!\n");
		
		P(&mut);
		readLock--;
		if(readLock == 0)
		{
			V(&writeLock);
		}
		V(&mut);
		

		Close(pt->connfd);
		free(pt);
		return NULL;
	}

	serverFile = open_clientfd(host, port);

	//add in request print stuff here
	strcpy(request, method);
	strcat(request, " ");
	strcat(request, filename);
	strcat(request, " HTTP/1.0\r\n");
	strcat(request, HTTPHDR);
	
	rio_writen(serverFile, request, strlen(request));
	//XXX
	//printf(request);
	
	send_requesthdrs(&rio, serverFile, host);

	rio_readinitb(&tmprio, serverFile);
	
	char* buf2 = (char*)malloc(MAX_OBJECT_SIZE);
	int totalRead = 0;
	while ( (amountRead = rio_readnb(&tmprio, buf, MAXBUF)) > 0 )
	{
		rio_writen(fd, buf, amountRead);
		if(totalRead+amountRead <= MAX_OBJECT_SIZE)
		{
			memcpy(buf2+totalRead,buf,amountRead);
		}
		totalRead+=amountRead;
	}

	amountRead = totalRead;
		
	//TODO lock cache
	//FIXME how to delete enough stuff?
	if(amountRead <= MAX_OBJECT_SIZE)
	{
	//	printf("Lock: %d\n", writeLock);
		P(&writeLock);
	//	printf("Lock2: %d\n", writeLock);

		if(amountRead + cachesize <= MAX_CACHE_SIZE)
		{
			time_t lowtime = counter;//time(NULL);
			int leastrecent = -1;
			int n;
			for(n = 0; n < CACHEL; n++)
			{
				if(times[n] < lowtime)
				{
					leastrecent = n;
					lowtime = times[n];
				}
				if(pages[n] == NULL)
				{
					leastrecent = n;
					break;
				}
			}
			n = leastrecent;
			if(pages[n] != NULL)
			{
				free(pages[n]);
				pages[n] = NULL;
				free(names[n]);
				names[n] = NULL;
			}
			void* page = (void*)malloc(amountRead);
			memcpy(page, buf2, amountRead);
			printf("page: \n");
			printf("%s",page);
			char* website_cpy = (char*)malloc(strlen(website)+1);
			strncpy(website_cpy,website,strlen(website));
			website_cpy[strlen(website)]='\0';
			pages[n] = page;
			times[n] = counter;//time(NULL);
			cachesize-=sizes[n];
			sizes[n] = amountRead;
			cachesize+=amountRead;
			names[n] = website_cpy;
		}
		else
		{
			while(cachesize + amountRead > MAX_CACHE_SIZE)
			{
				time_t lowtime = counter;//time(NULL);
				int leastrecent = -1;
				int n;
				for(n = 0; n < CACHEL; n++)
				{
					if(times[n] < lowtime && pages[n] != NULL)
					{
						leastrecent = n;
						lowtime = times[n];
					}
				}
				
				n = leastrecent; 

				free(pages[n]);
				pages[n] = NULL;
				free(names[n]);
				names[n] = NULL;
				cachesize -= sizes[n];
				sizes[n] = 0;
				times[n] = 0;
			}
			int n;
			for(n = 0; n < CACHEL; n++)
			{
				if(pages[n] == NULL) break;
			}
			void* page = (void*)malloc(amountRead);
			memcpy(page, buf2, amountRead);
			pages[n] = page;
			char* website_cpy = (char*)malloc(strlen(website));
			strncpy(website_cpy,website,strlen(website));
			times[n] = counter;//time(NULL);
			names[n] = website_cpy;
			sizes[n] = amountRead;
			cachesize += amountRead;
		}
		V(&writeLock);
	//TODO unlock cache
	}
	free(buf2);
	close(serverFile);
	Close(pt->connfd);
	free(pt);
	return NULL;
}
Ejemplo n.º 24
0
void *thread(void *p)
{
    //可以自动释放线程
    Pthread_detach(pthread_self());
    int connfd=((struct args*)p)->connfd,turn=((struct args*)p)->turn;
    free(p);
    
    char buf[MAXLINE];
    char method[MAXLINE],version[MAXLINE],url[MAXLINE];
    char host[MAXLINE],query[MAXLINE];
    char url_tmp[300],*data_tmp;
    rio_t rio;
    int index,port,content_length;
    int serverfd;
    
    rio_readinitb(&rio,connfd);
    rio_readlineb(&rio,buf,MAXLINE);
    sscanf(buf,"%s %s %s",method,url,version);
    
    if(strcasecmp(method,"GET")) {
        printf("Not GET\r\n");
        Close(connfd);
        return NULL;
    }
    //忽视客户端的请求
    do {
        rio_readlineb(&rio,buf,MAXLINE-1);
    }while(strcmp(buf,"\r\n"));
    
    /* find cache block */
    for(index=0;index<10;index++) {
        cache_read_url(index,url_tmp);
        /* the block'url is same as current url */
        if(!strcmp(url,url_tmp))
            break;
    }
    
    data_tmp=(char*)Malloc(MAX_OBJECT_SIZE);
    data_tmp[0]='\0';
    
    if(index <10) { /* if have cached */
        cache_read_data(index,data_tmp,turn);
        rio_writen(connfd,data_tmp,strlen(data_tmp));
        Close(connfd);
        free(data_tmp);
        return NULL;
    }
    
    /* connect to server */
    parse_url(url,host,query,&port);
    if((serverfd=connect_server(host,port,query))<0) {
        /* connect to server failed, return */
        free(data_tmp);
        Close(connfd);
        return NULL;
    }
    
    rio_readinitb(&rio,serverfd);
    content_length=0;
    /* read response head line */
    do {
        int t=rio_readlineb(&rio,buf,MAXLINE-1);
        if(t<=0)
            break;
        strncat(data_tmp,buf,t);
        if(strstr(buf,"Content-length")!=NULL)
            sscanf(buf,"Content-length: %d\r\n",&content_length);
        rio_writen(connfd,buf,t);
    }while(strcmp(buf,"\r\n"));
    
    /* read response body */
    /* response is small enough to cache */
    if(content_length+strlen(data_tmp)<MAX_OBJECT_SIZE) {
        while(content_length>0) {
            int t= rio_readnb(&rio,buf,(content_length<MAXLINE-1)?content_length:MAXLINE-1);
            if(t<=0)
                continue;
            content_length-=t;
            strncat(data_tmp,buf,t);
            rio_writen(connfd,buf,t);
        }
        index=0;
        int i;
        /* least-recently-used */
        for(i=1;i<10;i++) {
            if(cache_read_turn(i)<cache_read_turn(index)) {
                index=i;
            }
        }
        /* cache write */
        cache_write(index,url,data_tmp,turn);
    }
    /* ignore store and write to client */
    else {
        while(content_length>0) {
            int t= rio_readnb(&rio,buf,(content_length<MAXLINE-1)?content_length:MAXLINE-1);
            if(t<=0)
                break;
            content_length-=t;
            rio_writen(connfd,buf,t);
        }
    }
    Close(connfd);
    Close(serverfd);
    free(data_tmp);
    return NULL;
}