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

📄 http.c

📁 ipp打印机服务器原代码 注意:请将ipp.gz改为ipp.tar.gz 然后使用tar zxvf ipp.tar.gz解压 站长注意
💻 C
📖 第 1 页 / 共 4 页
字号:
/* * "$Id: http.c,v 1.144 2005/01/03 19:29:45 mike Exp $" * *   HTTP routines for the Common UNIX Printing System (CUPS). * *   Copyright 1997-2005 by Easy Software Products, all rights reserved. * *   These coded instructions, statements, and computer programs are the *   property of Easy Software Products and are protected by Federal *   copyright law.  Distribution and use rights are outlined in the file *   "LICENSE.txt" which should have been included with this file.  If this *   file is missing or damaged please contact Easy Software Products *   at: * *       Attn: CUPS Licensing Information *       Easy Software Products *       44141 Airport View Drive, Suite 204 *       Hollywood, Maryland 20636 USA * *       Voice: (301) 373-9600 *       EMail: cups-info@cups.org *         WWW: http://www.cups.org * *   This file is subject to the Apple OS-Developed Software exception. * * Contents: * *   httpInitialize()     - Initialize the HTTP interface library and set the *                          default HTTP proxy (if any). *   httpCheck()          - Check to see if there is a pending response from *                          the server. *   httpClearCookie()    - Clear the cookie value(s). *   httpClose()          - Close an HTTP connection... *   httpConnect()        - Connect to a HTTP server. *   httpConnectEncrypt() - Connect to a HTTP server using encryption. *   httpEncryption()     - Set the required encryption on the link. *   httpReconnect()      - Reconnect to a HTTP server... *   httpGetSubField()    - Get a sub-field value. *   httpSetField()       - Set the value of an HTTP header. *   httpDelete()         - Send a DELETE request to the server. *   httpGet()            - Send a GET request to the server. *   httpHead()           - Send a HEAD request to the server. *   httpOptions()        - Send an OPTIONS request to the server. *   httpPost()           - Send a POST request to the server. *   httpPut()            - Send a PUT request to the server. *   httpTrace()          - Send an TRACE request to the server. *   httpFlush()          - Flush data from a HTTP connection. *   httpRead()           - Read data from a HTTP connection. *   httpSetCookie()      - Set the cookie value(s)... *   httpWait()           - Wait for data available on a connection. *   httpWrite()          - Write data to a HTTP connection. *   httpGets()           - Get a line of text from a HTTP connection. *   httpPrintf()         - Print a formatted string to a HTTP connection. *   httpGetDateString()  - Get a formatted date/time string from a time value. *   httpGetDateTime()    - Get a time value from a formatted date/time string. *   httpUpdate()         - Update the current HTTP state for incoming data. *   httpDecode64()       - Base64-decode a string. *   httpDecode64_2()     - Base64-decode a string. *   httpEncode64()       - Base64-encode a string. *   httpEncode64_2()     - Base64-encode a string. *   httpGetLength()      - Get the amount of data remaining from the *                          content-length or transfer-encoding fields. *   http_field()         - Return the field index for a field name. *   http_send()          - Send a request with all fields and the trailing *                          blank line. *   http_wait()          - Wait for data available on a connection. *   http_upgrade()       - Force upgrade to TLS encryption. *   http_setup_ssl()     - Set up SSL/TLS on a connection. *   http_shutdown_ssl()  - Shut down SSL/TLS on a connection. *   http_read_ssl()      - Read from a SSL/TLS connection. *   http_write_ssl()     - Write to a SSL/TLS connection. *   CDSAReadFunc()       - Read function for CDSA decryption code. *   CDSAWriteFunc()      - Write function for CDSA encryption code. *//* * Include necessary headers... */#include "http-private.h"#include <stdio.h>#include <stdlib.h>#include <stdarg.h>#include <ctype.h>#include "string.h"#include <fcntl.h>#include <errno.h>#include "http.h"#include "debug.h"#ifndef WIN32#  include <signal.h>#  include <sys/time.h>#  include <sys/resource.h>#endif /* !WIN32 *//* * Some operating systems have done away with the Fxxxx constants for * the fcntl() call; this works around that "feature"... */#ifndef FNONBLK#  define FNONBLK O_NONBLOCK#endif /* !FNONBLK *//* * Local functions... */static http_field_t	http_field(const char *name);static int		http_send(http_t *http, http_state_t request,			          const char *uri);static int		http_wait(http_t *http, int msec);#ifdef HAVE_SSLstatic int		http_upgrade(http_t *http);static int		http_setup_ssl(http_t *http);static void		http_shutdown_ssl(http_t *http);static int		http_read_ssl(http_t *http, char *buf, int len);static int		http_write_ssl(http_t *http, const char *buf, int len);#  ifdef HAVE_CDSASSLstatic OSStatus		CDSAReadFunc(SSLConnectionRef connection, void *data, size_t *dataLength);static OSStatus		CDSAWriteFunc(SSLConnectionRef connection, const void *data, size_t *dataLength);#  endif /* HAVE_CDSASSL */#endif /* HAVE_SSL *//* * Local globals... */static const char * const http_fields[] =			{			  "Accept-Language",			  "Accept-Ranges",			  "Authorization",			  "Connection",			  "Content-Encoding",			  "Content-Language",			  "Content-Length",			  "Content-Location",			  "Content-MD5",			  "Content-Range",			  "Content-Type",			  "Content-Version",			  "Date",			  "Host",			  "If-Modified-Since",			  "If-Unmodified-since",			  "Keep-Alive",			  "Last-Modified",			  "Link",			  "Location",			  "Range",			  "Referer",			  "Retry-After",			  "Transfer-Encoding",			  "Upgrade",			  "User-Agent",			  "WWW-Authenticate"			};static const char * const days[7] =			{			  "Sun",			  "Mon",			  "Tue",			  "Wed",			  "Thu",			  "Fri",			  "Sat"			};static const char * const months[12] =			{			  "Jan",			  "Feb",			  "Mar",			  "Apr",			  "May",			  "Jun",		          "Jul",			  "Aug",			  "Sep",			  "Oct",			  "Nov",			  "Dec"			};/* * 'httpInitialize()' - Initialize the HTTP interface library and set the *                      default HTTP proxy (if any). */voidhttpInitialize(void){#ifdef HAVE_LIBSSL#  ifndef WIN32  struct timeval	curtime;	/* Current time in microseconds */#  endif /* !WIN32 */  int			i;		/* Looping var */  unsigned char		data[1024];	/* Seed data */#endif /* HAVE_LIBSSL */#ifdef WIN32  WSADATA	winsockdata;		/* WinSock data */  static int	initialized = 0;	/* Has WinSock been initialized? */  if (!initialized)    WSAStartup(MAKEWORD(1,1), &winsockdata);#elif defined(HAVE_SIGSET)  sigset(SIGPIPE, SIG_IGN);#elif defined(HAVE_SIGACTION)  struct sigaction	action;		/* POSIX sigaction data */ /*  * Ignore SIGPIPE signals...  */  memset(&action, 0, sizeof(action));  action.sa_handler = SIG_IGN;  sigaction(SIGPIPE, &action, NULL);#else  signal(SIGPIPE, SIG_IGN);#endif /* WIN32 */#ifdef HAVE_GNUTLS  gnutls_global_init();#endif /* HAVE_GNUTLS */#ifdef HAVE_LIBSSL  SSL_load_error_strings();  SSL_library_init(); /*  * Using the current time is a dubious random seed, but on some systems  * it is the best we can do (on others, this seed isn't even used...)  */#ifdef WIN32#else  gettimeofday(&curtime, NULL);  srand(curtime.tv_sec + curtime.tv_usec);#endif /* WIN32 */  for (i = 0; i < sizeof(data); i ++)    data[i] = rand(); /* Yes, this is a poor source of random data... */  RAND_seed(&data, sizeof(data));#endif /* HAVE_LIBSSL */}/* * 'httpCheck()' - Check to see if there is a pending response from the server. */int				/* O - 0 = no data, 1 = data available */httpCheck(http_t *http)		/* I - HTTP connection */{  return (httpWait(http, 0));}/* * 'httpClearCookie()' - Clear the cookie value(s). */voidhttpClearCookie(http_t *http)			/* I - Connection */{  if (!http)    return;  if (http->cookie)  {    free(http->cookie);    http->cookie = NULL;  }}/* * 'httpClose()' - Close an HTTP connection... */voidhttpClose(http_t *http)		/* I - Connection to close */{  DEBUG_printf(("httpClose(http=%p)\n", http));  if (!http)    return;  if (http->input_set)    free(http->input_set);  if (http->cookie)    free(http->cookie);#ifdef HAVE_SSL  if (http->tls)    http_shutdown_ssl(http);#endif /* HAVE_SSL */#ifdef WIN32  closesocket(http->fd);#else  close(http->fd);#endif /* WIN32 */  free(http);}/* * 'httpConnect()' - Connect to a HTTP server. */http_t *			/* O - New HTTP connection */httpConnect(const char *host,	/* I - Host to connect to */            int        port)	/* I - Port number */{  http_encryption_t	encrypt;/* Type of encryption to use */ /*  * Set the default encryption status...  */  if (port == 443)    encrypt = HTTP_ENCRYPT_ALWAYS;  else    encrypt = HTTP_ENCRYPT_IF_REQUESTED;  return (httpConnectEncrypt(host, port, encrypt));}/* * 'httpConnectEncrypt()' - Connect to a HTTP server using encryption. */http_t *				/* O - New HTTP connection */httpConnectEncrypt(const char *host,	/* I - Host to connect to */                   int        port,	/* I - Port number */		   http_encryption_t encrypt)					/* I - Type of encryption to use */{  int			i;		/* Looping var */  http_t		*http;		/* New HTTP connection */  struct hostent	*hostaddr;	/* Host address data */  DEBUG_printf(("httpConnectEncrypt(host=\"%s\", port=%d, encrypt=%d)\n",                host ? host : "(null)", port, encrypt));  if (!host)    return (NULL);  httpInitialize(); /*  * Lookup the host...  */  if ((hostaddr = httpGetHostByName(host)) == NULL)  {   /*    * This hack to make users that don't have a localhost entry in    * their hosts file or DNS happy...    */    if (strcasecmp(host, "localhost") != 0)      return (NULL);    else if ((hostaddr = httpGetHostByName("127.0.0.1")) == NULL)      return (NULL);  } /*  * Verify that it is an IPv4 address (IPv6 support will come in CUPS 1.2...)  */  if (hostaddr->h_addrtype != AF_INET || hostaddr->h_length != 4)    return (NULL); /*  * Allocate memory for the structure...  */  http = calloc(sizeof(http_t), 1);  if (http == NULL)    return (NULL);  http->version  = HTTP_1_1;  http->blocking = 1;  http->activity = time(NULL);  http->fd       = -1; /*  * Copy the hostname and port and then "reconnect"...  */  strlcpy(http->hostname, host, sizeof(http->hostname));  http->hostaddr.sin_family = hostaddr->h_addrtype;#ifdef WIN32  http->hostaddr.sin_port   = htons((u_short)port);#else  http->hostaddr.sin_port   = htons(port);#endif /* WIN32 */ /*  * Set the encryption status...  */  if (port == 443)	/* Always use encryption for https */    http->encryption = HTTP_ENCRYPT_ALWAYS;  else    http->encryption = encrypt; /*  * Loop through the addresses we have until one of them connects...  */  strlcpy(http->hostname, host, sizeof(http->hostname));  for (i = 0; hostaddr->h_addr_list[i]; i ++)  {   /*    * Load the address...    */    memcpy((char *)&(http->hostaddr.sin_addr), hostaddr->h_addr_list[i],           hostaddr->h_length);   /*    * Connect to the remote system...    */    if (!httpReconnect(http))      return (http);  } /*  * Could not connect to any known address - bail out!  */  free(http);  return (NULL);}/* * 'httpEncryption()' - Set the required encryption on the link. */int					/* O - -1 on error, 0 on success */httpEncryption(http_t            *http,	/* I - HTTP data */               http_encryption_t e)	/* I - New encryption preference */{  DEBUG_printf(("httpEncryption(http=%p, e=%d)\n", http, e));#ifdef HAVE_SSL  if (!http)    return (0);  http->encryption = e;  if ((http->encryption == HTTP_ENCRYPT_ALWAYS && !http->tls) ||      (http->encryption == HTTP_ENCRYPT_NEVER && http->tls))    return (httpReconnect(http));  else if (http->encryption == HTTP_ENCRYPT_REQUIRED && !http->tls)    return (http_upgrade(http));  else    return (0);#else  if (e == HTTP_ENCRYPT_ALWAYS || e == HTTP_ENCRYPT_REQUIRED)    return (-1);  else    return (0);#endif /* HAVE_SSL */}/* * 'httpReconnect()' - Reconnect to a HTTP server... */int				/* O - 0 on success, non-zero on failure */httpReconnect(http_t *http)	/* I - HTTP data */{  int		val;		/* Socket option value */  DEBUG_printf(("httpReconnect(http=%p)\n", http));  if (!http)    return (-1);#ifdef HAVE_SSL  if (http->tls)    http_shutdown_ssl(http);#endif /* HAVE_SSL */ /*  * Close any previously open socket...  */  if (http->fd >= 0)#ifdef WIN32    closesocket(http->fd);#else    close(http->fd);#endif /* WIN32 */ /*  * Create the socket and set options to allow reuse.  */  if ((http->fd = socket(AF_INET, SOCK_STREAM, 0)) < 0)  {#ifdef WIN32    http->error  = WSAGetLastError();#else    http->error  = errno;#endif /* WIN32 */    http->status = HTTP_ERROR;    return (-1);  }#ifdef FD_CLOEXEC  fcntl(http->fd, F_SETFD, FD_CLOEXEC);	/* Close this socket when starting *					 * other processes...              */#endif /* FD_CLOEXEC */  val = 1;  setsockopt(http->fd, SOL_SOCKET, SO_REUSEADDR, (char *)&val, sizeof(val));#ifdef SO_REUSEPORT  val = 1;  setsockopt(http->fd, SOL_SOCKET, SO_REUSEPORT, &val, sizeof(val));#endif /* SO_REUSEPORT */ /*  * Using TCP_NODELAY improves responsiveness, especially on systems  * with a slow loopback interface...  Since we write large buffers  * when sending print files and requests, there shouldn't be any  * performance penalty for this...  */  val = 1;#ifdef WIN32  setsockopt(http->fd, IPPROTO_TCP, TCP_NODELAY, (char *)&val, sizeof(val)); #else  setsockopt(http->fd, IPPROTO_TCP, TCP_NODELAY, &val, sizeof(val)); #endif // WIN32 /*  * Connect to the server...  */  if (connect(http->fd, (struct sockaddr *)&(http->hostaddr),              sizeof(http->hostaddr)) < 0)  {#ifdef WIN32    http->error  = WSAGetLastError();#else    http->error  = errno;#endif /* WIN32 */    http->status = HTTP_ERROR;#ifdef WIN32    closesocket(http->fd);#else    close(http->fd);#endif    http->fd = -1;    return (-1);  }  http->error  = 0;  http->status = HTTP_CONTINUE;#ifdef HAVE_SSL  if (http->encryption == HTTP_ENCRYPT_ALWAYS)  {   /*    * Always do encryption via SSL.    */    if (http_setup_ssl(http) != 0)    {#ifdef WIN32      closesocket(http->fd);#else      close(http->fd);#endif /* WIN32 */      return (-1);    }  }  else if (http->encryption == HTTP_ENCRYPT_REQUIRED)    return (http_upgrade(http));#endif /* HAVE_SSL */  return (0);}/* * 'httpGetSubField()' - Get a sub-field value. */char *					/* O - Value or NULL */httpGetSubField(http_t       *http,	/* I - HTTP data */                http_field_t field,	/* I - Field index */                const char   *name,	/* I - Name of sub-field */		char         *value)	/* O - Value string */{  const char	*fptr;			/* Pointer into field */  char		temp[HTTP_MAX_VALUE],	/* Temporary buffer for name */		*ptr;			/* Pointer into string buffer */  DEBUG_printf(("httpGetSubField(http=%p, field=%d, name=\"%s\", value=%p)\n",                http, field, name, value));  if (http == NULL ||      field < HTTP_FIELD_ACCEPT_LANGUAGE ||      field > HTTP_FIELD_WWW_AUTHENTICATE ||      name == NULL || value == NULL)    return (NULL);  for (fptr = http->fields[field]; *fptr;)

⌨️ 快捷键说明

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