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; }
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); }
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; }
/* * 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); } }
void handle_request( struct http_connection *conn, const struct http_request *request, void *arg ) { http_handle_request( conn->outbuf, request, file_exist, load_file ); }