Пример #1
0
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
  }
}
Пример #2
0
/* $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;
}
/* $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);
    }
}
Пример #4
0
/* parse_request_h is a error handling version of parse_request */
void parse_request_h(struct client_request *request, int clientfd)
{
	int ret;
	
	ret = parse_request(request, clientfd);
	if (ret == 0)
		return;
	if (ret == -1) 
		clienterror(clientfd, "URI", "400", "Bad request",
					"Request could not be understood by proxy");
	if (ret == -2) 
		clienterror(clientfd, "method", "501", "Not Implemented",
					"Proxy does not implement this method");
	close_connection(request, clientfd, -1);
}
Пример #5
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;

	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);
	}
}
Пример #6
0
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);
}
Пример #7
0
Файл: tiny.c Проект: 4179e1/misc
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);
	}
}
Пример #8
0
Файл: tiny.c Проект: akxxsb/tiny
/*
 * 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
    }
}
Пример #9
0
/*
 * 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);
    }
}
Пример #10
0
void HttpSession::Handler(){

    int         is_static;
    struct stat sbuf;
    char        buf[MAXLINE];
    char        method[MAXLINE],uri[MAXLINE],version[MAXLINE];
    char        filename[MAXLINE], cgiargs[MAXLINE];
    //以上都可作为类私有成员,但觉得作用不大
        
    rio.rio_readlineb(buf,MAXLINE);
    sscanf(buf,"%s %s %s",method,uri,version);

    if(strcasecmp(method,"GET")){
        clienterror(fd,method,"501","Not Implement",
                    "Server doesn't implement this method");
        read_requestdrs();
    }
    is_static = parse_uri(uri,filename,cgiargs);
    if(stat(filename,&sbuf)<0){
        clienterror(fd,filename,"404","Not found",
                   "Server 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",
                        "server couldn't read the filem");
            return;
        }
        server_static(fd,filename,sbuf.st_size);
    }
    else{
        if(!(S_ISREG(sbuf.st_mode))||(!S_IRUSR& sbuf.st_mode)){
            clienterror(fd,filename,"403","Forbidden",
                        "Server couldn't run the program");
            return;
        }
        //server_dynamic();  //调用动态内容
    }

}
Пример #11
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
    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);
        }
    }
}
Пример #12
0
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);
        }
}
Пример #13
0
/*
 * 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 */
}
Пример #14
0
/*
 * checkClientRequest - check the correctness of request from client
 *
 * Pamameters:
 *		fd:		file descriptor
 *	 method:	GET method
 *		url: 	parsed url
 *	 version: 	HTTP/1.0
 *		
 */
void checkClientRequest(int fd, char *method, char *url, char *version) {

    /* check request method, only accept GET method for now */    
    if (strcasecmp(method, "GET")) {                     
        clienterror(fd, method, "501", "Not Implemented",
                    "Proxy does not implement this method");
        return;
    }  

    /* check reqeust url */   
    char url_prefix[7]; // using for checking "http://"
    strncpy(url_prefix, url, 7);
    if (strcasecmp(url_prefix, "http://")) {
        clienterror(fd, url, "400", "Bad Request",
                    "Proxy cannot understand this url");
        return;
    }

    /* check request version, should use "HTTP/1.0" */
    if (strcasecmp(version, "HTTP/1.0")) {
        dbg_printf("Attention: only accept HTTP/1.0, change to HTTP/1.0\n");
        strcpy(version, "HTTP/1.0");
    }
}
Пример #15
0
/* open_serverfd_h is a wrapper for open_clientfd and handles errors. */
int open_serverfd_h(struct client_request *request, int clientfd)
{
	int serverfd;
	
	serverfd = open_clientfd(request->host, request->server_port);
	if (serverfd >= 0)
		return serverfd;
	if (serverfd == -1)  /* socket_error */
		close_connection(request, clientfd, -1);
	if (serverfd == -2)  /* DNS error */
		clienterror(clientfd, "http address", "404", "Not found",
					"Proxy could not find server");
	close_connection(request, clientfd, -1);
	abort(); /* flow should never reach here */
}
Пример #16
0
void *proxy_thread(void *vargp) {
	int fd = *(int *)vargp;
	struct stat sbuf;
	char buf[MAXLINE], method[MAXLINE], uri[MAXLINE], version[MAXLINE];
	rio_t rio;

	Pthread_detach(Pthread_self());

	Rio_readinitb(&rio, fd);
	RIO_realineb(&rio, buf, MAXLINE);
	sscanf(buf, "%s %s %s", method, uri, version);

	if (strcasecmp(method, "GET")) {
		clienterror(fd, method, "501", "Not Implemented",
			"Proxy does not support this method");
		return;
	}

	read_requesthdrs(&rio);
}
Пример #17
0
/*
 * handle_request - handle one HTTP request/response transaction
 */
void handle_request(int fd) 
{
    struct stat sbuf;
    char buf[MAXLINE], method[MAXLINE], uri[MAXLINE], version[MAXLINE];
    char headers[MAXBUF];
    char request[MAXLINE], hostname[MAXLINE], arguments[MAXLINE], port[MAXLINE];
    int serverfd;
    rio_t rio_client;
    rio_t rio_server;

    /* Read request line and headers */
    Rio_readinitb(&rio_client, fd);
    if (!Rio_readlineb(&rio_client, buf, MAXLINE))
        return;
    printf("%s", buf);
    sscanf(buf, "%s %s %s", method, uri, version);
    if (strcasecmp(method, "GET")) {
        clienterror(fd, method, "501", "Not Implemented", "Proxy does not implement this method");
        return;
    }

    process_uri(uri, hostname, arguments, port);
    process_hdrs(&rio_client, headers, hostname);
    printf("%s\n", request);
    printf("%s\n", headers);

    sprintf(request, "GET %s HTTP/1.0 \r\n", arguments);

    /* send request to server */
    serverfd = Open_clientfd(hostname, port);

    Rio_writen(serverfd, request, strlen(request));
    Rio_writen(serverfd, headers, strlen(headers));

    /* answer to client */
    Rio_readinitb(&rio_server, serverfd);
    process_answer(&rio_server, fd);  
}
Пример #18
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;
}
Пример #19
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; 
    } 
}
Пример #20
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);
        }
}
Пример #21
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;

    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;
    }
}
Пример #22
0
/* $begin proxy */
void proxy(int fd) 
{
    char buf[MAXLINE], method[MAXLINE], uri[MAXLINE], version[MAXLINE];
    char buf_internet[MAXLINE], payload[MAX_OBJECT_SIZE];
    char host[MAXLINE], path[MAXLINE];
    int port, fd_internet;
    int found = 0;
    size_t n;
    size_t sum = 0;
    mio_t mio_user, mio_internet;
    cnode_t * node;


  
    /* Read request line and headers */
    Mio_readinitb(&mio_user, fd);
    Mio_readlineb(&mio_user, buf, MAXLINE);

    printf("Request: %s\n", buf);

    if (strcmp(buf, "") == 0)
        return;

    sscanf(buf, "%s %s %s", method, uri, version);
    if (strcasecmp(method, "GET")) { 
        clienterror(fd, method, "501", "Not Implemented",
                "Ming does not implement this method");
        return;
    }

    read_requesthdrs(&mio_user);

    /* Parse URI from GET request */
    if (!parse_uri(uri, host, &port, path)) {
		clienterror(fd, uri, "404", "Not found",
		    "Ming couldn't parse the request");
		return;
    }

    printf("uri = \"%s\"\n", uri);
	if (VERBOSE) {

        printf("host = \"%s\", ", host);
        printf("port = \"%d\", ", port);
        printf("path = \"%s\"\n", path);
    }

    if (CACHE_ENABLE) {
        /* Critcal readcnt section begin */
        P(&mutex);
        readcnt++;
        if (readcnt == 1)  // First in
            P(&w);
        V(&mutex);
        /* Critcal readcnt section end */

        /* Critcal reading section begin */
        Cache_check();
        if ((node = match(host, port, path)) != NULL) {
            printf("Cache hit!\n");
            delete(node);
            enqueue(node);
            Mio_writen(fd, node->payload, node->size);
            printf("Senting respond %u bytes from cache\n",
                   (unsigned int)node->size);
            //fprintf(stdout, node->payload);
            found = 1;
        }        
        /* Critcal reading section end */  

        /* Critcal readcnt section begin */    
        P(&mutex);
        readcnt--;
        if (readcnt == 0)
            V(&w);
        V(&mutex);
        /* Critcal readcnt section end */

        if (found == 1) {
            printf("Proxy is exiting\n\n");
            return;
        }

        printf("Cache miss!\n");
    }

    fd_internet = Open_clientfd_r(host, port);
	Mio_readinitb(&mio_internet, fd_internet);

	/* Forward request */
    sprintf(buf_internet, "GET %s HTTP/1.0\r\n", path);
    Mio_writen(fd_internet, buf_internet, strlen(buf_internet));
	sprintf(buf_internet, "Host: %s\r\n", host);
    Mio_writen(fd_internet, buf_internet, strlen(buf_internet));
    Mio_writen(fd_internet, user_agent_hdr, strlen(user_agent_hdr));
    Mio_writen(fd_internet, accept_hdr, strlen(accept_hdr));
    Mio_writen(fd_internet, accept_encoding_hdr, strlen(accept_encoding_hdr));
    Mio_writen(fd_internet, connection_hdr, strlen(connection_hdr));
    Mio_writen(fd_internet, pxy_connection_hdr, strlen(pxy_connection_hdr));

	/* Forward respond */

    strcpy(payload, "");
    while ((n = Mio_readlineb(&mio_internet, buf_internet, MAXLINE)) != 0) {

        //printf("Fd = %d, Sum = %d, n = %d\n", mio_internet.mio_fd, sum, n);
        sum += n;
        if (sum <= MAX_OBJECT_SIZE)
            strcat(payload, buf_internet);
		Mio_writen(fd, buf_internet, n);
	}

    printf("Forward respond %d bytes\n", sum);


    if (CACHE_ENABLE) {
        if (sum <= MAX_OBJECT_SIZE) {
            node = new(host, port, path, payload, sum);

            /* Critcal write section begin */
            P(&w);
            Cache_check();            
            while (cache_load + sum > MAX_CACHE_SIZE) {
                printf("!!!!!!!!!!!!!!!!!Cache evicted!!!!!!!!!!!!!!!!!!\n");
                dequeue();
            }
            enqueue(node);
            printf("The object has been cached\n");
            printf("Current cache size is %d \n", cache_count);            
            printf("Current cache load is %d bytes\n", cache_load);
            //fprintf(stdout, payload);
            Cache_check();
            V(&w);
            /* Critcal write section end */
        }
    }
Пример #23
0
/**
 * Handles HTTP Requests that are sent from the client.
 *
 * Heavily based on the Tiny Server Implementation.
*/
void *service(void *conn)
{
	//Make sure we deallocate our file descriptor
	int fd = *((int *) conn);
	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) <= 0)
	{
		close(fd);
		return NULL;
	}

	sscanf(buf, "%s %s %s", method, uri, version);

	if (strcasecmp(method, "GET"))
	{
		clienterror(fd, method, "501", "METHOD NOT ALLOWED", "METHOD NOW ALLOWED");
		close(fd);
		return NULL;
	}

	read_requesthdrs(&rio);

	parse_uri(uri, filename, cgiargs);

	char json[MAXLINE];
	
	if (strstr(uri, "junk") != NULL)
	{
	    clienterror(fd, method, "404", "NOT FOUND", version);
	    close(fd);
	    return NULL;
	}
	else if (strstr(uri, "/runloop") != NULL)
	{
		sendResponse(fd, "Started 15 second spin.", "text/html", version, strlen("Started 15 second spin."));
		time_t curTime = time(NULL);
		time_t endTime = curTime;
		while ((endTime - curTime) < 15)
		{
			endTime = time(NULL);
		}
	}
	else if (strstr(uri, "/allocanon") != NULL)
	{
		if (allocatedCount > MAX_ALLOC_ALLOWED)
		{
			sendResponse(fd, "Reached maximum of 3 blocks, request denied.", "text/html", version, strlen("Reached maximum of 6 blocks, request denied."));
			close(fd);
			return NULL;
		}
		else
		{
			char *block = mmap(0, 256000000, PROT_WRITE|PROT_READ, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
			if (block == MAP_FAILED)
				printf("Error occured during mmap call\n");

			memset(block, '0', 256000000);
			allocatedBlocks[allocatedCount] = block;
			allocatedCount++;

			char msg[512];
			sprintf(msg, "Mapped and touched 256MB anonymous memory, now have %d blocks allocated in total.", allocatedCount);
			sendResponse(fd, msg, "text/html", version, strlen(msg));
		}
	}
	else if (strstr(uri, "/freeanon") != NULL)
	{
		if (allocatedCount == 0)
		{
			sendResponse(fd, "No blocks allocated.", "text/html", version, strlen("No blocks allocated."));
			close(fd);
			return NULL;
		}
		else
		{
			allocatedCount--;
			if (munmap(allocatedBlocks[allocatedCount], 256000000) != 0)
				printf("Error occured during munmap call\n");
			char msg[512];
			sprintf(msg, "Unmapped 256MB, %d blocks left.", allocatedCount);
			sendResponse(fd, msg, "text/html", version, strlen(msg));
		}
	}
	else if (strstr(uri, "/loadavg") != NULL || strstr(uri, "/loadavg?callback=") != NULL || (strstr(uri, "/loadavg?") != NULL && strstr(uri, "&callback=") != NULL))
	{
		FILE *file = fopen("/proc/loadavg", "r");
		if (file != NULL)
		{
			char loadAvgString[512];
			fgets(loadAvgString, sizeof(loadAvgString), file);
			fclose(file);

			char a1[20], a2[20], a3[20], numThreads[20];
			char *runThreads, *totalThreads;

			sscanf(loadAvgString, "%s %s %s %s", a1, a2, a3, numThreads);
			runThreads = strtok(numThreads, "/");
			totalThreads = strtok(NULL, " ");

			strcat(json, "{\"total_threads\": \"");
			strcat(json, totalThreads);
			strcat(json, "\", \"loadavg\": [\"");
			strcat(json, a1);
			strcat(json, "\", \"");
			strcat(json, a2);
			strcat(json, "\", \"");
			strcat(json, a3);
			strcat(json, "\"], \"");
			strcat(json, "running_threads\": \"");
			strcat(json, runThreads);
			strcat(json, "\"}");
		}
		char *callback;

		if (strstr(uri, "/loadavg?callback=") != NULL)
                  callback = strstr(uri, "?callback=");
                else
                  callback = strstr(uri, "&callback=");

		//		char *callback = strstr(uri, "?callback=");

		if (callback != NULL)
		{
			callback += 10;
			char *string = strtok(callback, "& ");

			char function[512];
			function[0] = '\0';

			strcat(function, string);
			strcat(function, "(");
			strcat(function, json);
			strcat(function, ")");
			
			sendResponse(fd, function, "application/javascript", version, strlen(function));
		}
		else
		{
			sendResponse(fd, json, "application/json", version, strlen(json));
		}
	}

	else if (strstr(uri, "/meminfo") != NULL || strstr(uri, "/meminfo?callback=") != NULL || (strstr(uri, "/meminfo?") != NULL && strstr(uri, "&callback=") != NULL))
	{
		FILE *file = fopen("/proc/meminfo", "r");
		strcat(json, "{");

		if (file != NULL)
		{
			char line[512];
			while (fgets(line, sizeof(line), file) != NULL)
			{
				char name[20];
				char size[20];

				sscanf(line, "%s %s", name, size);
				name[strlen(name) - 1] = '\0';

				//printf("%s: %s\n", name, size);
				strcat(json, "\"");
				strcat(json, name);
				strcat(json, "\": \"");
				strcat(json, size);
				strcat(json, "\", ");
			}

			json[strlen(json) - 2] = '\0';
			fclose(file);
			strcat(json, "}");
		}

		char *callback;
		if (strstr(uri, "/meminfo?callback=") != NULL)
		  callback = strstr(uri, "?callback=");
		else
		  callback = strstr(uri, "&callback=");

		if (callback != NULL)
		{
			callback += 10;
			char *string = strtok(callback, "& ");

			char function[512];
			function[0] = '\0';

			strcat(function, string);
			strcat(function, "(");
			strcat(function, json);
			strcat(function, ")");
			
			sendResponse(fd, function, "application/javascript", version, strlen(function));
		}
		else
		{
			sendResponse(fd, json, "application/json", version, strlen(json));
		}
	}

	//Provides all of the necessary functions for file serving
	else
	{
		if (strstr(filename, "..") != NULL)
	  	{
	  		clienterror(fd, method, "403", "Forbidden", "File pathname not allowed");
	    	return NULL;
	  	}

	  	char *type;
	  	if (strstr(filename, ".html") != NULL || strstr(filename, ".htm") != NULL)
	    	type = "text/html";
	  	else if (strstr(filename, ".gif") != NULL) 
	    	type = "image/gif";
		else if (strstr(filename, ".jpg") != NULL) 
		    type = "image/jpeg";
		else if (strstr(filename, ".js") != NULL) 
		    type = "application/javascript";
		else if (strstr(filename, ".css") != NULL) 
		    type = "text/css";
		else 
		    type = "text/plain";

		printf("\n%s\n", filename);

	  	FILE *file = fopen(filename, "r");
	 	if (file == NULL)
	    {
	      	clienterror(fd, method, "404", "NOT FOUND", "File Not Found");
	      	return NULL;
	    }

	  	fseek(file, 0, SEEK_END);
	  	int length = ftell(file);
	 	fseek(file, 0, SEEK_SET);
	  	char *data = (char *) malloc(length);

	  	fread(data, length, 1, file);

	  	printf("\n%s\n", data);
	  	sendResponse(fd, data, type, version, length);
	}

	close(fd);
	pthread_exit(NULL);
	//return NULL;
}
Пример #24
0
int main(int argc, char **argv) 
{
    int listenfd,connfd, port,clientlen;
    pid_t pid;
    struct sockaddr_in clientaddr;
    char isdaemon=0,*portp=NULL,*logp=NULL,tmpcwd[MAXLINE];

    #ifdef HTTPS 
    int sslport;
    char dossl=0,*sslportp=NULL;
    #endif

    openlog(argv[0],LOG_NDELAY|LOG_PID,LOG_DAEMON);	
    cwd=(char*)get_current_dir_name();	
    strcpy(tmpcwd,cwd);
    strcat(tmpcwd,"/");
    /* parse argv */

    #ifdef  HTTPS
    parse_option(argc,argv,&isdaemon,&portp,&logp,&sslportp,&dossl);
    sslportp==NULL ?(sslport=atoi(Getconfig("https"))) : (sslport=atoi(sslportp));

    if(dossl==1||strcmp(Getconfig("dossl"),"yes")==0)
    	dossl=1;
    #else
    parse_option(argc,argv,&isdaemon,&portp,&logp);
    #endif

    portp==NULL ?(port=atoi(Getconfig("http"))) : (port=atoi(portp));


    Signal(SIGCHLD,sigChldHandler);


    /* init log */
    if(logp==NULL) 
    	logp=Getconfig("log");
    initlog(strcat(tmpcwd,logp));

    /* whethe show dir */
    if(strcmp(Getconfig("dir"),"no")==0)
    	isShowdir=0;	
    	

    clientlen = sizeof(clientaddr);


    if(isdaemon==1||strcmp(Getconfig("daemon"),"yes")==0)
    	Daemon(1,1);

    writePid(1);

    /* $https start  */ 
    #ifdef HTTPS 
    if(dossl)
    {
    	if((pid=Fork())==0)
	{
		listenfd= Open_listenfd(sslport);
		ssl_init();

		while(1)
		{
			connfd = Accept(listenfd, (SA *)&clientaddr, &clientlen);
			if(access_ornot(inet_ntoa(clientaddr.sin_addr))==0)
			{
				clienterror(connfd,"maybe this web server not open to you!" , "403", "Forbidden", "Tiny couldn't read the file");
				continue;
			}

			if((pid=Fork())>0)
			{
				Close(connfd);
				continue;
			}
			else if(pid==0)
			{
				ishttps=1;	
				doit(connfd);
				exit(1);
			}
		}
	}
    }
    #endif

    /* $end https */


    listenfd = Open_listenfd(port);
    while (1)
    {
	connfd = Accept(listenfd, (SA *)&clientaddr, &clientlen);
	if(access_ornot(inet_ntoa(clientaddr.sin_addr))==0)
	{
	    clienterror(connfd,"maybe this web server not open to you!" , "403", "Forbidden", "Tiny couldn't read the file");
	    continue;
	}

	if((pid=Fork())>0)
	{
		Close(connfd);
		continue;
	}
	else if(pid==0)
	{
		doit(connfd);
		exit(1);
	}
    }
}
Пример #25
0
//*************************************************
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);
}
Пример #26
0
/* $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);
	}
    }
}
Пример #27
0
int main(int argc, char **argv) 
{
    int listenfd, connfd, port, clientlen;
    pid_t pid;
    struct sockaddr_in clientaddr;
    char daemon=0,*portp=NULL,*logp=NULL,tmpcwd[MAXLINE];

    cwd=(char*)get_current_dir_name();	
    strcpy(tmpcwd,cwd);
    strcat(tmpcwd,"/");
    /* parse argv */
    parse_option(argc,argv,&daemon,&portp,&logp);
    portp==NULL ?(port=atoi(getconfig("port"))) : (port=atoi(portp));

    /* init log */
    if(logp==NULL) 
    	logp=getconfig("log");
    initlog(strcat(tmpcwd,logp));

    /* whethe show dir */
    if(strcmp(getconfig("dir"),"no")==0)
    	isShowdir=0;	
    	
    if(daemon==1||strcmp(getconfig("daemon"),"yes")==0)
	init_daemon();

    listenfd = Open_listenfd(port);


    /* $https start  */ 

    if((pid=Fork())==0)
    {
       listenfd= Open_listenfd(4444);
	ssl_init();

    	while(1)
	{
		clientlen = sizeof(clientaddr);
		connfd = Accept(listenfd, (SA *)&clientaddr, &clientlen);
		if(access_ornot(inet_ntoa(clientaddr.sin_addr))==0)
		{
		clienterror(connfd,"maybe this web server not open to you!" , "403", "Forbidden", "Tiny couldn't read the file");
		continue;
		}

		if((pid=Fork())>0)
		{
			close(connfd);
			continue;
		}
		else if(pid==0)
		{
			ishttps=1;	
			doit(connfd);
		}
	}
    }

    /* $end https */

    while (1)
    {
	clientlen = sizeof(clientaddr);
	connfd = Accept(listenfd, (SA *)&clientaddr, &clientlen);
	if(access_ornot(inet_ntoa(clientaddr.sin_addr))==0)
	{
	    clienterror(connfd,"maybe this web server not open to you!" , "403", "Forbidden", "Tiny couldn't read the file");
	    continue;
	}

	if((pid=Fork())>0)
	{
		close(connfd);
		continue;
	}
	else if(pid==0)
	{
		doit(connfd);
	}

    }
}
Пример #28
0
void doit(int fd) 
{
    printf("doit %d\n",fd);
    
    char buf[MAX_OBJECT_SIZE], method[MAXLINE], uri[MAXLINE], version[MAXLINE];
    char hostname[MAXLINE];
    char path[MAXLINE]="\0";
    int req_port=0;
    char host[MAXLINE];
    
    int serverfd,serverlen;
    struct sockaddr_in serveraddr;

    rio_t rio;
    int err=0;
    char reqhdr[MAX_OBJECT_SIZE];


    //cache
    char cache_buf[MAX_OBJECT_SIZE];
    ssize_t size;
    size=0;
    cache_node *cache_hit=NULL;

    /* Read request line and headers */
    Rio_readinitb(&rio, fd);

    if ((err=rio_readlineb(&rio, buf, MAX_OBJECT_SIZE))<0){
        clienterror(fd,"get wrong","400","bad request","bad get");
        return;
    }
    sscanf(buf, "%s %s %s", method, uri, version);
    printf("get[%s]",buf);
    
    if (strcmp(buf,"\0")==0){
        clienterror(fd,"get 0","400","Bad Request","invalid request");
        return;
    }
    if (strcasecmp(method, "GET")) { 
        clienterror(fd, method, "501", "Not Implemented",
                    "Proxy does not implement this method");
        return;
    }

    //parse uri
    if (parse_uri(uri,host,hostname,path,&req_port)<0){
        clienterror(fd,uri,"400","Bad Request","invalid request");
        return;
    }

    printf("uri %s %s %s %s %d\n",uri,host,hostname,path,req_port);

    cache_hit=find_fit(cache_head,uri);
	
    if (cache_hit!=NULL){
        //cache hit
        if (cache_to_client(fd,cache_head,cache_hit)<0){
	    clienterror(fd,"cache","505","read cache error","cache error");}
            return;
    }

    // not hit
    // establish connection with the web server
    serverlen=sizeof(serveraddr);
    serverfd=open_clientfd_r(hostname,req_port);
    printf("server %d\n",serverfd);	

    if (serverfd<=0){
        clienterror(fd,"serverfd","400","bad request","connection error");
        return;
    }	

    //built http request to the server
    sprintf(reqhdr,"GET %s HTTP/1.0\r\n",path);
    strcat(reqhdr,"Host: ");
    strcat(reqhdr,host);
    strcat(reqhdr,"\r\n");
    strcat(reqhdr,user_agent_hdr);
    strcat(reqhdr,accept_hdr);
    strcat(reqhdr,accept_encoding_hdr);

    //send addtional header
    parse_requesthdrs(&rio,reqhdr);
    Rio_writen(serverfd,reqhdr,strlen(reqhdr));

    //read from server
    rio_t server_rio;
    Rio_readinitb(&server_rio,serverfd);
    char read_server[MAX_OBJECT_SIZE];
    ssize_t length = 0;
    cache_node *new_node = NULL;

    while((length=Rio_readnb(&server_rio,read_server,MAX_OBJECT_SIZE))>0){
        printf("length%lu\n",length);
        //printf("%s",read_server);
        //forward to the client
        Rio_writen(fd,read_server,length);
        size+=length;
        if (size<=MAX_OBJECT_SIZE){
            sprintf(cache_buf,"%s",read_server);
        }
    }
    printf("buf size%lu\n",size);
    //Rio_writen(fd,read_server,MAXLINE);
    
    if (size<=MAX_OBJECT_SIZE){
        new_node=build_node(uri,size,cache_buf);
        printf("new node%p %lu\n",new_node,new_node->size);
        server_to_cache(cache_head,new_node);
    }

    Close(serverfd);

    return;
}
Пример #29
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;
}
Пример #30
0
// 
// 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);
	}
}