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

📄 http.c

📁 ipp打印机服务器原代码 注意:请将ipp.gz改为ipp.tar.gz 然后使用tar zxvf ipp.tar.gz解压 站长注意
💻 C
📖 第 1 页 / 共 4 页
字号:
  if (strcasecmp(http->fields[HTTP_FIELD_TRANSFER_ENCODING], "chunked") == 0)  {    DEBUG_puts("httpGetLength: chunked request!");    http->data_encoding  = HTTP_ENCODE_CHUNKED;    http->data_remaining = 0;  }  else  {    http->data_encoding = HTTP_ENCODE_LENGTH;   /*    * The following is a hack for HTTP servers that don't send a    * content-length or transfer-encoding field...    *    * If there is no content-length then the connection must close    * after the transfer is complete...    */    if (http->fields[HTTP_FIELD_CONTENT_LENGTH][0] == '\0')      http->data_remaining = 2147483647;    else      http->data_remaining = atoi(http->fields[HTTP_FIELD_CONTENT_LENGTH]);    DEBUG_printf(("httpGetLength: content_length=%d\n", http->data_remaining));  }  return (http->data_remaining);}/* * 'http_field()' - Return the field index for a field name. */static http_field_t		/* O - Field index */http_field(const char *name)	/* I - String name */{  int	i;			/* Looping var */  for (i = 0; i < HTTP_FIELD_MAX; i ++)    if (strcasecmp(name, http_fields[i]) == 0)      return ((http_field_t)i);  return (HTTP_FIELD_UNKNOWN);}/* * 'http_send()' - Send a request with all fields and the trailing blank line. */static int			/* O - 0 on success, non-zero on error */http_send(http_t       *http,	/* I - HTTP data */          http_state_t request,	/* I - Request code */	  const char   *uri)	/* I - URI */{  int		i;		/* Looping var */  char		*ptr,		/* Pointer in buffer */		buf[1024];	/* Encoded URI buffer */  static const char * const codes[] =		{		/* Request code strings */		  NULL,		  "OPTIONS",		  "GET",		  NULL,		  "HEAD",		  "POST",		  NULL,		  NULL,		  "PUT",		  NULL,		  "DELETE",		  "TRACE",		  "CLOSE"		};  static const char hex[] = "0123456789ABCDEF";				/* Hex digits */  DEBUG_printf(("http_send(http=%p, request=HTTP_%s, uri=\"%s\")\n",                http, codes[request], uri));  if (http == NULL || uri == NULL)    return (-1); /*  * Encode the URI as needed...  */  for (ptr = buf; *uri != '\0' && ptr < (buf + sizeof(buf) - 1); uri ++)    if (*uri <= ' ' || *uri >= 127)    {      if (ptr < (buf + sizeof(buf) - 1))        *ptr ++ = '%';      if (ptr < (buf + sizeof(buf) - 1))        *ptr ++ = hex[(*uri >> 4) & 15];      if (ptr < (buf + sizeof(buf) - 1))        *ptr ++ = hex[*uri & 15];    }    else      *ptr ++ = *uri;  *ptr = '\0'; /*  * See if we had an error the last time around; if so, reconnect...  */  if (http->status == HTTP_ERROR || http->status >= HTTP_BAD_REQUEST)    httpReconnect(http); /*  * Send the request header...  */  http->state = request;  if (request == HTTP_POST || request == HTTP_PUT)    http->state ++;  http->status = HTTP_CONTINUE;#ifdef HAVE_SSL  if (http->encryption == HTTP_ENCRYPT_REQUIRED && !http->tls)  {    httpSetField(http, HTTP_FIELD_CONNECTION, "Upgrade");    httpSetField(http, HTTP_FIELD_UPGRADE, "TLS/1.0,SSL/2.0,SSL/3.0");  }#endif /* HAVE_SSL */  if (httpPrintf(http, "%s %s HTTP/1.1\r\n", codes[request], buf) < 1)  {    http->status = HTTP_ERROR;    return (-1);  }  for (i = 0; i < HTTP_FIELD_MAX; i ++)    if (http->fields[i][0] != '\0')    {      DEBUG_printf(("%s: %s\n", http_fields[i], http->fields[i]));      if (httpPrintf(http, "%s: %s\r\n", http_fields[i], http->fields[i]) < 1)      {	http->status = HTTP_ERROR;	return (-1);      }    }  if (httpPrintf(http, "\r\n") < 1)  {    http->status = HTTP_ERROR;    return (-1);  }  httpClearFields(http);  return (0);}/* * 'http_wait()' - Wait for data available on a connection. */static int				/* O - 1 if data is available, 0 otherwise */http_wait(http_t *http,			/* I - HTTP data */          int    msec)			/* I - Milliseconds to wait */{#ifndef WIN32  struct rlimit		limit;          /* Runtime limit */#endif /* !WIN32 */  struct timeval	timeout;	/* Timeout */  int			nfds;		/* Result from select() */  int			set_size;	/* Size of select set */  DEBUG_printf(("http_wait(http=%p, msec=%d)\n", http, msec)); /*  * Check the SSL/TLS buffers for data first...  */#ifdef HAVE_SSL  if (http->tls)  {#  ifdef HAVE_LIBSSL    if (SSL_pending((SSL *)(http->tls)))      return (1);#  elif defined(HAVE_GNUTLS)    if (gnutls_record_check_pending(((http_tls_t *)(http->tls))->session))      return (1);#  elif defined(HAVE_CDSASSL)    size_t bytes;			/* Bytes that are available */    if (!SSLGetBufferedReadSize((SSLContextRef)http->tls, &bytes) && bytes > 0)      return;#  endif /* HAVE_LIBSSL */  }#endif /* HAVE_SSL */ /*  * Then try doing a select() to poll the socket...  */  if (!http->input_set)  {#ifdef WIN32   /*    * Windows has a fixed-size select() structure, different (surprise,    * surprise!) from all UNIX implementations.  Just allocate this    * fixed structure...    */    http->input_set = calloc(1, sizeof(fd_set));#else   /*    * Allocate the select() input set based upon the max number of file    * descriptors available for this process...    */    getrlimit(RLIMIT_NOFILE, &limit);    set_size = (limit.rlim_cur + 31) / 8 + 4;    if (set_size < sizeof(fd_set))      set_size = sizeof(fd_set);    http->input_set = calloc(1, set_size);#endif /* WIN32 */    if (!http->input_set)      return (0);  }  do  {    FD_SET(http->fd, http->input_set);    if (msec >= 0)    {      timeout.tv_sec  = msec / 1000;      timeout.tv_usec = (msec % 1000) * 1000;      nfds = select(http->fd + 1, http->input_set, NULL, NULL, &timeout);    }    else      nfds = select(http->fd + 1, http->input_set, NULL, NULL, NULL);  }#ifdef WIN32  while (nfds < 0 && WSAGetLastError() == WSAEINTR);#else  while (nfds < 0 && errno == EINTR);#endif /* WIN32 */  FD_CLR(http->fd, http->input_set);  return (nfds > 0);}#ifdef HAVE_SSL/* * 'http_upgrade()' - Force upgrade to TLS encryption. */static int			/* O - Status of connection */http_upgrade(http_t *http)	/* I - HTTP data */{  int		ret;		/* Return value */  http_t	myhttp;		/* Local copy of HTTP data */  DEBUG_printf(("http_upgrade(%p)\n", http)); /*  * Copy the HTTP data to a local variable so we can do the OPTIONS  * request without interfering with the existing request data...  */  memcpy(&myhttp, http, sizeof(myhttp)); /*  * Send an OPTIONS request to the server, requiring SSL or TLS  * encryption on the link...  */  httpClearFields(&myhttp);  httpSetField(&myhttp, HTTP_FIELD_CONNECTION, "upgrade");  httpSetField(&myhttp, HTTP_FIELD_UPGRADE, "TLS/1.0, SSL/2.0, SSL/3.0");  if ((ret = httpOptions(&myhttp, "*")) == 0)  {   /*    * Wait for the secure connection...    */    while (httpUpdate(&myhttp) == HTTP_CONTINUE);  }  httpFlush(&myhttp); /*  * Copy the HTTP data back over, if any...  */  http->fd         = myhttp.fd;  http->error      = myhttp.error;  http->activity   = myhttp.activity;  http->status     = myhttp.status;  http->version    = myhttp.version;  http->keep_alive = myhttp.keep_alive;  http->used       = myhttp.used;  if (http->used)    memcpy(http->buffer, myhttp.buffer, http->used);  http->auth_type   = myhttp.auth_type;  http->nonce_count = myhttp.nonce_count;  memcpy(http->nonce, myhttp.nonce, sizeof(http->nonce));  http->tls        = myhttp.tls;  http->encryption = myhttp.encryption; /*  * See if we actually went secure...  */  if (!http->tls)  {   /*    * Server does not support HTTP upgrade...    */    DEBUG_puts("Server does not support HTTP upgrade!");#  ifdef WIN32    closesocket(http->fd);#  else    close(http->fd);#  endif    http->fd = -1;    return (-1);  }  else    return (ret);}/* * 'http_setup_ssl()' - Set up SSL/TLS support on a connection. */static int				/* O - Status of connection */http_setup_ssl(http_t *http)		/* I - HTTP data */{#  ifdef HAVE_LIBSSL  SSL_CTX	*context;	/* Context for encryption */  SSL		*conn;		/* Connection for encryption */#  elif defined(HAVE_GNUTLS)  http_tls_t	*conn;		/* TLS session object */  gnutls_certificate_client_credentials *credentials;				/* TLS credentials */#  elif defined(HAVE_CDSASSL)  SSLContextRef	conn;		/* Context for encryption */  OSStatus	error;		/* Error info */#  endif /* HAVE_LIBSSL */  DEBUG_printf(("http_setup_ssl(http=%p)\n", http));#  ifdef HAVE_LIBSSL  context = SSL_CTX_new(SSLv23_client_method());  conn    = SSL_new(context);  SSL_set_fd(conn, http->fd);  if (SSL_connect(conn) != 1)  {#    ifdef DEBUG    unsigned long	error;	/* Error code */    while ((error = ERR_get_error()) != 0)      printf("http_setup_ssl: %s\n", ERR_error_string(error, NULL));#    endif /* DEBUG */    SSL_CTX_free(context);    SSL_free(conn);#    ifdef WIN32    http->error  = WSAGetLastError();#    else    http->error  = errno;#    endif /* WIN32 */    http->status = HTTP_ERROR;    return (HTTP_ERROR);  }#  elif defined(HAVE_GNUTLS)  conn = (http_tls_t *)malloc(sizeof(http_tls_t));  if (conn == NULL)  {    http->error  = errno;    http->status = HTTP_ERROR;    return (-1);  }  credentials = (gnutls_certificate_client_credentials *)                    malloc(sizeof(gnutls_certificate_client_credentials));  if (credentials == NULL)  {    free(conn);    http->error = errno;    http->status = HTTP_ERROR;    return (-1);  }  gnutls_certificate_allocate_credentials(credentials);  gnutls_init(&(conn->session), GNUTLS_CLIENT);  gnutls_set_default_priority(conn->session);  gnutls_credentials_set(conn->session, GNUTLS_CRD_CERTIFICATE, *credentials);  gnutls_transport_set_ptr(conn->session, http->fd);  if ((gnutls_handshake(conn->session)) != GNUTLS_E_SUCCESS)  {    http->error  = errno;    http->status = HTTP_ERROR;    return (-1);  }  conn->credentials = credentials;#  elif defined(HAVE_CDSASSL)  error = SSLNewContext(false, &conn);  if (!error)    error = SSLSetIOFuncs(conn, CDSAReadFunc, CDSAWriteFunc);  if (!error)    error = SSLSetConnection(conn, (SSLConnectionRef)http->fd);  if (!error)    error = SSLSetAllowsExpiredCerts(conn, true);  if (!error)    error = SSLSetAllowsAnyRoot(conn, true);  if (!error)    error = SSLHandshake(conn);  if (error != 0)  {    http->error  = error;    http->status = HTTP_ERROR;    SSLDisposeContext(conn);    close(http->fd);    return (-1);  }#  endif /* HAVE_CDSASSL */  http->tls = conn;  return (0);}/* * 'http_shutdown_ssl()' - Shut down SSL/TLS on a connection. */static voidhttp_shutdown_ssl(http_t *http)	/* I - HTTP data */{#  ifdef HAVE_LIBSSL  SSL_CTX	*context;	/* Context for encryption */  SSL		*conn;		/* Connection for encryption */  conn    = (SSL *)(http->tls);  context = SSL_get_SSL_CTX(conn);  SSL_shutdown(conn);  SSL_CTX_free(context);  SSL_free(conn);#  elif defined(HAVE_GNUTLS)  http_tls_t      *conn;	/* Encryption session */  gnutls_certificate_client_credentials *credentials;				/* TLS credentials */  conn = (http_tls_t *)(http->tls);  credentials = (gnutls_certificate_client_credentials *)(conn->credentials);  gnutls_bye(conn->session, GNUTLS_SHUT_RDWR);  gnutls_deinit(conn->session);  gnutls_certificate_free_credentials(*credentials);  free(credentials);  free(conn);#  elif defined(HAVE_CDSASSL)  SSLClose((SSLContextRef)http->tls);  SSLDisposeContext((SSLContextRef)http->tls);#  endif /* HAVE_LIBSSL */  http->tls = NULL;}/* * 'http_read_ssl()' - Read from a SSL/TLS connection. */static int				/* O - Bytes read */http_read_ssl(http_t *http,		/* I - HTTP data */	      char   *buf,		/* I - Buffer to store data */	      int    len)		/* I - Length of buffer */{#  if defined(HAVE_LIBSSL)  return (SSL_read((SSL *)(http->tls), buf, len));#  elif defined(HAVE_GNUTLS)  return (gnutls_record_recv(((http_tls_t *)(http->tls))->session, buf, len));#  elif defined(HAVE_CDSASSL)  OSStatus	error;			/* Error info */  size_t	processed;		/* Number of bytes processed */  error = SSLRead((SSLContextRef)http->tls, buf, len, &processed);  if (error == 0)    return (processed);  else  {    http->error = error;    return (-1);  }#  endif /* HAVE_LIBSSL */}/* * 'http_write_ssl()' - Write to a SSL/TLS connection. */static int				/* O - Bytes written */http_write_ssl(http_t     *http,	/* I - HTTP data */	       const char *buf,		/* I - Buffer holding data */	       int        len)		/* I - Length of buffer */{#  if defined(HAVE_LIBSSL)  return (SSL_write((SSL *)(http->tls), buf, len));#  elif defined(HAVE_GNUTLS)  return (gnutls_record_send(((http_tls_t *)(http->tls))->session, buf, len));#  elif defined(HAVE_CDSASSL)  OSStatus	error;			/* Error info */  size_t	processed;		/* Number of bytes processed */  error = SSLWrite((SSLContextRef)http->tls, buf, len, &processed);  if (error == 0)    return (processed);  else  {    http->error = error;    return (-1);  }#  endif /* HAVE_LIBSSL */}#  if defined(HAVE_CDSASSL)/* * 'CDSAReadFunc()' - Read function for CDSA decryption code. */static OSStatus					/* O  - -1 on error, 0 on success */CDSAReadFunc(SSLConnectionRef connection,	/* I  - SSL/TLS connection */             void             *data,		/* I  - Data buffer */	     size_t           *dataLength)	/* IO - Number of bytes */{  ssize_t	bytes;				/* Number of bytes read */  bytes = recv((int)connection, data, *dataLength, 0);  if (bytes >= 0)  {    *dataLength = bytes;    return (0);  }  else    return (-1);}/* * 'CDSAWriteFunc()' - Write function for CDSA encryption code. */static OSStatus					/* O  - -1 on error, 0 on success */CDSAWriteFunc(SSLConnectionRef connection,	/* I  - SSL/TLS connection */              const void       *data,		/* I  - Data buffer */	      size_t           *dataLength)	/* IO - Number of bytes */{  ssize_t bytes;  bytes = write((int)connection, data, *dataLength);  if (bytes >= 0)  {    *dataLength = bytes;    return (0);  }  else    return (-1);}#  endif /* HAVE_CDSASSL */#endif /* HAVE_SSL *//* * End of "$Id: http.c,v 1.144 2005/01/03 19:29:45 mike Exp $". */

⌨️ 快捷键说明

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