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

📄 emhttp.c

📁 这是有名的<<嵌入式系统TCP/IP应用层协议>>,M.Tim Jones 著
💻 C
字号:
/* *  Embedded HTTP Server main * *  ./software/ch7/emhttps/emhttp.c * *  mtj@cogitollc.com * */#include <sys/socket.h>#include <arpa/inet.h>#include <signal.h>#include <stdio.h>#include <string.h>#include <sys/un.h>#include <unistd.h>#include "emhttp.h"#include "filehdlr.h"#include "dyncntnt.h"#include "log.h"const char *notimplemented={"HTTP/1.1 501 Not Implemented\n\n"};const char *notfound={"HTTP/1.1 404 File not found\n\n"};const char *success={"HTTP/1.1 200 OK\n"};const char *created={"HTTP/1.1 201 Created\n"};const char *content_types[]={	"text/html",	"application/octet-stream",	"image/jpeg",	"image/gif",	"text/plain",	"text/x-hdml"};/*--------------------------------------------------------------------------- * ouch() - signal handler for SIGPIPE (UN*X host only) *-------------------------------------------------------------------------*/void ouch ( int sigNum ){  /*    * Avoid EPIPE crash...    */}/*--------------------------------------------------------------------------- * getFilename() - Parse a filename out of the URL *-------------------------------------------------------------------------*/void getFilename(char *inbuf, char *out, int start){  int i=start, j=0;  /*    * Skip any initial spaces    */  while (inbuf[i] == ' ') i++;  for ( ; i < strlen(inbuf) ; i++) {    if (inbuf[i] == ' ') {      out[j] = 0;      break;    }    out[j++] = inbuf[i];  }  if (!strcmp(out, "/")) strcpy(out, "/index.html");}/*--------------------------------------------------------------------------- * determineContentType() - self explanatory *-------------------------------------------------------------------------*/int determineContentType(int fileOffset){  char suffix[20];  int  i;  extern unsigned char filedata[];  fileOffset+=2;  for ( ; filedata[fileOffset] != 0 ; fileOffset++) {    if (filedata[fileOffset] == '.') break;  }  if (filedata[fileOffset] == 0) return(TEXT_PLAIN);  else {    fileOffset++;    for (i = 0 ; filedata[fileOffset+i] != 0 ; i++) {      suffix[i] = filedata[fileOffset+i];    }    suffix[i] = 0;    /*      * Now that we've go the suffix, determine the content type      */    if (!strncmp(suffix, "html", 4) || !strncmp(suffix, "HTML", 4) ||	!strncmp(suffix, "htm", 3)  || !strncmp(suffix, "HTM", 3)) {      return(TEXT_HTML);    } else if (!strncmp(suffix, "class", 5) || !strncmp(suffix, "CLASS", 5) ||               !strncmp(suffix, "jar", 3)   ||  !strncmp(suffix, "JAR", 3)) {      return(OCTET_STREAM);    } else if (!strncmp(suffix, "jpeg", 4) || !strncmp(suffix, "JPEG", 4) ||               !strncmp(suffix, "jpg", 4)  || !strncmp(suffix, "JPG", 4)) {      return(JPEG_IMAGE);    } else if (!strncmp(suffix, "gif", 3) || !strncmp(suffix, "GIF", 3)) {      return(GIF_IMAGE);    } else if (!strncmp(suffix, "hdml", 4)) {      return(TEXT_HDML);    } else {      return(OCTET_STREAM);    }  }}/*--------------------------------------------------------------------------- * returnFileHeader() - Emit the HTTP response message through the socket *-------------------------------------------------------------------------*/void returnFileHeader(int fd, int ct){  char line[MAX_LINE+1];  write(fd, success, strlen(success));  sprintf(line, "Server: emhttp\n");   write(fd, line, strlen(line));  sprintf(line, "Connection: close\n");  write(fd, line, strlen(line));  sprintf(line, "Content-Type: %s\n\n", content_types[ct]);  write(fd, line, strlen(line));}/*--------------------------------------------------------------------------- * parseAndEmitFile() - Parse the HTML and replace dynamic content tags *-------------------------------------------------------------------------*/void parseAndEmitFile(int fd, struct fileHdrStruct *filehdr){  int i;  char content[MAX_LINE+1];  extern unsigned char filedata[];  /* Emit the dynamic HTML file replacing the <DATA #> with the appropriate   * content.   */  for (i = 0 ; i < filehdr->size ; i++) {    if (filedata[filehdr->fileStart+i] == '<') {      if (!strncmp(&filedata[filehdr->fileStart+i+1], "DATA", 4)) {        i+= 6;        getDynamicContent(&filedata[filehdr->fileStart+i], content);        /*         * Emit the dynamic content         */        write(fd, content, strlen(content));        for ( ; filedata[filehdr->fileStart+i] != '>' ; i++);      } else {        write(fd, &filedata[filehdr->fileStart+i], 1);      }    } else {      write(fd, &filedata[filehdr->fileStart+i], 1);    }  }}/*--------------------------------------------------------------------------- * returnFile() - High level return message function *-------------------------------------------------------------------------*/void returnFile(int fd, struct fileHdrStruct *filehdr){  int ct;  extern unsigned char filedata[];  ct = determineContentType(filehdr->hdrStart);  returnFileHeader(fd, ct);  if ((ct == TEXT_HTML) || (ct == TEXT_HDML)) {    parseAndEmitFile(fd, filehdr);  } else {    write(fd, &filedata[filehdr->fileStart], filehdr->size);  }}/*--------------------------------------------------------------------------- * findMsgBody() - Find the message body of an HTTP Request Message *-------------------------------------------------------------------------*/char *findMsgBody( char *buf ){  char *temp;  char *separator={"\015\012\015\012"};  temp = strstr(buf, separator);  if (temp == NULL) return NULL;  else return temp+4;}/*--------------------------------------------------------------------------- * handleConnection() - Parse and handle the current HTTP request message *-------------------------------------------------------------------------*/void handleConnection(int fd){  int len, max, loop;  char buffer[4096]={0};  char filename[256]={0};  int ret;  struct fileHdrStruct filehdr;  /*   * Read in the Request Header    */  max = 0;   loop = 1;  while (loop) {    len = read(fd, &buffer[max], 255); buffer[max+len] = 0;    if (len <= 0) return;    max += len;    if (!strncmp(buffer, "POST", 4)) {      if (strstr(buffer, "+Query")) loop = 0;    } else {      if ((buffer[max-4] == 0x0d) && (buffer[max-3] == 0x0a) &&          (buffer[max-2] == 0x0d) && (buffer[max-1] == 0x0a)) loop = 0;    }  }  /*   * Determine request    */  if (!strncmp(buffer, "GET", 3)) {    getFilename(buffer, filename, 4);    if (!strncmp(filename, "/log", 4)) {      sendLog(fd);    } else {      ret = lookupFilename(filename, &filehdr);      if (ret > 0) {        returnFile(fd, &filehdr);      } else {        emitByte(PREFIX_BYTE); emitByte(UNKNOWN_FILE);        emitString(filename);  emitByte(SUFFIX_BYTE);        write(fd, notfound, strlen(notfound));      }    }  } else if (!strncmp(buffer, "POST", 4)) {    getFilename(buffer, filename, 5);    ret = callDynamicHandler(filename, findMsgBody(buffer));    if (ret == 0) {      write(fd, created, strlen(created));    } else {      write(fd, notfound, strlen(notfound));    }    emitByte(PREFIX_BYTE); emitByte(POST_REQUEST);    emitString(filename);  emitByte(SUFFIX_BYTE);  } else {    write(fd, notimplemented, strlen(notimplemented));  }}/*--------------------------------------------------------------------------- * main() - The embedded HTTP server main *-------------------------------------------------------------------------*/int main(int argc, char *argv[]){  int listenfd, connfd, on=1;  socklen_t clilen;  struct sockaddr_in cliaddr, servaddr;  extern void userInit();  /* Init the dynamic content test func */  userInit();  (void)signal(SIGPIPE, ouch);  listenfd = socket(AF_INET, SOCK_STREAM, 0);  setsockopt( listenfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on) );  bzero((void *)&servaddr, sizeof(servaddr));  servaddr.sin_family = AF_INET;  servaddr.sin_addr.s_addr = htonl(INADDR_ANY);  servaddr.sin_port = htons(80);  bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr));  listen(listenfd, 5);  for ( ; ; ) {    clilen = sizeof(cliaddr);    connfd = accept(listenfd, (struct sockaddr *)&cliaddr, &clilen);    if (connfd <= 0) break;    handleConnection(connfd);    close(connfd);  }  close(listenfd);  return(0);}/* *  Copyright (c) 2002 Charles River Media.  All rights reserved. *  *  Redistribution and use in source and binary forms, with or  *  without modification, is hereby granted without fee provided  *  that the following conditions are met: *  *    1.  Redistributions of source code must retain the above  *        copyright notice, this list of conditions and the  *        following disclaimer. *    2.  Redistributions in binary form must reproduce the above *        copyright notice, this list of conditions and the  *        following disclaimer in the documentation and/or other  *        materials provided with the distribution. *    3.  Neither the name of Charles River Media nor the names of  *        its contributors may be used to endorse or promote products  *        derived from this software without specific prior  *        written permission. *  * THIS SOFTWARE IS PROVIDED BY CHARLES RIVER MEDIA AND CONTRIBUTERS  * 'AS IS' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL CHARLES * RIVER MEDIA OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,  * INCIDENTAL, SPECIAL, EXEMPLARAY, OR CONSEQUENTIAL DAMAGES (INCLUDING,  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE  * POSSIBILITY OF SUCH DAMAGE. */

⌨️ 快捷键说明

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