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

📄 http-core.c

📁 Serveez是一个服务器框架
💻 C
📖 第 1 页 / 共 2 页
字号:
      break;    case 403:      txt = "Forbidden";      break;    case 404:      txt = "Not Found";      break;    case 405:      txt = "Method Not Allowed";      break;    case 406:      txt = "Not Acceptable";      break;    case 407:      txt = "Proxy Authentication Required";      break;    case 408:      txt = "Request Timeout";      break;    case 409:      txt = "Conflict";      break;    case 410:      txt = "Gone";      break;    case 411:      txt = "Length Required";      break;    case 412:      txt = "Precondition Failed";      break;    case 413:      txt = "Request Entity Too Large";      break;    case 414:      txt = "Request-URI Too Long";      break;    case 415:      txt = "Unsupported Media Type";      break;    case 416:      txt = "Requested Range Not Satisfiable";      break;    case 417:      txt = "Expectation Failed";      break;    case 500:      txt = "Internal Server Error";      break;    case 501:      txt = "Not Implemented";      break;    case 502:      txt = "Bad Gateway";      break;    case 503:      txt = "Service Unavailable";      break;    case 504:      txt = "Gateway Timeout";      break;    case 505:      txt = "HTTP Version Not Supported";      break;    default:       txt = "Bad Request";     }  http->response = response;  /* Send some standard error message. */  return svz_sock_printf (sock, 			  "<html><body bgcolor=white text=black><br>"			  "<h1>%d %s</h1>"			  "<hr noshade><i>%s/%s server at %s port %d, "			  "please send email to <a href=\"mailto:%s\">%s</a> "			  "for reporting errors</i>"			  "</body></html>",			  response, txt, 			  svz_library, svz_version,			  cfg->host ? cfg->host : 			  svz_inet_ntoa (sock->local_addr),			  ntohs (sock->local_port), cfg->admin, cfg->admin);}/* * This function is used to re-initialize a HTTP connection for * Keep-Alive connections. Return -1 if it is not 'Keep'able. */inthttp_keep_alive (svz_socket_t *sock){  if (sock->userflags & HTTP_FLAG_KEEP)    {      http_free_socket (sock);      sock->userflags &= ~HTTP_FLAG;       sock->read_socket = svz_tcp_read_socket;      sock->check_request = http_check_request;      sock->write_socket = http_default_write;      sock->send_buffer_fill = 0;      sock->idle_func = http_idle;#if ENABLE_DEBUG      svz_log (LOG_DEBUG, "http: keeping connection alive\n");#endif      return 0;    }  return -1;}/* * This function is used to check if the connection in SOCK is a * Keep-Alive connection and sends the appropriate HTTP header property. */voidhttp_check_keepalive (svz_socket_t *sock){  http_socket_t *http = sock->data;  http_config_t *cfg = sock->cfg;  if ((sock->userflags & HTTP_FLAG_KEEP) && http->keepalive > 0)    {      sock->idle_counter = cfg->timeout;      http_add_header ("Connection: Keep-Alive\r\n");      http_add_header ("Keep-Alive: timeout=%d, max=%d\r\n", 		       sock->idle_counter, cfg->keepalive);      http->keepalive--;    }  /* tell HTTP/1.1 clients that the connection is closed after delivery */  else    {      sock->userflags &= ~HTTP_FLAG_KEEP;      http_add_header ("Connection: close\r\n");    }}/* * Create a date format used within the Common Log Format. That is as * follows: [DD/MMM/YYYY:HH:MM:SS +ZZZZ] */char *http_clf_date (time_t t){  static char date[64];  static char months[12][4] = {    "Jan", "Feb", "Mar", "Apr", "May", "Jun",     "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"  };  struct tm *tm;  tm = localtime (&t);  sprintf (date, "%02d/%s/%04d:%02d:%02d:%02d %c%02ld%02ld",	   tm->tm_mday, months[tm->tm_mon], tm->tm_year + 1900,	   tm->tm_hour, tm->tm_min, tm->tm_sec,	   timezone > 0 ? '+' : '-',	   timezone > 0 ? timezone / 3600 : -timezone / 3600,	   timezone > 0 ? (timezone / 60) % 60 : -(timezone / 60) % 60);  return date;}/* * Produce a ASCTIME date without the trailing '\n' from a given time_t. */char *http_asc_date (time_t t){  static char asc[64];  struct tm * gm_time;  gm_time = gmtime (&t);  strftime (asc, 64, "%a, %d %b %Y %H:%M:%S GMT", gm_time);  return asc;}/* * Extract a date information from a given string and return a  * UTC time (time_t) as time() does. */time_thttp_parse_date (char *date){  struct tm parse_time;  int n;  char _month[4];  char _wkday[10];  time_t ret;  static char month[12][4] = {    "Jan", "Feb", "Mar", "Apr", "May", "Jun",     "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"  };  switch (date[3])    {      /* ASCTIME-Date */    case ' ':      sscanf (date, "%3s %3s %2d %02d:%02d:%02d %04d",	      _wkday, _month, &parse_time.tm_mday, &parse_time.tm_hour, 	      &parse_time.tm_min, &parse_time.tm_sec, &parse_time.tm_year);            break;      /* RFC1123-Date */    case ',':      sscanf (date, "%3s, %02d %3s %04d %02d:%02d:%02d GMT", 	      _wkday, &parse_time.tm_mday, _month, &parse_time.tm_year,	      &parse_time.tm_hour, &parse_time.tm_min, &parse_time.tm_sec);      break;      /* RFC850-Date */    default:      sscanf (date, "%s, %02d-%3s-%02d %02d:%02d:%02d GMT", 	      _wkday, &parse_time.tm_mday, _month, &parse_time.tm_year,	      &parse_time.tm_hour, &parse_time.tm_min, &parse_time.tm_sec);      parse_time.tm_mon += parse_time.tm_mon >= 70 ? 1900 : 2000;      break;    }      /* find the month identifier */  for (n = 0; n < 12; n++)    if (!memcmp (_month, month[n], 3))      parse_time.tm_mon = n;  parse_time.tm_isdst = daylight;  parse_time.tm_year -= 1900;  ret = mktime (&parse_time);  ret -= timezone;  if (daylight > 0)    ret += 3600;  return ret;}/* * Parse part of the receive buffer for HTTP request properties * and store it in the socket structure SOCK. Return the amount of * properties found in the request. */inthttp_parse_property (svz_socket_t *sock, char *request, char *end){  int properties, n;  char *p;  http_socket_t *http;  /* get the http socket structure */  http = sock->data;  /* reserve data space for the http properties */  http->property = svz_malloc (MAX_HTTP_PROPERTIES * 2 * sizeof (char *));  properties = 0;  n = 0;  /* find out properties if necessary */  while (SVZ_INT16 (request) != CRLF && properties < MAX_HTTP_PROPERTIES - 1)    {      /* get property entity identifier */      p = request;      while (*p != ':' && p < end)	p++;      if (p == end)	break;      http->property[n] = svz_malloc (p - request + 1);      strncpy (http->property[n], request, p - request);      http->property[n][p - request] = 0;      n++;      request = p + 2;      /* get property entity body */      while (SVZ_INT16 (p) != CRLF && p < end)	p++;      if (p == end || p <= request)	break;      http->property[n] = svz_malloc (p - request + 1);      strncpy (http->property[n], request, p - request);      http->property[n][p - request] = 0;      n++;      properties++;      request = p + 2;#if 0      printf ("http header: {%s} = {%s}\n", 	      http->property[n - 2], http->property[n - 1]);#endif    }  request += 2;  http->property[n] = NULL;  return properties;}/* * Find a given property entity in the HTTP request properties. * Return a NULL pointer if not found. */char *http_find_property (http_socket_t *http, char *key){  int n;  /* check if there are any properties */  if (http->property == NULL)    return NULL;  /* search through all the http properties */  n = 0;  while (http->property[n])    {      if (!svz_strcasecmp (http->property[n], key))	{	  return http->property[n + 1];	}      n += 2;    }  return NULL;}#define ASC_TO_HEX(c)                             \  if (c >= '0' && c <= '9') c -= '0';             \  else if (c >= 'a' && c <= 'f') c -= ('a' - 10); \  else if (c >= 'A' && c <= 'F') c -= ('A' - 10);/* * Convert hexadecimal encoded characters within the URI. This is  * necessary for some special characters. The URI is a Uniform Resource  * Identifier meaning the requested file. */voidhttp_process_uri (char *uri){  char *p;  char h, l;  /* Test if there is any occurrence of the special character encoding. */  while ((p = strchr (uri, '%')) != NULL)    {      if ((h = *(p + 1)) != 0 && (l = *(p + 2)) != 0)	{	  /* Convert to byte. */	  ASC_TO_HEX (h);	  ASC_TO_HEX (l);	  *p = (char) ((h << 4) | l);	  /* Copy rest of URI. */	  uri = ++p;	  while (*(p + 2))	    {	      *p = *(p + 2);	      p++;	    }	  *p = '\0';	}      else	break;    }}/* * This routine gets all available content types from a given * file which should have kind of "/etc/mime.types"s format. */#define TYPES_LINE_SIZE 1024inthttp_read_types (http_config_t *cfg){  FILE *f;  char *line;  char *p, *end;  char *content;  char *suffix;  char *content_type;  /* create the content type hash table if necessary */  if (cfg->types == NULL)    cfg->types = svz_hash_create (4);  /* try open the file */  if ((f = svz_fopen (cfg->type_file, "rt")) == NULL)    {      return -1;    }  line = svz_malloc (TYPES_LINE_SIZE);  /* read all lines within the file */  while ((fgets (line, TYPES_LINE_SIZE, f)) != NULL)    {      /* delete all trailing newline characters, skip empty lines */      p = line + strlen (line) - 1;      while (p != line && (*p == '\r' || *p == '\n'))	p--;      if (p == line)	continue;      *(p + 1) = 0;      p = line;      end = line + strlen (line);      /* parse content type */      content = line;      while (p < end && (*p != ' ' && *p != '\t'))	p++;      *p++ = 0;      /* parse all file suffixes associated with this content type */      while (p < end)	{	  while (p < end && (*p == ' ' || *p == '\t'))	    p++;	  if (p == end)	    break;	  suffix = p;	  while (p < end && (*p != ' ' && *p != '\t'))	    p++;	  *p++ = 0;	  if (strlen (suffix))	    {	      /* 	       * add the given content type to the hash if it does not	       * contain it already	       */	      if (!svz_hash_get (cfg->types, suffix))		{		  content_type = svz_malloc (strlen (content) + 1);		  strcpy (content_type, content);		  svz_hash_put (cfg->types, suffix, content_type);		}	    }	}    }  svz_fclose (f);  svz_free (line);  return 0;}/* * This routine delivers a valid content type for a given file. * It falls back to the socket's http configuration default content * type if the suffix could not be found. */char *http_find_content_type (svz_socket_t *sock, char *file){  http_config_t *cfg = sock->cfg;  char *suffix = file + strlen (file) - 1;  char *type;  /* parse file back until a trailing '.' */  while (suffix > file && *suffix != '.')    suffix--;  if (suffix != file)    suffix++;  /* find this file suffix in the content type hash */  if ((type = svz_hash_get (cfg->types, suffix)) != NULL)    {      return type;    }  return cfg->default_type;}/* * This routine converts a relative file/path name into an * absolute file/path name. The given argument will be reallocated * if necessary. */char *http_absolute_file (char *file){  char *savedir;  char *p;  char *savefile;  char *dir;  int have_path = 0;  /* find any path separator in the file */  p = file + strlen (file) - 1;  while (p > file && *p != '/' && *p != '\\')    p--;  if (*p == '/' || *p == '\\')    {      have_path = 1;      p++;    }  /* save the filename within a buffer */  savefile = svz_strdup (p);  /* get current work directory */  savedir = svz_getcwd ();    /*    * If there was no path separator in the filename then just concate   * current work directory and filename.   */  if (!have_path)    {      savedir = svz_realloc (savedir, strlen (savedir) + strlen (file) + 2);      strcat (savedir, "/");      strcat (savedir, savefile);      svz_free (file);      return savedir;    }    /* change to give directory (absolute or relative)  */  *p = 0;  if (chdir (file) == -1)    {      *p = '/';      svz_log (LOG_ERROR, "chdir: %s\n", SYS_ERROR);#if ENABLE_DEBUG      svz_log (LOG_DEBUG, "cannot change dir: %s\n", file);#endif      svz_free (savefile);      svz_free (savedir);      return file;    }  *p = '/';  /* get now the current work directory */  dir = svz_getcwd ();  /* concate new work directory with given filename */  dir = svz_realloc (dir, strlen (dir) + strlen (savefile) + 2);  strcat (dir, "/");  strcat (dir, savefile);  svz_free (savefile);  svz_free (file);  /* change back to the original work directory */  chdir (savedir);  svz_free (savedir);  return dir;}#else /* ENABLE_HTTP_PROTO */int http_core_dummy; /* Shut compiler warnings up. */#endif /* not ENABLE_HTTP_PROTO */

⌨️ 快捷键说明

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