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

📄 httpd.c

📁 這是一個實時嵌入式作業系統 實作了MCS51 ARM等MCU
💻 C
📖 第 1 页 / 共 2 页
字号:
      if (newlen > HTTPD_IOBUFFER_SIZE)        {          newlen   = HTTPD_IOBUFFER_SIZE;          chunklen = HTTPD_IOBUFFER_SIZE - pstate->ht_sndlen;        }      else        {          chunklen = len;        }      vdbg("[%d] sndlen=%d len=%d newlen=%d chunklen=%d\n",           pstate->ht_sockfd, pstate->ht_sndlen, len, newlen, chunklen);      /* Copy that chunk into the send buffer */      memcpy(&pstate->ht_buffer[pstate->ht_sndlen], buffer, chunklen);      if (newlen >= HTTPD_IOBUFFER_SIZE)        {          /* The buffer is full.. Send what we have and reset to send again */          httpd_dumpbuffer(pstate->ht_buffer, newlen);          ret = send(pstate->ht_sockfd, pstate->ht_buffer, newlen, 0);          if (ret < 0)            {              return ret;            }          newlen = 0;        }      pstate->ht_sndlen = newlen;      len              -= chunklen;      buffer           += chunklen;    }  while (len > 0);  return OK;}static int send_headers(struct httpd_state *pstate, const char *statushdr, int len){  char *ptr;  int ret;  ret = httpd_addchunk(pstate, statushdr, len);  if (ret < 0)    {      return ret;    }  ptr = strrchr(pstate->ht_filename, ISO_period);  if (ptr == NULL)    {      ret = httpd_addchunk(pstate, g_httpcontenttypebinary, strlen(g_httpcontenttypebinary));    }  else if (strncmp(g_httpextensionhtml, ptr, strlen(g_httpextensionhtml)) == 0 ||           strncmp(g_httpextensionshtml, ptr, strlen(g_httpextensionshtml)) == 0)    {      ret = httpd_addchunk(pstate, g_httpcontenttypehtml, strlen(g_httpcontenttypehtml));    }  else if (strncmp(g_httpextensioncss, ptr, strlen(g_httpextensioncss)) == 0)    {      ret = httpd_addchunk(pstate, g_httpcontenttypecss, strlen(g_httpcontenttypecss));    }  else if (strncmp(g_httpextensionpng, ptr, strlen(g_httpextensionpng)) == 0)    {      ret = httpd_addchunk(pstate, g_httpcontenttypepng, strlen(g_httpcontenttypepng));    }  else if (strncmp(g_httpextensiongif, ptr, strlen(g_httpextensiongif)) == 0)    {      ret = httpd_addchunk(pstate, g_httpcontenttypegif, strlen(g_httpcontenttypegif));    }  else if (strncmp(g_httpextensionjpg, ptr, strlen(g_httpextensionjpg)) == 0)    {      ret = httpd_addchunk(pstate, g_httpcontenttypejpg, strlen(g_httpcontenttypejpg));    }  else    {      ret = httpd_addchunk(pstate, g_httpcontenttypeplain, strlen(g_httpcontenttypeplain));    }  return ret;}static int httpd_sendfile(struct httpd_state *pstate){  char *ptr;  int ret = ERROR;  pstate->ht_sndlen = 0;  if (!httpd_fs_open(pstate->ht_filename, &pstate->ht_file))    {      memcpy(pstate->ht_filename, g_http404path, strlen(g_http404path));      httpd_fs_open(g_http404path, &pstate->ht_file);      if (send_headers(pstate, g_httpheader404, strlen(g_httpheader404)) == OK)        {          ret = httpd_addchunk(pstate, pstate->ht_file.data, pstate->ht_file.len);        }    }  else    {      if (send_headers(pstate, g_httpheader200, strlen(g_httpheader200)) == OK)        {          ptr = strchr(pstate->ht_filename, ISO_period);          if (ptr != NULL &&              strncmp(ptr, g_httpextensionshtml, strlen(g_httpextensionshtml)) == 0)            {              ret = handle_script(pstate);            }          else            {              ret = httpd_addchunk(pstate, pstate->ht_file.data, pstate->ht_file.len);            }        }    }  /* Send anything remaining in the buffer */  if (ret == OK && pstate->ht_sndlen > 0)    {      httpd_dumpbuffer(pstate->ht_buffer, pstate->ht_sndlen);      if (send(pstate->ht_sockfd, pstate->ht_buffer, pstate->ht_sndlen, 0) < 0)        {          ret = ERROR;        }    }  return ret;}static inline int httpd_cmd(struct httpd_state *pstate){  ssize_t recvlen;  int i;  /* Get the next HTTP command.  We will handle only GET */  recvlen = recv(pstate->ht_sockfd, pstate->ht_buffer, HTTPD_IOBUFFER_SIZE, 0);  if (recvlen < 0)    {      dbg("[%d] recv failed: %d\n", pstate->ht_sockfd, errno);      return ERROR;    }  httpd_dumpbuffer(pstate->ht_buffer, recvlen);  /*  We will handle only GET */  if (strncmp(pstate->ht_buffer, g_httpcmdget, strlen(g_httpcmdget)) != 0)    {      dbg("[%d] Unsupported command\n", pstate->ht_sockfd);      return ERROR;    }  /* Get the name of the file to provide */  if (pstate->ht_buffer[4] != ISO_slash)    {      dbg("[%d] Missing path\n", pstate->ht_sockfd);      return ERROR;    }  else if (pstate->ht_buffer[5] == ISO_space)    {      strncpy(pstate->ht_filename, g_httpindexpath, strlen(g_httpindexpath));    }  else    {      for (i = 0;           i < (HTTPD_MAX_FILENAME-1) && pstate->ht_buffer[i+4] != ISO_space;           i++)        {          pstate->ht_filename[i] = pstate->ht_buffer[i+4];        }        pstate->ht_filename[i]='\0';    }  dbg("[%d] Filename: %s\n", pstate->ht_sockfd, pstate->ht_filename);  /* Then send the file */  return httpd_sendfile(pstate);}/**************************************************************************** * Name: httpd_handler * * Description: *   Each time a new connection to port 80 is made, a new thread is created *   that begins at this entry point.  There should be exactly one argument *   and it should be the socket descriptor (+1). * ****************************************************************************/static void *httpd_handler(void *arg){  struct httpd_state *pstate = (struct httpd_state *)malloc(sizeof(struct httpd_state));  int                 sockfd = (int)arg;  int                 ret    = ERROR;  dbg("[%d] Started\n", sockfd);  /* Verify that the state structure was successfully allocated */  if (pstate)    {      /* Loop processing each HTTP command *///    do        {          /* Re-initialize the thread state structure */          memset(pstate, 0, sizeof(struct httpd_state));          pstate->ht_sockfd = sockfd;          /* Then handle the next httpd command */          ret = httpd_cmd(pstate);        }//    while (ret == OK);      /* End of command processing -- Clean up and exit */      free(pstate);    }  /* Exit the task */  dbg("[%d] Exitting\n", sockfd);  close(sockfd);  pthread_exit(NULL);}/**************************************************************************** * Public Functions ****************************************************************************//**************************************************************************** * Name: httpd_listen * * Description: *   This is the main processing thread for the webserver.  It never returns *   unless an error occurs * ****************************************************************************/int httpd_listen(void){  /* Execute httpd_handler on each connection to port 80 */  uip_server(HTONS(80), httpd_handler, CONFIG_NETUTILS_HTTPDSTACKSIZE);  /* uip_server only returns on errors */  return ERROR;}/**************************************************************************** * Name: httpd_init * * Description: *   This function initializes the web server and should be called at system *   boot-up. * ****************************************************************************/void httpd_init(void){}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -