void hio_response_http_set_header(HioResponseHttp *http, HrtBuffer *name, HrtBuffer *value) { g_return_if_fail(hrt_buffer_is_locked(name)); g_return_if_fail(hrt_buffer_is_locked(value)); g_mutex_lock(http->headers_lock); if (http->headers_sent) { g_mutex_unlock(http->headers_lock); hrt_message("Attempt to set http header after we already sent the headers, ignoring"); return; } /* FIXME overwrite a previous duplicate header if any */ http->headers = g_slist_prepend(http->headers, header_new(name, value)); g_mutex_unlock(http->headers_lock); }
void *handleClient(void *args) { pthread_detach(pthread_self()); pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL); pthread_cleanup_push(&cleanup_client, args); int buffer_length = 0, string_length = 1, reads = 1; ws_client *n = args; n->thread_id = pthread_self(); pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL); pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); char buffer[BUFFERSIZE]; n->string = (char *) malloc(sizeof(char)); if (n->string == NULL) { pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL); handshake_error("Couldn't allocate memory.", ERROR_INTERNAL, n); pthread_exit((void *) EXIT_FAILURE); } printf("Client connected with the following information:\n" "\tSocket: %d\n" "\tAddress: %s\n\n", n->socket_id, (char *) n->client_ip); printf("Checking whether client is valid ...\n\n"); fflush(stdout); /** * Getting headers and doing reallocation if headers is bigger than our * allocated memory. */ do { memset(buffer, '\0', BUFFERSIZE); if ((buffer_length = recv(n->socket_id, buffer, BUFFERSIZE, 0)) <= 0){ pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL); handshake_error("Didn't receive any headers from the client.", ERROR_BAD, n); pthread_exit((void *) EXIT_FAILURE); } if (reads == 1 && strlen(buffer) < 14) { handshake_error("SSL request is not supported yet.", ERROR_NOT_IMPL, n); pthread_exit((void *) EXIT_FAILURE); } string_length += buffer_length; char *tmp = realloc(n->string, string_length); if (tmp == NULL) { pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL); handshake_error("Couldn't reallocate memory.", ERROR_INTERNAL, n); pthread_exit((void *) EXIT_FAILURE); } n->string = tmp; tmp = NULL; memset(n->string + (string_length-buffer_length-1), '\0', buffer_length+1); memcpy(n->string + (string_length-buffer_length-1), buffer, buffer_length); reads++; } while( strncmp("\r\n\r\n", n->string + (string_length-5), 4) != 0 && strncmp("\n\n", n->string + (string_length-3), 2) != 0 && strncmp("\r\n\r\n", n->string + (string_length-8-5), 4) != 0 && strncmp("\n\n", n->string + (string_length-8-3), 2) != 0 ); printf("User connected with the following headers:\n%s\n\n", n->string); fflush(stdout); ws_header *h = header_new(); if (h == NULL) { pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL); handshake_error("Couldn't allocate memory.", ERROR_INTERNAL, n); pthread_exit((void *) EXIT_FAILURE); } n->headers = h; pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL); if ( parseHeaders(n->string, n, port) < 0 ) { pthread_exit((void *) EXIT_FAILURE); } if ( sendHandshake(n) < 0 && n->headers->type != UNKNOWN ) { pthread_exit((void *) EXIT_FAILURE); } list_add(l, n); pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); printf("Client has been validated and is now connected\n\n"); printf("> "); fflush(stdout); uint64_t next_len = 0; char next[BUFFERSIZE]; memset(next, '\0', BUFFERSIZE); while (1) { if ( communicate(n, next, next_len) != CONTINUE) { break; } pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL); if (n->headers->protocol == CHAT) { list_multicast(l, n); } else if (n->headers->protocol == ECHO) { list_multicast_one(l, n, n->message); } else { list_multicast_one(l, n, n->message); } pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); if (n->message != NULL) { memset(next, '\0', BUFFERSIZE); memcpy(next, n->message->next, n->message->next_len); next_len = n->message->next_len; message_free(n->message); free(n->message); n->message = NULL; } } printf("Shutting client down..\n\n"); printf("> "); fflush(stdout); pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL); list_remove(l, n); pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); pthread_cleanup_pop(0); pthread_exit((void *) EXIT_SUCCESS); }