📄 connection.c
字号:
memmove (connection->read_buffer, &connection->read_buffer[connection->readLoc - processed], processed); if (connection->uploadSize != -1) connection->uploadSize -= (connection->readLoc - processed); connection->readLoc = processed; if ((connection->uploadSize == 0) || ((connection->readLoc == 0) && (connection->uploadSize == -1) && (connection->socket_fd == -1))) { connection->bodyReceived = 1; connection->readLoc = 0; connection->read_buffer_size = 0; connection->read_buffer = NULL; }}/** * This function handles a particular connection when it has been * determined that there is data to be read off a socket. All implementations * (multithreaded, external select, internal select) call this function * to handle reads. */intMHD_connection_handle_read (struct MHD_Connection *connection){ int bytes_read; void *tmp; if (connection->pool == NULL) connection->pool = MHD_pool_create (connection->daemon->pool_size); if (connection->pool == NULL) { MHD_DLOG (connection->daemon, "Failed to create memory pool!\n"); CLOSE (connection->socket_fd); connection->socket_fd = -1; return MHD_NO; } if ((connection->readLoc >= connection->read_buffer_size) && (connection->headersReceived == 0)) { /* need to grow read buffer */ tmp = MHD_pool_reallocate (connection->pool, connection->read_buffer, connection->read_buffer_size, connection->read_buffer_size * 2 + MHD_BUF_INC_SIZE); if (tmp == NULL) { MHD_DLOG (connection->daemon, "Not enough memory for reading headers!\n"); MHD_excessive_data_handler (connection, MHD_HTTP_REQUEST_ENTITY_TOO_LARGE); return MHD_NO; } connection->read_buffer = tmp; connection->read_buffer_size = connection->read_buffer_size * 2 + MHD_BUF_INC_SIZE; } if (connection->readLoc >= connection->read_buffer_size) { MHD_DLOG (connection->daemon, "Unexpected call to %s.\n", __FUNCTION__); return MHD_NO; } bytes_read = RECV (connection->socket_fd, &connection->read_buffer[connection->readLoc], connection->read_buffer_size - connection->readLoc, 0); if (bytes_read < 0) { if (errno == EINTR) return MHD_NO; MHD_DLOG (connection->daemon, "Failed to receive data: %s\n", STRERROR (errno)); CLOSE (connection->socket_fd); connection->socket_fd = -1; return MHD_YES; } if (bytes_read == 0) { /* other side closed connection */ connection->read_close = MHD_YES; if (connection->readLoc > 0) MHD_call_connection_handler (connection); shutdown (connection->socket_fd, SHUT_RD); return MHD_YES; } connection->readLoc += bytes_read; if (connection->headersReceived == 0) { MHD_parse_connection_headers (connection); if (connection->headersReceived == 1) { connection->post_processed = MHD_test_post_data (connection); } } if (connection->headersReceived == 1) { if ((connection->post_processed == MHD_YES) && (connection->uploadSize == connection->readLoc)) if (MHD_NO == MHD_parse_post_data (connection)) connection->post_processed = MHD_NO; if (((connection->post_processed == MHD_NO) || (connection->read_buffer_size == connection->readLoc)) && (connection->method != NULL)) MHD_call_connection_handler (connection); } return MHD_YES;}/** * Check if we need to set some additional headers * for http-compiliance. */static voidMHD_add_extra_headers (struct MHD_Connection *connection){ const char *have; char buf[128]; if (connection->response->total_size == -1) { have = MHD_get_response_header (connection->response, MHD_HTTP_HEADER_CONNECTION); if (have == NULL) MHD_add_response_header (connection->response, MHD_HTTP_HEADER_CONNECTION, "close"); } else if (NULL == MHD_get_response_header (connection->response, MHD_HTTP_HEADER_CONTENT_LENGTH)) { _REAL_SNPRINTF (buf, 128, "%llu", (unsigned long long) connection->response->total_size); MHD_add_response_header (connection->response, MHD_HTTP_HEADER_CONTENT_LENGTH, buf); }}static voidget_date_string (char *date, unsigned int max){ static const char *days[] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" }; static const char *mons[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct","Nov", "Dec" }; struct tm now; time_t t; time (&t); gmtime_r (&t, &now); snprintf (date, max - 1, "Date: %3s, %02u %3s %04u %02u:%02u:%02u GMT\r\n", days[now.tm_wday % 7], now.tm_mday, mons[now.tm_mon % 12], now.tm_year, now.tm_hour, now.tm_min, now.tm_sec);}/** * Allocate the connection's write buffer and * fill it with all of the headers from the * HTTPd's response. */static intMHD_build_header_response (struct MHD_Connection *connection){ size_t size; size_t off; struct MHD_HTTP_Header *pos; char code[32]; char date[128]; char *data; MHD_add_extra_headers (connection); SPRINTF (code, "%s %u\r\n", MHD_HTTP_VERSION_1_1, connection->responseCode); off = strlen (code); /* estimate size */ size = off + 2; /* extra \r\n at the end */ pos = connection->response->first_header; while (pos != NULL) { size += strlen (pos->header) + strlen (pos->value) + 4; /* colon, space, linefeeds */ pos = pos->next; } if (NULL == MHD_get_response_header (connection->response, MHD_HTTP_HEADER_DATE)) get_date_string (date, sizeof (date)); else date[0] = '\0'; size += strlen (date); /* produce data */ data = MHD_pool_allocate (connection->pool, size + 1, MHD_YES); if (data == NULL) { MHD_DLOG (connection->daemon, "Not enough memory for write!\n"); return MHD_NO; } memcpy (data, code, off); pos = connection->response->first_header; while (pos != NULL) { SPRINTF (&data[off], "%s: %s\r\n", pos->header, pos->value); off += strlen (pos->header) + strlen (pos->value) + 4; pos = pos->next; } strcpy (&data[off], date); off += strlen (date); sprintf (&data[off], "\r\n"); off += 2; if (off != size) abort (); connection->write_buffer = data; connection->writeLoc = size; connection->writePos = 0; connection->write_buffer_size = size + 1; return MHD_YES;}/** * This function was created to handle writes to sockets when it has * been determined that the socket can be written to. All * implementations (multithreaded, external select, internal select) * call this function */intMHD_connection_handle_write (struct MHD_Connection *connection){ struct MHD_Response *response; int ret; if (MHD_need_100_continue (connection)) { ret = SEND (connection->socket_fd, &HTTP_100_CONTINUE[connection->continuePos], strlen (HTTP_100_CONTINUE) - connection->continuePos, 0); if (ret < 0) { if (errno == EINTR) return MHD_YES; MHD_DLOG (connection->daemon, "Failed to send data: %s\n", STRERROR (errno)); CLOSE (connection->socket_fd); connection->socket_fd = -1; return MHD_YES; } connection->continuePos += ret; return MHD_YES; } response = connection->response; if (response == NULL) { MHD_DLOG (connection->daemon, "Unexpected call to %s.\n", __FUNCTION__); return MHD_NO; } if (!connection->headersSent) { if ((connection->write_buffer == NULL) && (MHD_NO == MHD_build_header_response (connection))) { /* oops - close! */ CLOSE (connection->socket_fd); connection->socket_fd = -1; return MHD_NO; } ret = SEND (connection->socket_fd, &connection->write_buffer[connection->writePos], connection->writeLoc - connection->writePos, 0); if (ret < 0) { if (errno == EINTR) return MHD_YES; MHD_DLOG (connection->daemon, "Failed to send data: %s\n", STRERROR (errno)); CLOSE (connection->socket_fd); connection->socket_fd = -1; return MHD_YES; } connection->writePos += ret; if (connection->writeLoc == connection->writePos) { connection->writeLoc = 0; connection->writePos = 0; connection->headersSent = 1; MHD_pool_reallocate (connection->pool, connection->write_buffer, connection->write_buffer_size, 0); connection->write_buffer = NULL; connection->write_buffer_size = 0; } return MHD_YES; } if (response->total_size < connection->messagePos) abort (); /* internal error */ if (response->crc != NULL) pthread_mutex_lock (&response->mutex); /* prepare send buffer */ if ((response->crc != NULL) && ((response->data_start > connection->messagePos) || (response->data_start + response->data_size <= connection->messagePos))) { ret = response->crc (response->crc_cls, connection->messagePos, response->data, MIN (response->data_buffer_size, response->total_size - connection->messagePos)); if (ret == -1) { /* end of message, signal other side by closing! */ response->total_size = connection->messagePos; CLOSE (connection->socket_fd); connection->socket_fd = -1; if (response->crc != NULL) pthread_mutex_unlock (&response->mutex); return MHD_YES; } response->data_start = connection->messagePos; response->data_size = ret; if (ret == 0) { if (response->crc != NULL) pthread_mutex_unlock (&response->mutex); return MHD_YES; } } /* transmit */ ret = SEND (connection->socket_fd, &response->data[connection->messagePos - response->data_start], response->data_size - (connection->messagePos - response->data_start), 0); if (response->crc != NULL) pthread_mutex_unlock (&response->mutex); if (ret < 0) { if (errno == EINTR) return MHD_YES; MHD_DLOG (connection->daemon, "Failed to send data: %s\n", STRERROR (errno)); CLOSE (connection->socket_fd); connection->socket_fd = -1; return MHD_YES; } connection->messagePos += ret; if (connection->messagePos > response->total_size) abort (); /* internal error */ if (connection->messagePos == response->total_size) { if ((connection->bodyReceived == 0) || (connection->headersReceived == 0)) abort (); /* internal error */ MHD_destroy_response (response); connection->continuePos = 0; connection->responseCode = 0; connection->response = NULL; connection->headers_received = NULL; connection->headersReceived = 0; connection->headersSent = 0; connection->bodyReceived = 0; connection->messagePos = 0; connection->method = NULL; connection->url = NULL; if ((connection->read_close == MHD_YES) || (0 != strcasecmp (MHD_HTTP_VERSION_1_1, connection->version))) { /* closed for reading => close for good! */ if (connection->socket_fd != -1) CLOSE (connection->socket_fd); connection->socket_fd = -1; } connection->version = NULL; connection->read_buffer = NULL; connection->write_buffer = NULL; connection->read_buffer_size = 0; connection->readLoc = 0; connection->write_buffer_size = 0; connection->writePos = 0; connection->writeLoc = 0; MHD_pool_destroy (connection->pool); connection->pool = NULL; } return MHD_YES;}/* end of connection.c */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -