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

📄 http_util.c

📁 网络MPEG4IP流媒体开发源代码
💻 C
字号:
/* * The contents of this file are subject to the Mozilla Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.mozilla.org/MPL/ *  * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. *  * The Original Code is MPEG4IP. *  * The Initial Developer of the Original Code is Cisco Systems Inc. * Portions created by Cisco Systems Inc. are * Copyright (C) Cisco Systems Inc. 2001.  All Rights Reserved. *  * Contributor(s):  *              Bill May        wmay@cisco.com *//* * http_util.c - http utilities. */#include "systems.h"#include <time.h>#include "http_private.h"/* * http_disect_url * Carve URL up into portions that we can use - store them in the * client structure.  url points after http::// * We're looking for m_host (destination name), m_port (destination port) * and m_resource (location of file on m_host - also called path) */static int http_dissect_url (const char *name,			    http_client_t *cptr){  // Assume name points at host name  const char *uptr = name;  const char *nextslash, *nextcolon, *rightbracket;  char *host;  size_t hostlen;  // skip ahead after host  rightbracket = NULL;  if (*uptr == '[') {    rightbracket = strchr(uptr, ']');    if (rightbracket != NULL) {      uptr++;      // literal IPv6 address      if (rightbracket[1] == ':') {	nextcolon = rightbracket + 1;      } else	nextcolon = NULL;      nextslash = strchr(rightbracket, '/');    } else {      return -1;    }  } else {    nextslash = strchr(uptr, '/');    nextcolon = strchr(uptr, ':');  }  cptr->m_port = 80;  if (nextslash != NULL || nextcolon != NULL) {    if (nextcolon != NULL &&	(nextcolon < nextslash || nextslash == NULL)) {      hostlen = nextcolon - uptr;      // have a port number      nextcolon++;      cptr->m_port = 0;      while (isdigit(*nextcolon)) {	cptr->m_port *= 10;	cptr->m_port += *nextcolon - '0';	nextcolon++;      }      if (cptr->m_port == 0 || (*nextcolon != '/' && *nextcolon != '\0')) {	return (-1);      }    } else {      // no port number      hostlen = nextslash - uptr;	    }    if (hostlen == 0) {      return (-1);    }    FREE_CHECK(cptr, m_host);    if (rightbracket != NULL) hostlen--;    host = malloc(hostlen + 1);    if (host == NULL) {      return (-1);    }    memcpy(host, uptr, hostlen);    host[hostlen] = '\0';    cptr->m_host = host;  } else {    if (*uptr == '\0') {      return (EINVAL);    }    FREE_CHECK(cptr, m_host);    host = strdup(uptr);    if (rightbracket != NULL) {       host[strlen(host) - 1] = '\0';    }    cptr->m_host = host;  }    FREE_CHECK(cptr, m_resource);  if (nextslash != NULL) {    cptr->m_resource = strdup(nextslash);  } else {    cptr->m_resource = strdup("/");  }  return (0);}  /* * http_decode_and_connect_url * decode the url, and connect it.  If we were already connected, * disconnect the socket and move forward */int http_decode_and_connect_url (const char *name,				 http_client_t *cptr){  int check_open;  uint16_t port;  const char *old_host;  struct hostent *host;  struct sockaddr_in sockaddr;  int result;    if (strncasecmp(name, "http://", strlen("http://")) != 0) {    return (-1);  }  name += strlen("http://");  check_open = 0;  port = 80;  old_host = NULL;  if (cptr->m_state == HTTP_STATE_CONNECTED) {    check_open = 1;    port = cptr->m_port;    old_host = cptr->m_host;    cptr->m_host = NULL; // don't inadvertantly free it  }  if (http_dissect_url(name, cptr) < 0) {    // If there's an error - nothing's changed    return (-1);  }  if (check_open) {    // See if the existing host matches the new one    int match = 0;    // Compare strings, first    if (strcasecmp(old_host, cptr->m_host) == 0) {      // match      if (port == cptr->m_port) {	match = 1;      }    } else {      // Might be same - resolve new address and compare      host = gethostbyname(cptr->m_host);      if (host == NULL) {#ifdef _WIN32		  return -1;#else	if (h_errno > 0) h_errno = 0 - h_errno;	return (h_errno);#endif      }      if (memcmp(host->h_addr,		 &cptr->m_server_addr,		 sizeof(struct in_addr)) == 0 &&	  (port == cptr->m_port)) {	match = 1;      } else {	cptr->m_server_addr = *(struct in_addr *)host->h_addr;      }    }    free((void *)old_host); // free off the old one we saved    if (match == 0) {      cptr->m_state = HTTP_STATE_CLOSED;      closesocket(cptr->m_server_socket);      cptr->m_server_socket = -1;    } else {      // keep using the same socket...      return 0;    }      } else {    // No existing connection - get the new address.    host = gethostbyname(cptr->m_host);    if (host == NULL) {#ifdef _WIN32		return -1;#else      if (h_errno > 0) h_errno = 0 - h_errno;      return (h_errno);#endif    }    cptr->m_server_addr = *(struct in_addr *)host->h_addr;  }  // Create and connect the socket  cptr->m_server_socket = socket(AF_INET, SOCK_STREAM, 0);  if (cptr->m_server_socket == -1) {    return (-1);  }  sockaddr.sin_family = AF_INET;  sockaddr.sin_port = htons(cptr->m_port);  sockaddr.sin_addr = cptr->m_server_addr;  result = connect(cptr->m_server_socket,		   (struct sockaddr *)&sockaddr,		   sizeof(sockaddr));  if (result == -1) {    return (-1);  }  cptr->m_state = HTTP_STATE_CONNECTED;  return (0);}static const char *user_agent = "Mpeg4ip http library 0.1";/* * http_build_header - create a header string * Will eventually want to expand this if we want to specify * content type, etc. */int http_build_header (char *buffer,		       uint32_t maxlen,		       uint32_t *at,		       http_client_t *cptr,		       const char *method){  int ret;#define SNPRINTF_CHECK(fmt, value) \  ret = snprintf(buffer + *at, maxlen - *at, (fmt), (value)); \  if (ret == -1) { \    return (-1); \  }\  *at += ret;  ret = snprintf(buffer,		 maxlen,		 "%s %s HTTP/1.1\r\nHost: %s\r\n",		 method,		 cptr->m_resource,		 cptr->m_host);  if (ret == -1) return -1;  *at += ret;  SNPRINTF_CHECK("User-Agent: %s\r\n", user_agent);  SNPRINTF_CHECK("%s", "\r\n");#undef SNPRINTF_CHECK  return (ret);}/* * Logging code */static int http_debug_level = LOG_ERR;static error_msg_func_t error_msg_func = NULL;void http_set_loglevel (int loglevel){  http_debug_level = loglevel;}void http_set_error_func (error_msg_func_t func){  error_msg_func = func;}void http_debug (int loglevel, const char *fmt, ...){  va_list ap;  if (loglevel <= http_debug_level) {    va_start(ap, fmt);    if (error_msg_func != NULL) {      (error_msg_func)(loglevel, "libhttp", fmt, ap);    } else { #if _WIN32 && _DEBUG	  char msg[1024];      _vsnprintf(msg, 1024, fmt, ap);      OutputDebugString(msg);      OutputDebugString("\n");#else      struct timeval thistime;      char buffer[80];      time_t secs;      gettimeofday(&thistime, NULL);      // To add date, add %a %b %d to strftime      secs = thistime.tv_sec;      strftime(buffer, sizeof(buffer), "%X", localtime(&secs));      printf("%s.%03ld-libhttp-%d: ",	     buffer, (unsigned long)thistime.tv_usec / 1000, loglevel);      vprintf(fmt, ap);      printf("\n");#endif    }    va_end(ap);  }}

⌨️ 快捷键说明

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