⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 connection.c

📁 一个 http 服务器的框架实现
💻 C
📖 第 1 页 / 共 3 页
字号:
  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 + -