예제 #1
0
static ssize_t handle_read( const int64 clientsocket ) {
  struct http_data* h = io_getcookie( clientsocket );
  ssize_t l;

  if( ( l = io_tryread( clientsocket, static_inbuf, sizeof static_inbuf ) ) <= 0 ) {
    handle_dead( clientsocket );
    return 0;
  }

  /* If we get the whole request in one packet, handle it without copying */
  if( !array_start( &h->request ) ) {
    if( memchr( static_inbuf, '\n', l ) )
      return http_handle_request( clientsocket, static_inbuf, l );
    h->flag |= STRUCT_HTTP_FLAG_ARRAY_USED;
    array_catb( &h->request, static_inbuf, l );
    return 0;
  }

  h->flag |= STRUCT_HTTP_FLAG_ARRAY_USED;
  array_catb( &h->request, static_inbuf, l );

  if( array_failed( &h->request ) )
    return http_issue_error( clientsocket, CODE_HTTPERROR_500 );

  if( ( array_bytes( &h->request ) > 8192 ) && !accesslist_isblessed( (char*)&h->ip, OT_PERMISSION_MAY_SYNC ) )
     return http_issue_error( clientsocket, CODE_HTTPERROR_500 );

  if( memchr( array_start( &h->request ), '\n', array_bytes( &h->request ) ) )
    return http_handle_request( clientsocket, array_start( &h->request ), array_bytes( &h->request ) );

  return 0;
}
예제 #2
0
int main(int argc, char* argv[]){
  struct sockaddr_in server_addr;
  struct sockaddr_in remote_addr;

  const int BUFFER_SIZE = 4096;
  char buf[BUFFER_SIZE];

  int SERVER_PORT=10000;
  int listen_fd = socket(AF_INET, SOCK_STREAM, 0);
  int reuseaddr = 1;
  setsockopt(listen_fd, SOL_SOCKET, SO_REUSEADDR, &reuseaddr, sizeof(reuseaddr));
  memset(&server_addr, 0, sizeof(server_addr));

  server_addr.sin_family = AF_INET;
  server_addr.sin_addr.s_addr = INADDR_ANY;
  server_addr.sin_port = htons(SERVER_PORT);

  printf("binding on port %d\n", SERVER_PORT);
  if(bind(listen_fd, (struct sockaddr*)&server_addr, sizeof(server_addr)) < 0){
    printf("Could not bind address\n");
    return -1;
  }

  if(listen(listen_fd, 1) < 0){
    printf("Could not listen on port\n");
    return -2;
  }

  while(1){
    socklen_t sock_len = sizeof(remote_addr);
    int client_fd = accept(listen_fd, (struct sockaddr*)&remote_addr, &sock_len);

    int pid;
    if((pid = fork()) == 0){
      close(listen_fd);

      char client_ip[32];
      inet_ntop(AF_INET, (const void *)&remote_addr.sin_addr, client_ip, sizeof(client_ip));

      printf("Request from %s[fd:%d]\n", client_ip, client_fd);
      struct HttpRequest request;
      http_parse_request(client_fd, &request);
      http_handle_request(&request);

      close(client_fd);
      _exit(0);
    }else if(pid > 0){
      close(client_fd);
    }else{      
      printf("could not fork sub process\n");
    }
  }
  return 0;
}
int main()
{
  CHICKEN_run(C_toplevel);

  FCGX_Request* request = malloc(sizeof(FCGX_Request));

  FCGX_Init();
  FCGX_InitRequest(request, 0, 0);

  while (FCGX_Accept_r(request) == 0)
  {
    http_handle_request(request);
    FCGX_Finish_r(request);
  }

  FCGX_Free(request, 1);

  free(request);
}
예제 #4
0
int main(int argc, char *argv[]) {
    struct sockaddr_in server_addr;
    struct sockaddr_in remote_addr;
    struct epoll_event ev, events[MAX_EVENTS];

    const int BUFFER_SIZE = 4096;
    char buf[BUFFER_SIZE];

    int SERVER_PORT = 10000;
    int listen_fd = socket(AF_INET, SOCK_STREAM, 0);
    int reuseaddr = 1;

    bzero(&ev, sizeof(ev));
    int epoll_fd = epoll_create(500/*deprecated?*/);
    if (epoll_fd == -1) {
        printf("could not create epoll descriptor\n");
        return -1;
    }
    
    setnonblocking(listen_fd);
    setsockopt(listen_fd, SOL_SOCKET, SO_REUSEADDR, &reuseaddr, sizeof(reuseaddr));
    memset(&server_addr, 0, sizeof(server_addr));

    server_addr.sin_family = AF_INET;
    server_addr.sin_addr.s_addr = INADDR_ANY;
    server_addr.sin_port = htons(SERVER_PORT);

    printf("binding on port %d\n", SERVER_PORT);
    if (bind(listen_fd, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) {
        printf("Could not bind address\n");
        return -2;
    }

    if (listen(listen_fd, 1) < 0) {
        printf("Could not listen on port\n");
        return -3;
    }

    ev.events = EPOLLIN;
    ev.data.fd = listen_fd;

    if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, listen_fd, &ev) == -1) {
        printf("Could not add listen fd to epoll descriptor\n");
        return -4;
    }

    while (1) {
        int nfds = epoll_wait(epoll_fd, events, MAX_EVENTS, -1);
        if (nfds == -1) {
            printf("Could not wait epoll events\n");
            return -5;
        }

        for (int n = 0; n < nfds; n++) {
            if (events[n].data.fd == listen_fd) {
                socklen_t sock_len = sizeof(remote_addr);
                int client_fd = accept(listen_fd, (struct sockaddr *)&remote_addr, &sock_len);
                if (client_fd == -1) {
                    printf("Could not accept connection request\n");
                }

                //char client_ip[32];
                //inet_ntop(AF_INET, (const void *)&remote_addr.sin_addr, client_ip, sizeof(client_ip));
                //printf("Request from %s[fd:%d]\n", client_ip, client_fd);

                buffered_request_init(client_fd);

                setnonblocking(client_fd);
                setsockopt(client_fd, SOL_SOCKET, SO_REUSEADDR, &reuseaddr, sizeof(reuseaddr));
                ev.events = EPOLLIN | EPOLLOUT | EPOLLET;
                ev.data.fd = client_fd;
                if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, client_fd, &ev) == -1) {
                    printf("Could not add new connection request to epoll descriptor\n");
                }
            } else {
                int client_fd = events[n].data.fd;
                buffered_request_t *buffered = buffered_request_for_connection(client_fd);
                static int disable_cork = 0;
                if (events[n].events & EPOLLHUP) {
                  printf("[%d]Hup Disconnected\n", client_fd);
                      setsockopt(client_fd, SOL_TCP, TCP_CORK, &disable_cork, sizeof(disable_cork));
                  http_close_connection(buffered);
                    //                    epoll_ctl(epoll_fd, EPOLL_CTL_DEL, client_fd, &ev);                    
                    continue;
                }
                
                if (events[n].events & EPOLLIN) {
                    int read_count = buffered_request_read_all_available_data(buffered);
                    if(read_count > 0){
                      //printf("[%d]Received request:\n%s\n", client_fd, &(buffered->readbuf[buffered->readpos]));
                        
                        //TODO: handle request only if already a full request
                        http_request_t request;
                        if(http_parse_request(buffered, &request)< 0){
                          printf("failed to parse request\n");
                        }
                    
                        http_handle_request(buffered, &request);
                    }else if(read_count == 0){
                      http_close_connection(buffered);
                      //epoll_ctl(epoll_fd, EPOLL_CTL_DEL, client_fd, &ev);                      
                      continue;
                    }
                }

                if (events[n].events & EPOLLOUT) {
                  if(!buffered_request_has_wroten_all(buffered)){
                    static int enable_cork = 1;
                    setsockopt(client_fd, SOL_TCP, TCP_CORK, &enable_cork, sizeof(enable_cork));
                    //printf("[%d]SEND response:\n%s\n", client_fd, &(buffered->writebuf[buffered->writepos]));
                    buffered_request_write_all_available_data(buffered);
                                         
                    if(buffered_request_has_wroten_all(buffered)){

                      setsockopt(client_fd, SOL_TCP, TCP_CORK, &disable_cork, sizeof(disable_cork));
                      //printf("[%d]Disconnected\n", client_fd);
                      http_close_connection(buffered);
                      //epoll_ctl(epoll_fd, EPOLL_CTL_DEL, client_fd, &ev);
                      continue;
                      }
                    
                  }
                }

                if (events[n].events & EPOLLERR) {
                    printf("[%d] ERR Disconnected\n", client_fd);
                    setsockopt(client_fd, SOL_TCP, TCP_CORK, &disable_cork, sizeof(disable_cork));
                    http_close_connection(buffered);
                    //epoll_ctl(epoll_fd, EPOLL_CTL_DEL, client_fd, &ev);                    
                    continue;
                }

            }
        }
    }
    return 0;
}
예제 #5
0
/*
 * Launch a http server that listens on the given port.
 */
void http_server(uint16_t port, void (*callback)(struct http_user_vars_s *),
    bool launch)
{
    socket_t s_listen = socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP);
    if (s_listen == INVALID_SOCKET)
    {
        error("unable to create a socket for the configuration server");
    }
    struct sockaddr_in6 listen_addr;
    memset(&listen_addr, 0x0, sizeof(listen_addr));
    listen_addr.sin6_family = AF_INET6;
    listen_addr.sin6_port   = htons(port);
    listen_addr.sin6_addr   = in6addr_any;
    int on = 1;
    setsockopt(s_listen, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on));
    // For Windows we must explicitly allow IPv4 connections
    on = 0;
    if (setsockopt(s_listen, IPPROTO_IPV6, IPV6_V6ONLY, (char *)&on,
            sizeof(on)) != 0)
    {
        warning("unable to allow incoming IPv4 connections to configuration "
            "server");
    }
    if (bind(s_listen, (const void *)&listen_addr, sizeof(listen_addr)) != 0)
    {
        error("unable to create configuation server; failed to bind to "
            "address localhost:%u", port);
    }

    if (listen(s_listen, 1) != 0)
    {
        error("unable to create configuation server; failed to listen to "
            "address localhost:%u", port);
    }

    // Launch the UI:
    if (launch)
    {
        launch_ui(port);
    }

    // Main server loop:
    while (true)
    {
        struct sockaddr_in6 accept_addr;
        socklen_t accept_len = sizeof(accept_addr);
        socket_t s = accept(s_listen, (struct sockaddr *)&accept_addr,
            &accept_len);
        if (s == INVALID_SOCKET)
        {
            warning("unable to accept incoming connection to configuration "
                "server localhost:%u", port);
            close_socket(s);
            continue;
        }
        static const struct in6_addr in6addr_loopbackv4 =
            {{{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF, 127, 0, 0, 1}}};
        if (memcmp(&accept_addr.sin6_addr, &in6addr_loopback,
                sizeof(in6addr_loopback)) != 0 &&
            memcmp(&accept_addr.sin6_addr, &in6addr_loopbackv4,
                sizeof(in6addr_loopbackv4) - 3) != 0)
        {
            warning("unable to accept incoming connection to configuration "
                "server localhost:%u from non-local address", port);
            close_socket(s);
            continue;
        }
        char request[MAX_REQUEST_BUFF_SIZE];
        struct http_parser_s parser;
        http_parser_init(&parser);
        do
        {
            size_t n = recv(s, request, sizeof(request)-1, 0);
            if (n <= 0)
            {
                http_user_vars_free(&parser.request.vars);
                warning("unable to read request for configuration server "
                    "localhost:%u", port);
                close_socket(s);
                break;
            }
            request[n] = '\0';
            http_parse_request(request, n, &parser);
            switch (parser.state)
            {
                case HTTP_STATE_FINAL:
                    break;
                case HTTP_STATE_ERROR:
                    http_user_vars_free(&parser.request.vars);
                    warning("unable to parse request to configuration server "
                        "localhost:%u", port);
                    close_socket(s);
                    break;
                default:
                    continue;
            }
            http_callback_func_t generate;
            if (parser.request.method == HTTP_METHOD_GET &&
                (generate = http_lookup_callback(parser.request.name)) != NULL)
            {
                http_buffer_t content = http_buffer_open();
                if (generate(content))
                {
                    bool success = http_send_response(s, 200, content,
                        &parser.request);
                    if (!success)
                    {
                        http_error(s, 500, &parser.request);
                    }
                }
                else
                {
                    http_error(s, 404, &parser.request);
                }
                http_buffer_close(content);
            }
            else
            {
                callback(&parser.request.vars);
                http_handle_request(s, &parser.request);
            }
            shutdown(s, SHUT_RDWR);
            http_user_vars_free(&parser.request.vars);
            close_socket(s);
        } 
        while (false);
    }
}
예제 #6
0
void handle_request( struct http_connection *conn, const struct http_request *request, void *arg )
{
	http_handle_request( conn->outbuf, request, file_exist, load_file );
}