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

📄 http.c

📁 穿越防火墙技术代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/*http.cCopyright (C) 1999 Lars Brinkhoff.  See COPYING for terms and conditions.bug alert: parse_header() doesn't handle header fields that are extendedover multiple lines.*/#include <time.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include "http.h"#include "common.h"static inline ssize_thttp_method (int fd, Http_destination *dest,	     Http_method method, ssize_t length){  char str[1024]; /* FIXME: possible buffer overflow */  Http_request *request;  ssize_t n;  if (fd == -1)    {      log_error ("http_method: fd == -1");      return -1;    }  n = 0;  if (dest->proxy_name != NULL)    n = sprintf (str, "http://%s:%d", dest->host_name, dest->host_port);  sprintf (str + n, "/index.html?crap=%ld", time (NULL));  request = http_create_request (method, str, 1, 1);  if (request == NULL)    return -1;  sprintf (str, "%s:%d", dest->host_name, dest->host_port);  http_add_header (&request->header, "Host", str);  if (length >= 0)    {      sprintf (str, "%d", length);      http_add_header (&request->header, "Content-Length", str);    }  http_add_header (&request->header, "Connection", "close");  if (dest->proxy_authorization)    {      http_add_header (&request->header,		       "Proxy-Authorization",		       dest->proxy_authorization);    }  if (dest->user_agent)    {      http_add_header (&request->header,		       "User-Agent",		       dest->user_agent);    }  n = http_write_request (fd, request);  http_destroy_request (request);  return n;}ssize_thttp_get (int fd, Http_destination *dest){  return http_method (fd, dest, HTTP_GET, -1);}ssize_thttp_put (int fd, Http_destination *dest, size_t length){  return http_method (fd, dest, HTTP_PUT, (ssize_t)length);}ssize_thttp_post (int fd, Http_destination *dest, size_t length){  return http_method (fd, dest, HTTP_POST, (ssize_t)length);}inthttp_error_to_errno (int err){  /* Error codes taken from RFC2068. */  switch (err)    {    case -1: /* system error */      return errno;    case -200: /* OK */    case -201: /* Created */    case -202: /* Accepted */    case -203: /* Non-Authoritative Information */    case -204: /* No Content */    case -205: /* Reset Content */    case -206: /* Partial Content */      return 0;    case -400: /* Bad Request */      log_error ("http_error_to_errno: 400 bad request");      return EIO;    case -401: /* Unauthorized */      log_error ("http_error_to_errno: 401 unauthorized");      return EACCES;    case -403: /* Forbidden */      log_error ("http_error_to_errno: 403 forbidden");      return EACCES;    case -404: /* Not Found */      log_error ("http_error_to_errno: 404 not found");      return ENOENT;    case -411: /* Length Required */      log_error ("http_error_to_errno: 411 length required");      return EIO;    case -413: /* Request Entity Too Large */      log_error ("http_error_to_errno: 413 request entity too large");      return EIO;    case -505: /* HTTP Version Not Supported       */      log_error ("http_error_to_errno: 413 HTTP version not supported");      return EIO;    case -100: /* Continue */    case -101: /* Switching Protocols */    case -300: /* Multiple Choices */    case -301: /* Moved Permanently */    case -302: /* Moved Temporarily */    case -303: /* See Other */    case -304: /* Not Modified */    case -305: /* Use Proxy */     case -402: /* Payment Required */    case -405: /* Method Not Allowed */    case -406: /* Not Acceptable */    case -407: /* Proxy Autentication Required */    case -408: /* Request Timeout */    case -409: /* Conflict */    case -410: /* Gone */    case -412: /* Precondition Failed */    case -414: /* Request-URI Too Long */    case -415: /* Unsupported Media Type */    case -500: /* Internal Server Error */    case -501: /* Not Implemented */    case -502: /* Bad Gateway */    case -503: /* Service Unavailable */    case -504: /* Gateway Timeout */      log_error ("http_error_to_errno: HTTP error %d", err);      return EIO;    default:      log_error ("http_error_to_errno: unknown error %d", err);      return EIO;    }}static Http_methodhttp_string_to_method (const char *method, size_t n){  if (strncmp (method, "GET", n) == 0)    return HTTP_GET;  if (strncmp (method, "PUT", n) == 0)    return HTTP_PUT;  if (strncmp (method, "POST", n) == 0)    return HTTP_POST;  if (strncmp (method, "OPTIONS", n) == 0)    return HTTP_OPTIONS;  if (strncmp (method, "HEAD", n) == 0)    return HTTP_HEAD;  if (strncmp (method, "DELETE", n) == 0)    return HTTP_DELETE;  if (strncmp (method, "TRACE", n) == 0)    return HTTP_TRACE;  return -1;}static const char *http_method_to_string (Http_method method){  switch (method)    {    case HTTP_GET: return "GET";    case HTTP_PUT: return "PUT";    case HTTP_POST: return "POST";    case HTTP_OPTIONS: return "OPTIONS";    case HTTP_HEAD: return "HEAD";    case HTTP_DELETE: return "DELETE";    case HTTP_TRACE: return "TRACE";    }  return "(uknown)";}static ssize_tread_until (int fd, int ch, unsigned char **data){  unsigned char *buf, *buf2;  ssize_t n, len, buf_size;  *data = NULL;  buf_size = 100;  buf = malloc (buf_size);  if (buf == NULL)    {      log_error ("read_until: out of memory");      return -1;    }  len = 0;  while ((n = read_all (fd, buf + len, 1)) == 1)    {      if (buf[len++] == ch)	break;      if (len + 1 == buf_size)	{	  buf_size *= 2;	  buf2 = realloc (buf, buf_size);	  if (buf2 == NULL)	    {	      log_error ("read_until: realloc failed");	      free (buf);	      return -1;	    }	  buf = buf2;	}    }  if (n <= 0)    {      free (buf);      if (n == 0)	log_error ("read_until: closed");      else	log_error ("read_until: read error: %s", strerror (errno));      return n;    }  /* Shrink to minimum size + 1 in case someone wants to add a NUL. */  buf2 = realloc (buf, len + 1);  if (buf2 == NULL)    log_error ("read_until: realloc: shrink failed"); /* not fatal */  else    buf = buf2;  *data = buf;  return len;}static inline Http_header *http_alloc_header (const char *name, const char *value){  Http_header *header;  header = malloc (sizeof (Http_header));  if (header == NULL)    return NULL;  header->name = header->value = NULL;  header->name = strdup (name);  header->value = strdup (value);  if (name == NULL || value == NULL)    {      if (name == NULL)	free ((char *)name);      if (value == NULL)	free ((char *)value);      free (header);      return NULL;    }  return header;}Http_header *http_add_header (Http_header **header, const char *name, const char *value){  Http_header *new_header;  new_header = http_alloc_header (name, value);  if (new_header == NULL)    return NULL;  new_header->next = NULL;  while (*header)    header = &(*header)->next;  *header = new_header;  return new_header;}static ssize_tparse_header (int fd, Http_header **header){  unsigned char buf[2];  unsigned char *data;  Http_header *h;  size_t len;  ssize_t n;  *header = NULL;  n = read_all (fd, buf, 2);  if (n <= 0)    return n;  if (buf[0] == '\r' && buf[1] == '\n')    return n;  h = malloc (sizeof (Http_header));  if (h == NULL)    {      log_error ("parse_header: malloc failed");      return -1;    }  *header = h;  h->name = NULL;  h->value = NULL;  n = read_until (fd, ':', &data);  if (n <= 0)    return n;  data = realloc (data, n + 2);  if (data == NULL)    {      log_error ("parse_header: realloc failed");      return -1;    }  memmove (data + 2, data, n);  memcpy (data, buf, 2);  n += 2;  data[n - 1] = 0;  h->name = data;  len = n;  n = read_until (fd, '\r', &data);  if (n <= 0)    return n;  data[n - 1] = 0;  h->value = data;  len += n;  n = read_until (fd, '\n', &data);  if (n <= 0)    return n;  free (data);  if (n != 1)    {      log_error ("parse_header: invalid line ending");      return -1;    }  len += n;  log_verbose ("parse_header: %s:%s", h->name, h->value);  n = parse_header (fd, &h->next);  if (n <= 0)    return n;  len += n;  return len;}static ssize_thttp_write_header (int fd, Http_header *header){  ssize_t n = 0, m;  if (header == NULL)    return write_all (fd, "\r\n", 2);  m = write_all (fd, (void *)header->name, strlen (header->name));  if (m == -1)    {      return -1;    }  n += m;  m = write_all (fd, ": ", 2);  if (m == -1)    {      return -1;    }  n += m;  m = write_all (fd, (void *)header->value, strlen (header->value));  if (m == -1)    {      return -1;    }  n += m;  m = write_all (fd, "\r\n", 2);  if (m == -1)    {      return -1;    }  n += m;  m = http_write_header (fd, header->next);  if (m == -1)    {      return -1;    }  n += m;  return n;}static voidhttp_destroy_header (Http_header *header){  if (header == NULL)    return;  http_destroy_header (header->next);  if (header->name)    free ((char *)header->name);  if (header->value)    free ((char *)header->value);  free (header);}static inline Http_response *http_allocate_response (const char *status_message){  Http_response *response;  response = malloc (sizeof (Http_response));  if (response == NULL)    return NULL;

⌨️ 快捷键说明

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