static THREAD_RETVAL httpd_thread(void *arg) { httpd_t *httpd = arg; char buffer[1024]; int i; assert(httpd); while (1) { fd_set rfds; struct timeval tv; int nfds=0; int ret; MUTEX_LOCK(httpd->run_mutex); if (!httpd->running) { MUTEX_UNLOCK(httpd->run_mutex); break; } MUTEX_UNLOCK(httpd->run_mutex); /* Set timeout value to 5ms */ tv.tv_sec = 1; tv.tv_usec = 5000; /* Get the correct nfds value and set rfds */ FD_ZERO(&rfds); if (httpd->open_connections < httpd->max_connections) { FD_SET(httpd->server_fd4, &rfds); nfds = httpd->server_fd4+1; if (httpd->server_fd6 != -1) { FD_SET(httpd->server_fd6, &rfds); if (nfds <= httpd->server_fd6) { nfds = httpd->server_fd6+1; } } } for (i=0; i<httpd->max_connections; i++) { int socket_fd; if (!httpd->connections[i].connected) { continue; } socket_fd = httpd->connections[i].socket_fd; FD_SET(socket_fd, &rfds); if (nfds <= socket_fd) { nfds = socket_fd+1; } } ret = select(nfds, &rfds, NULL, NULL, &tv); if (ret == 0) { /* Timeout happened */ continue; } else if (ret == -1) { /* FIXME: Error happened */ logger_log(httpd->logger, LOGGER_INFO, "Error in select"); break; } if (FD_ISSET(httpd->server_fd4, &rfds)) { ret = httpd_accept_connection(httpd, httpd->server_fd4, 0); if (ret == -1) { break; } else if (ret == 0) { continue; } } if (httpd->server_fd6 != -1 && FD_ISSET(httpd->server_fd6, &rfds)) { ret = httpd_accept_connection(httpd, httpd->server_fd6, 1); if (ret == -1) { break; } else if (ret == 0) { continue; } } for (i=0; i<httpd->max_connections; i++) { http_connection_t *connection = &httpd->connections[i]; if (!connection->connected) { continue; } if (!FD_ISSET(connection->socket_fd, &rfds)) { continue; } /* If not in the middle of request, allocate one */ if (!connection->request) { connection->request = http_request_init(httpd->use_rtsp); assert(connection->request); } logger_log(httpd->logger, LOGGER_DEBUG, "Receiving on socket %d", connection->socket_fd); ret = recv(connection->socket_fd, buffer, sizeof(buffer), 0); if (ret == 0) { logger_log(httpd->logger, LOGGER_INFO, "Connection closed for socket %d", connection->socket_fd); httpd_remove_connection(httpd, connection); continue; } /* Parse HTTP request from data read from connection */ http_request_add_data(connection->request, buffer, ret); if (http_request_has_error(connection->request)) { logger_log(httpd->logger, LOGGER_INFO, "Error in parsing: %s", http_request_get_error_name(connection->request)); httpd_remove_connection(httpd, connection); continue; } /* If request is finished, process and deallocate */ if (http_request_is_complete(connection->request)) { http_response_t *response = NULL; httpd->callbacks.conn_request(connection->user_data, connection->request, &response); http_request_destroy(connection->request); connection->request = NULL; if (response) { const char *data; int datalen; int written; int ret; /* Get response data and datalen */ data = http_response_get_data(response, &datalen); written = 0; while (written < datalen) { ret = send(connection->socket_fd, data+written, datalen-written, 0); if (ret == -1) { /* FIXME: Error happened */ logger_log(httpd->logger, LOGGER_INFO, "Error in sending data"); break; } written += ret; } } else { logger_log(httpd->logger, LOGGER_INFO, "Didn't get response"); } http_response_destroy(response); } } } /* Remove all connections that are still connected */ for (i=0; i<httpd->max_connections; i++) { http_connection_t *connection = &httpd->connections[i]; if (!connection->connected) { continue; } logger_log(httpd->logger, LOGGER_INFO, "Removing connection for socket %d", connection->socket_fd); httpd_remove_connection(httpd, connection); } logger_log(httpd->logger, LOGGER_INFO, "Exiting HTTP thread"); return 0; }
printf("fh == 3\n"); data = (char *) malloc(12 + 20); length_res = 12 + 20; memcpy(data, fply_4, 12); memcpy(data + 12, payload + datalen - 20, 20); } http_response_add_header(res, "Content-Type", "application/octet-stream"); http_response_add_header(res, "Server", "AirTunes/110.92"); } } int i; http_response_finish(res, data, length_res); printf("%s\n", http_response_get_data(res, &i)); logger_log(conn->raop->logger, LOGGER_DEBUG, "Handled request %s with URL %s", method, http_request_get_url(request)); *response = res; } static void conn_destroy(void *ptr) { raop_conn_t *conn = ptr; if (conn->raop_rtp) { /* This is done in case TEARDOWN was not called */ raop_rtp_destroy(conn->raop_rtp); }