static int receive_http_response(int sock, char *buffer, size_t buffer_len, struct http_response_parts *parts)
{
  int len = 0;
  int count;
  do {
      if ((count = read(sock, &buffer[len], buffer_len - len)) == -1)
	return WHYF_perror("read(%d, %p, %d)", sock, &buffer[len], buffer_len - len);
      len += count;
  } while (len < buffer_len && count != 0 && !http_header_complete(buffer, len, len));
  if (debug & DEBUG_RHIZOME_RX)
    DEBUGF("Received HTTP response %s", alloca_toprint(-1, buffer, len));
  if (unpack_http_response(buffer, parts) == -1)
    return -1;
  if (parts->code != 200 && parts->code != 201) {
    INFOF("Failed HTTP request: server returned %003u %s", parts->code, parts->reason);
    return -1;
  }
  if (parts->content_length == -1) {
    if (debug & DEBUG_RHIZOME_RX)
      DEBUGF("Invalid HTTP reply: missing Content-Length header");
    return -1;
  }
  DEBUGF("content_length=%d", parts->content_length);
  return 0;
}
Exemple #2
0
void rhizome_client_poll(struct sched_ent *alarm)
{
  rhizome_http_request *r = (rhizome_http_request *)alarm;
  if (alarm->poll.revents == 0){
    rhizome_server_free_http_request(r);
    return;
  }
  switch(r->request_type)
    {
    case RHIZOME_HTTP_REQUEST_RECEIVING:
      /* Keep reading until we have two CR/LFs in a row */
      r->request[r->request_length] = '\0';
      sigPipeFlag=0;
      int bytes = read_nonblock(r->alarm.poll.fd, &r->request[r->request_length], RHIZOME_HTTP_REQUEST_MAXLEN - r->request_length);
      /* If we got some data, see if we have found the end of the HTTP request */
      if (bytes > 0) {
	// reset inactivity timer
	r->alarm.alarm = gettime_ms() + RHIZOME_IDLE_TIMEOUT;
	r->alarm.deadline = r->alarm.alarm + RHIZOME_IDLE_TIMEOUT;
	unschedule(&r->alarm);
	schedule(&r->alarm);
	r->request_length += bytes;
	if (http_header_complete(r->request, r->request_length, bytes + 4)) {
	  /* We have the request. Now parse it to see if we can respond to it */
	  rhizome_server_parse_http_request(r);
	}
      } else {
	if (debug & DEBUG_RHIZOME_TX)
	  DEBUG("Empty read, closing connection");
	rhizome_server_free_http_request(r);
	return;
      }
      if (sigPipeFlag) {
	if (debug & DEBUG_RHIZOME_TX)
	  DEBUG("Received SIGPIPE, closing connection");
	rhizome_server_free_http_request(r);
	return;
      }
      break;
    default:
      /* Socket already has request -- so just try to send some data. */
      rhizome_server_http_send_bytes(r);
      break;
  }
  return;
}
Exemple #3
0
void handle_client(int socket) {
	initialize_routes();
	req_header header;
	
	int recv_bytes;
	int total_recv;
	do {
		char buffer[5000] = {0};
 		recv_bytes = 0;
		total_recv=0;

		do {
			recv_bytes = recv(socket, buffer + total_recv, 5000, 0);
			if(recv_bytes == -1 || recv_bytes == 0) return;
			total_recv += recv_bytes ;
		}while(http_header_complete(buffer, total_recv) == -1);
		printf("%s", buffer);

		init_req_header(&header, buffer);
		printf("Connection : %s\n", header.connection);
		char * returnString = handle_request(&header);
		send_string(socket, returnString, strlen(returnString));	

		if(!strncmp(header.connection, "close", 5)){
			return;
		}

		fflush(socket);


	}while( recv_bytes != 0 && recv_bytes != -1);
	

	/* TODO Loop receiving requests and sending appropriate responses,
	 *      until one of the conditions to close the connection is
	 *      met.
	 */

}
Exemple #4
0
void handle_client(int socket) {
	initialize_routes();
	req_header header;

	int recv_bytes;
	int total_recv;

	while(1){
		char buffer[5000] = {0};
		recv_bytes = 0;
		total_recv=0;

		do {
			recv_bytes = recv(socket, buffer + total_recv, 5000, 0);
			if(recv_bytes == -1 || recv_bytes == 0) return;
			total_recv += recv_bytes ;
		}while(http_header_complete(buffer, total_recv) == -1);

		init_req_header(&header, buffer);
		char * returnString = handle_request(&header);
		printf("%s\n", returnString);
		int actlen = strlen(returnString);
		int send_length = send(socket, returnString, strlen(returnString), 0);
		//send_string(socket, returnString, strlen(returnString) + 2);
		//fflush(socket);
		if(!strncmp(header.connection, "close", 5)){
			return;
		}
	}
	//}while(!strcmp(header.connection, "keep-alive"));

	//close(socket);

/* TODO Loop receiving requests and sending appropriate responses,
 *      until one of the conditions to close the connection is
 *      met.
 */
return;
}
Exemple #5
0
void handle_client(int socket) {
  node *cookie, *param;
  service cmd;
  http_method method;
  http_response resp;
  int bytes, s, expected_len, header_len;
  char req[BUFFER_SIZE], buf[BUFFER_SIZE];
  const char *path;
  char *connection, *req_body_len;
  time_t since_time;

  /* TODO Loop receiving requests and sending appropriate responses,
   *      until one of the conditions to close the connection is
   *      met.
   */
  cookie = param = resp.expire = resp.cookie = NULL;

  do {
    // New request
    free_list(resp.cookie);
    free_list(resp.expire);
    if (cookie) free_list(cookie);
    if (param) free_list(param);
    cookie = param = NULL;
    memset(&resp, 0, sizeof(http_response));
    memset(req, 0, BUFFER_SIZE);
    bytes = 0;

    // Wait for HTTP header to complete
    do {
      bytes += recv(socket, req + bytes, BUFFER_SIZE, 0);
      header_len = http_header_complete(req, bytes);
    } while (header_len == -1);
    
    // Receive body if there is content length
    if (strstr(req, HDR_CONTENT_LEN)) {
      strcpy(buf, req);
      req_body_len = get_header_value_from_req(buf, HDR_CONTENT_LEN);
      expected_len = atoi(req_body_len) + header_len;
      while (bytes < expected_len) {
         bytes += recv(socket, req + bytes, BUFFER_SIZE, 0);
      }
    }
    // printf("recv %i bytes\n", bytes);

    // Get HTTP method
    method = http_parse_method(req);

    // Get path
    strcpy(buf, req);
    path = http_parse_path(http_parse_uri(buf));
    // printf("Request: %s\n", path);

    // Parse cookies 
    if (strstr(req, HDR_COOKIE)) {
      strcpy(buf, req);
      cookie = get_cookies_from_header(get_header_value_from_req(buf, HDR_COOKIE));
    } else {
      cookie = NULL;
    }

    // Match service command
    cmd = SERV_UNKNOWN;
    for (s= 0; s < SERV_UNKNOWN; s++) {
      if (strncasecmp(path, service_str[s], strlen(service_str[s])) == 0) {
        cmd = s;
        break;
      }
    }

    // Handle command
    switch(cmd) {
      case SERV_KNOCK:
      case SERV_LOGIN:
      case SERV_LOGOUT:
      case SERV_GETFILE:
      case SERV_ADDCART:
      case SERV_DELCART:
      case SERV_CHECKOUT:
        if (method == METHOD_GET) {
          param = get_params_from_query(get_query_str_from_path(path));
          if (cmd == SERV_KNOCK) {
            knock_handler(&resp, cookie);
          } else if (cmd == SERV_LOGIN) {
            login_handler(&resp, param);
          } else if (cmd == SERV_LOGOUT) {
            logout_handler(&resp, cookie);
          } else if (cmd == SERV_GETFILE) {
            since_time = 0;
            strcpy(buf, req);
            if (strstr(buf, HDR_IF_MOD_SINCE)) {
              if (!RFC_822_to_time(strstr(buf, HDR_IF_MOD_SINCE) + 
                    strlen(HDR_IF_MOD_SINCE), &since_time)) {
                since_time = 0;
              }
            }
            getfile_handler(&resp, param, since_time);
          } else if (cmd == SERV_ADDCART) {
            addcart_handler(&resp, param, cookie);
          } else if (cmd == SERV_DELCART) {
            delcart_handler(&resp, param, cookie);
          } else if (cmd == SERV_CHECKOUT) {
            checkout_handler(&resp, cookie);
          } else {
            resp.status = NOT_FOUND;
          }
        } else {
          resp.allow = METHOD_GET;
          resp.status = METHOD_NOT_ALLOWED;
        }
        break;
      case SERV_PUTFILE:
        if (method == METHOD_POST) {
          strcpy(buf, req);
          param = get_params_from_query((char*) http_parse_body(buf, bytes));
          putfile_handler(&resp, cookie, param);
        } else {
          resp.allow = METHOD_POST;
          resp.status = METHOD_NOT_ALLOWED;
        }
        break;
      default:
        resp.status = NOT_FOUND;
        break;
    }

    // Check if status not ok or 
    // client wants to close connection after completing request
    if (resp.status != OK) {
      resp.connection = CLOSE;
    } else if (strstr(req, "Connection:")) {
      connection = http_parse_header_field(buf, bytes, "Connection");
      if (strcmp(connection, "close") == 0) {
        resp.connection = CLOSE;
      }
    }

    send_response(socket, &resp);  
  } while (resp.connection != CLOSE);
}