Beispiel #1
0
int main( int argc, char *argv[] ){
	int sockfd, cfd, rec, s, wr=0, sent, lenn;
	int start = 0;
	char pcBuf[MAXBUF];
	char fulBuf[MAXBUF];
	int received;
	struct sockaddr client_addr;
	struct addrinfo hints;
	struct addrinfo *res;
	socklen_t client_addr_size;

	/******************* Connect to Client *******************/
	/* struct setup*/
	hints.ai_family = AF_INET;
	hints.ai_socktype = SOCK_STREAM;
	hints.ai_protocol = IPPROTO_TCP;	
	s = getaddrinfo(NULL, argv[1], &hints, &res);	
	if( s!=0){
		fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(s));
		exit(EXIT_FAILURE);
	}
	/* create socket */
	sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
	if( sockfd == -1)
		handle_error("socket");

	/* bind the socket */
	if( bind(sockfd, res->ai_addr, 
		res->ai_addrlen) == -1)
		handle_error("bind");

	/* listen for client */
	if( listen(sockfd, LISTEN_BACKLOG) == -1)
		handle_error("listen");

	freeaddrinfo(res);
	/* accept connection */
	/* int accept(int sockfd, struct sockaddr *addr, socketlen_t *addrlen) */
	client_addr_size = sizeof(struct sockaddr);
	while(1){
	  cfd = accept( sockfd, (struct sockaddr *) &client_addr, 
		&client_addr_size);
	  if( cfd <= 0)
	    handle_error("accept"); 
	  /*receive GET request from client */
          received= recv(cfd, pcBuf, MAXBUF, 0);
          int recc= recv(cfd, pcBuf+received, MAXBUF, 0);
      	  if(received == -1)
	    fprintf(stderr, "recv: failed");		
	  /*print received GET request on server terminal*/
	  if(write(1, pcBuf, received+recc) == -1){
	    handle_error("write");
	  }
	  /* echo what was received from the client */
	  if((sent = send(cfd,pcBuf, received, 0)) <0)
	    handle_error("send");
	  
	  /******************* Parse Request From Client *******************/
	  int len = strlen(pcBuf);
	  struct ParsedRequest *req = ParsedRequest_create();
	  if(ParsedRequest_parse(req, pcBuf, len) <0) {
	    printf("parse failed\n");
	    return -1;
	  }

	  char *h = req->host;
	  char *p = req->path;

	  get(h, p, cfd);	
	  
	  close(cfd);
  	}/* end infinite loop */
        /* Clean up */
        close(sockfd);
        return 0;
} /* end main */
Beispiel #2
0
int main(int argc, char **argv)
{
    char *port; // port
    int sockfd, new_fd;  // listen on sock_fd, new connection on new_fd
    struct addrinfo hints, *servinfo, *p;
    struct sockaddr_storage their_addr; // connector's address information
    socklen_t sin_size;
    struct sigaction sa;
    int yes=1;
    char s[INET6_ADDRSTRLEN];
    int rv;

    // received data
    char buf[MAXDATASIZE];
    int numbytes;

    // parsed request
    struct ParsedRequest *req;

    // response
    char header[MAXDATASIZE];
    int numHead;

    // file
    FILE *fp;
    char *fType;

    if (argc != 2) {
	printf("Usage: http_server <port-number>\n");
	exit(1);
    }
    port = argv[1];

    memset(&hints, 0, sizeof hints);
    hints.ai_family = AF_UNSPEC;
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_flags = AI_PASSIVE; // use my IP

    if ((rv = getaddrinfo(NULL, port, &hints, &servinfo)) != 0) {
        fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv));
        return 1;
    }

    // loop through all the results and bind to the first we can
    for(p = servinfo; p != NULL; p = p->ai_next) {
        if ((sockfd = socket(p->ai_family, p->ai_socktype,
                p->ai_protocol)) == -1) {
            perror("server: socket");
            continue;
        }

        if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes,
                sizeof(int)) == -1) {
            perror("setsockopt");
            exit(1);
        }

        if (bind(sockfd, p->ai_addr, p->ai_addrlen) == -1) {
            close(sockfd);
            perror("server: bind");
            continue;
        }

        break;
    }

    freeaddrinfo(servinfo); // all done with this structure

    if (p == NULL)  {
        fprintf(stderr, "server: failed to bind\n");
        exit(1);
    }

    if (listen(sockfd, BACKLOG) == -1) {
        perror("listen");
        exit(1);
    }

    sa.sa_handler = sigchld_handler; // reap all dead processes
    sigemptyset(&sa.sa_mask);
    sa.sa_flags = SA_RESTART;
    if (sigaction(SIGCHLD, &sa, NULL) == -1) {
        perror("sigaction");
        exit(1);
    }

    while(1) {  // main accept() loop
        sin_size = sizeof their_addr;
        new_fd = accept(sockfd, (struct sockaddr *)&their_addr, &sin_size);
        if (new_fd == -1) {
            perror("accept");
            continue;
        }

        inet_ntop(their_addr.ss_family,
            get_in_addr((struct sockaddr *)&their_addr),
            s, sizeof s);

        if (!fork()) { // this is the child process

            close(sockfd); // child doesn't need the listener

	   if((numbytes = recv(new_fd, buf, MAXDATASIZE-1, 0)) == -1) {
		perror("recv");
		exit(1);
	   }

	  strcpy(buf + numbytes, "\r\n\0");

	  // make it version 1.0, just for testing
	  char *version = strstr(buf, "HTTP/1.1");
	  if (version > 0) 
	  	strncpy(version + 7, "0", 1);


	  int len = strlen(buf);
	  req = ParsedRequest_create();
      int retval = ParsedRequest_parse_server(req, buf, len);
      if (retval < -1) {
          getResponse(header, "501 Not Implemented", TYPE_HTML, notImpMsg);
          sendResponse(new_fd, header);
      }
	  else if (retval < 0) {
         // 400 Bad Request
	     getResponse(header, "400 Bad Request", TYPE_HTML, badReqMsg); 
	     sendResponse(new_fd, header);
	  }
      
	// use buf as a temporary buffer to get the path
	getPath(buf, req->path);
      
	fType = getType(buf);
	  if (fType == NULL) {
		// Unsupported file type [trumps file not found; respond w/400 bad request.]
		getResponse(header, "400 Bad Request", TYPE_HTML, badReqMsg);
		sendResponse(new_fd, header);
	  }
            
	   
	   fp = fopen(buf, "rb");	   
	   if (fp == NULL) {
	    // File not found
	    getResponse(header, "404 Not Found", TYPE_HTML, notFoundMsg); 
	    sendResponse(new_fd, header);
	   }

	   fseek(fp, 0, SEEK_END);
	   long fsize = ftell(fp);
	   fseek(fp, 0, SEEK_SET);

	   // Send headers
	    numHead = 0;
	    numHead += sprintf(header, "HTTP/1.0 200 OK\r\n");
	    numHead += sprintf(header + numHead, "Connection: close\r\n");
	    numHead += sprintf(header + numHead, "Content-Length: %lu\r\n", fsize);    
	    numHead += sprintf(header + numHead, "Content-Type: %s\r\n\r\n", fType);
	
            if (send(new_fd, header, strlen(header), 0) == -1)
                perror("send");
	
	   // Send body
	   long chunk;
	   while (fsize > 0) {
		chunk = fsize < MAXDATASIZE ? fsize : MAXDATASIZE ;
		fread(buf, 1, chunk, fp);
		send(new_fd, buf, chunk, 0);
		fsize -= chunk;
	   }


            close(new_fd);
	    ParsedRequest_destroy(req);
            exit(0);

        }
        close(new_fd);  // parent doesn't need this
    }

    return 0;
}