int start_hyrise_mock(const char *port) { // create socket int socket = http_create_inet_socket(port); debug("Hyrise mock: Listening on port %s", port); // Disptach requests while(1) { // Allocates memory for request struct sockaddr socket_addr; socklen_t socket_len; int socket_fd = accept(socket, &socket_addr, &socket_len); if (socket_fd < 0) { log_err("Error: on accept."); continue; } struct HttpRequest *r; http_receive_request(socket_fd, &r); HttpRequest_free(r); struct HttpResponse resp; resp.status = 200; resp.payload = "Supi"; resp.content_length = strlen(resp.payload); http_send_response(socket_fd, &resp); close(socket_fd); } return 0; }
/* * Handles all the steps needed for and HTTP exchange */ void *handle_client( void *args ){ int client_file_desc = *( ( int *) args ); // What's the client saying? char *client_request; int bytes_received = http_receive_request( client_file_desc, &client_request ); if( !( bytes_received > 0 ) ){ printf( "[THREAD %lu] Got less than 1 byte from http_receive_request()\n", ( unsigned long ) pthread_self( ) ); } //Parse out the request HTTPRequest *request = malloc( sizeof ( HTTPRequest ) ); memset( request, 0, sizeof( HTTPRequest ) ); // I'm putting this on the stack char sc[10]; // because snprintf( sc, 10, "%lu", ( unsigned long ) pthread_self( ) ); // shut up char *strtok_context = &sc[0]; // No ragrets char *http_request_line = strtok_r( client_request, "\r\n", &strtok_context ); request->command = strtok_r( http_request_line, " ", &strtok_context ); request->resource = strtok_r( NULL, " ", &strtok_context ); request->version = strtok_r( NULL, " ", &strtok_context ); // Oh look! I don't need to free strtok_context. // yay // Respond to the client if( strcmp( request->command, "GET") == 0 ){ http_respond( client_file_desc, request->resource ); }else{ // Nothing more for me to do here } // Clean up memory and terminate the thread // Don't need these anymore free( request ); free( client_request ); // Deallocate the thread slot and close the file descriptor for the socket close_thread( pthread_self( ) ); printf( "[THREAD %lu] Thread socket unlocked\n", ( unsigned long ) pthread_self( ) ); printf( "[MAIN THREAD] %d/%d clients connected\n", count_thread_sockets( ), MAX_CLIENTS ); shutdown( client_file_desc, 2 ); close( client_file_desc ); // Terminate the thread pthread_exit( NULL ); }
void Dispatcher::dispatch_requests(int id) { debug("Thread %i started", id); while (1) { // Get an request out of the request queue int socket; debug("Try to lock %d", id); { std::unique_lock<std::mutex> lck(request_queue_mutex); while (request_queue.empty()) { debug("Wait %d", id); request_queue_empty.wait(lck); }; socket = request_queue.front(); request_queue.pop(); debug("Unlock %d", id); } debug("New request: Handled by thread %i", id); // Allocates memory for the request struct HttpRequest *request; int http_error = http_receive_request(socket, &request); if (http_error != HTTP_SUCCESS) { debug("Invalid Http request."); assert(request == NULL); // TODO send error msg to client close(socket); continue; } debug("Request payload: %s", request->payload); if (strncmp(request->resource, "/add_node/", 10) == 0) { struct sockaddr addr; socklen_t addrlen = sizeof(struct sockaddr); if (getpeername(socket, &addr, &addrlen) == 0) { if (addr.sa_family == AF_INET || addr.sa_family == AF_UNSPEC) { struct sockaddr_in *sa = (struct sockaddr_in *)&addr; char ip[INET_ADDRSTRLEN]; if (inet_ntop(AF_INET, &(sa->sin_addr), ip, INET_ADDRSTRLEN) == NULL) { log_err("/add_node/ - Converting network address to string"); } int port = (int)strtol(request->resource+10, (char **)NULL, 10); if (port == 0) { log_err("/add_node/ - Detecting port"); } debug("Add host: %s:%i", ip, port); add_host(ip, port); } else { debug("Cannot add host: Unsupported Address family %d", addr.sa_family); } } else { log_err("/add_node/ - getpeername()"); } HttpRequest_free(request); close(socket); } else if (strncmp(request->resource, "/remove_node/", 13) == 0) { char *delimiter = strchr(request->resource, ':'); if (delimiter != NULL) { char *ip = strndup(request->resource + 13, delimiter - (request->resource + 13)); int port = 0; remove_host(ip, port); free(ip); } HttpRequest_free(request); close(socket); } else if (strcmp(request->resource, "/node_info") == 0) { sendNodeInfo(request, socket); HttpRequest_free(request); close(socket); } else if (strcmp(request->resource, "/query") == 0) { int query_t = queryType(request->payload); switch(query_t) { case READ: distributor->distribute(request, socket); break; case LOAD: sendToAll(request, socket); break; case WRITE: distributor->sendToMaster(request, socket); break; default: log_err("Invalid query: %s", request->payload); throw "Invalid query."; } } else if (strcmp(request->resource, "/procedure") == 0) { distributor->sendToMaster(request, socket); } else { log_err("Invalid HTTP resource: %s", request->resource); exit(1); } } }