#include #include #include #include #include #include #include "misc.h" #include "socket.h" #include "webserver.h" typedef std::vector string_array; int def_timeout = 5; struct responseRoute { std::string method; std::string path; std::string content_type; response_callback rc; }; std::vector responses; //for use of multi-thread int max_send_failure = 10; std::atomic_bool SERVER_EXIT_FLAG(false); std::atomic_int working_thread(0) int sendall(SOCKET sock, std::string data) { unsigned int total = 0, bytesleft = data.size(); int sent = 0; const char* datastr = data.data(); while(total < bytesleft) { sent = send(sock, datastr + total, bytesleft, 0); if(sent < 0) { std::cerr< 2) { wrong_req(client_sock); goto end; } else if(vArray.size() > 1) { uri = vArray[0]; args = vArray[1]; } else uri = arguments; if(strcmp(command, "POST") == 0) { if(request.find("\r\n\r\n") != request.npos) postdata = request.substr(request.find("\r\n\r\n") + 4); } else if(strcmp(command, "OPTIONS") == 0) { serve_options(client_sock); goto end; } for(std::vector::iterator iter = responses.begin(); iter != responses.end(); ++iter) { if(iter->method.compare(command) == 0 && iter->path == uri) { response_callback &rc = iter->rc; serve_content(client_sock, iter->content_type, rc(args, postdata)); goto end; } } file_not_found(uri, client_sock); end: std::cerr<<"worker stop"<max_workers = 1; return start_web_server_multi(args); } int start_web_server_multi(void *argv) { //log startup struct listener_args *args = (listener_args*)argv; std::string listen_address = args->listen_address, request; int port = args->port, max_conn = args->max_conn, max_workers = args->max_workers, numbytes, worker_index = 0; socklen_t sock_size = sizeof(struct sockaddr_in); char buf[BUFSIZ]; struct sockaddr_in user_socket, server_addr; SOCKET acc_socket; int server_socket, fail_counter = 0; server_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_IP); std::thread workers[max_workers]; if (server_socket == -1) { //log socket error std::cerr<<"socket build error!"< max_send_failure) break; continue; } else { break; } } request = ""; while(true) //receive the complete request { numbytes = recv(acc_socket, buf, BUFSIZ - 1, 0); if(numbytes > 0) //received request.append(buf); if(numbytes < 0) { if(errno == EINTR || errno == EWOULDBLOCK || errno == EAGAIN) { continue; } else { break; } } if(numbytes == 0) break; } //handle_req(buf, acc_socket); while(working_thread >= max_workers) { sleep(10); if(SERVER_EXIT_FLAG) break; } while(workers[worker_index].get_id() != std::thread::id()) { worker_index++; } workers[worker_index] = std::thread(handle_req, request, acc_socket); workers[worker_index].detach(); worker_index++; if(worker_index > max_workers) worker_index = 0; } return 0; }