#include "lib/uce_lib.cpp" #include "fastcgi/src/fcgicc.cc" FastCGIServer server; ServerState server_state; MemoryArena* request_arena = 0; int handle_request(FastCGIRequest& request) { // This is always the first event to occur. It occurs when the // server receives all parameters. There may be more data coming on the // standard input stream. request.request_arena = request_arena; request.time_init = microtime(); request.ob_start(); // this one is for the headers request.ob_start(); // this one is for the content if (request.params.count("REQUEST_URI")) return 0; // OK, continue processing else return 1; // stop processing and return error code } int handle_data(FastCGIRequest& request) { // This event occurs when data is received on the standard input stream. // A simple String is used to hold the input stream, so it is the // responsibility of the application to remember which data it has // processed. The application may modify it; new data will be appended // to it by the server. The same goes for the output and error streams: // the application should append data to them; the server will remove // all sent data from them. return 0; // still OK std::transform(request.in.begin(), request.in.end(), std::back_inserter(request.err), std::bind1st(std::plus(), 1)); request.in.clear(); // don't process it again return 0; // still OK } int handle_complete(FastCGIRequest& request) { // The event handler can also be a class member function. This // event occurs when the parameters and standard input streams are // both closed, and thus the request is complete. // printf("(i) request handle\n"); context = &request; request.server = &server_state; request.time_start = microtime(); request.header["Content-Type"] = context->server->config.CONTENT_TYPE; request.get = parse_query(request.params["QUERY_String"]); if(request.params["HTTP_COOKIE"].length() > 0) request.cookies = parse_cookies(request.params["HTTP_COOKIE"]); String ct_info = request.params["CONTENT_TYPE"]; String ct_type = nibble(";", ct_info); if(request.params["REQUEST_METHOD"] == "POST") { if(ct_type == "multipart/form-data") { nibble("boundary=", ct_info); request.post = parse_multipart(request.in, String("--")+ct_info, request.uploaded_files); } else { request.post = parse_query(request.in); } } // printf("(i) request ready\n"); request.invoke(request.params["SCRIPT_FILENAME"]); switch_to_system_alloc(); for( auto &f : request.uploaded_files) { unlink(f.tmp_name); } if(request.session_id.length() > 0) save_session_data(request.session_id, request.session); cleanup_mysql_connections(); return 0; } void listen_for_connections() { //request_arena = new MemoryArena(server_state.config.MAX_MEMORY, "request"); signal(SIGSEGV, on_segfault); server.request_handler(&handle_request); server.data_handler(&handle_data); server.complete_handler(&handle_complete); for(;;) { //if(request_arena) request_arena->clear(); //current_memory_arena = request_arena; server.process(); } } int main(int argc, char** argv) { printf("(P) Starting parent server PID:%i\n", getpid()); signal(SIGCHLD, on_child_exit); srand(time()); //if(server_state.config.COMPILER_SYS_PATH == "") server_state.config.COMPILER_SYS_PATH = get_cwd(); // printf("MySQL client version: %s\n", mysql_get_client_info()); printf("Compiler base path: %s\n", server_state.config.COMPILER_SYS_PATH.c_str()); server_state.config.BIN_DIRECTORY = server_state.config.COMPILER_SYS_PATH + "/" + server_state.config.BIN_DIRECTORY; server_state.config.COMPILE_SCRIPT = server_state.config.COMPILER_SYS_PATH + "/" + server_state.config.COMPILE_SCRIPT; if(server_state.config.LISTEN_PORT) server.listen(server_state.config.LISTEN_PORT); if(server_state.config.SOCKET_PATH != "") server.listen(server_state.config.SOCKET_PATH); chmod(server_state.config.SOCKET_PATH.c_str(), S_IRWXU | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH); dirname(server_state.config.COMPILER_SYS_PATH); basename(server_state.config.COMPILER_SYS_PATH); mkdir(server_state.config.TMP_UPLOAD_PATH); mkdir(server_state.config.SESSION_PATH); //server.process(100); //server.process(); /*try { server.process_forever(); } catch (const std::runtime_error& e) { std::cout << e.what(); }*/ for(;;) { while(workers.size() < server_state.config.WORKER_COUNT) { spawn_subprocess(listen_for_connections); } sleep(1); } return 0; }