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

📄 http.c

📁 浏览器的源代码,可移植到嵌入式设备.
💻 C
📖 第 1 页 / 共 2 页
字号:
   gint status;   guint watch_id;#ifdef ENABLE_IPV6   struct sockaddr_in6 name;#else   struct sockaddr_in name;#endif   SocketData_t *S;   DilloHost *dh;   socklen_t socket_len = 0;   S = a_Klist_get_data(ValidSocks, GPOINTER_TO_INT(Info->LocalKey));   dh = S->addr_list_iter->data;   if ( (S->SockFD = socket(dh->af, SOCK_STREAM, IPPROTO_TCP)) < 0 ) {      S->Err = errno;      DEBUG_MSG(5, "Http_connect_socket ERROR: %s\n", g_strerror(errno));      return -1;   }   /* set NONBLOCKING and close on exec. */   fcntl(S->SockFD, F_SETFL,         O_NONBLOCK | fcntl(S->SockFD, F_GETFL));   fcntl(S->SockFD, F_SETFD,         FD_CLOEXEC | fcntl(S->SockFD, F_GETFD));   /* Some OSes require this...  */   memset(&name, 0, sizeof(name));   /* Set remaining parms. */   switch (dh->af) {   case AF_INET:   {      struct sockaddr_in *sin = (struct sockaddr_in *)&name;      socket_len = sizeof(struct sockaddr_in);      sin->sin_family = dh->af;      sin->sin_port = S->port ? htons(S->port) : htons(DILLO_URL_HTTP_PORT);      memcpy(&sin->sin_addr, dh->data, dh->alen);      if (a_Web_valid(S->web) && (S->web->flags & WEB_RootUrl))         DEBUG_MSG(5, "Connecting to %s\n", inet_ntoa(sin->sin_addr));      break;   }#ifdef ENABLE_IPV6   case AF_INET6:   {      char buf[128];      struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)&name;      socket_len = sizeof(struct sockaddr_in6);      sin6->sin6_family = dh->af;      sin6->sin6_port = S->port ? htons(S->port) : htons(DILLO_URL_HTTP_PORT);      memcpy(&sin6->sin6_addr, dh->data, dh->alen);      inet_ntop(dh->af, dh->data, buf, sizeof(buf));      if (a_Web_valid(S->web) && (S->web->flags & WEB_RootUrl))         DEBUG_MSG(5, "Connecting to %s\n", buf);      break;   }#endif   }   if (!S->GioCh)      S->GioCh = g_io_channel_unix_new(S->SockFD);   watch_id = g_io_add_watch(S->GioCh, G_IO_ERR | G_IO_HUP | G_IO_OUT,                             Http_use_socket, Info->LocalKey);   status = connect(S->SockFD, (struct sockaddr *)&name, socket_len);   if ( status == -1 && errno != EINPROGRESS ) {      DEBUG_MSG(5, "Http_connect_socket ERROR: %s\n", g_strerror(errno));      g_io_channel_close(S->GioCh);      g_source_remove(watch_id);      S->Err = errno;      return -1;   }   BW_MSG(S->web, 1, "Contacting host...");   return 0; /* Success */}/* * Create and submit the HTTP query to the IO engine */static void Http_send_query(ChainLink *Info, SocketData_t *S){   IOData_t *io;   gchar *query;   void *link;   /* Create the query */   query = a_Http_make_query_str(S->Url, S->use_proxy);   /* send query */   BW_MSG(S->web, 1, "Sending query to %s...", URL_HOST_(S->Url));   io = a_IO_new(IOWrite, S->SockFD);   a_IO_set_buf(io, query, strlen(query));   io->Flags |= IOFlag_FreeIOBuf;   link = a_Chain_link_new(Info, a_Http_ccc, BCK, a_IO_ccc, 1, 2);   a_Chain_bcb(OpStart, Info, io, NULL);   a_Chain_bcb(OpSend, Info, io, NULL);   /* Tell the cache to start the receiving CCC for the answer */   a_Chain_fcb(OpSend, Info, &S->SockFD, NULL);}/* * Test proxy settings and check the no_proxy domains list * Return value: whether to use proxy or not. */static gint Http_must_use_proxy(const DilloUrl *url){   gint i;   gchar **NoProxyVec = prefs.no_proxy_vec;   if (HTTP_Proxy) {      if (NoProxyVec)         for (i = 0; NoProxyVec[i]; ++i)            if (strstr(URL_AUTHORITY(url), NoProxyVec[i]))               return 0;      return 1;   }   return 0;}/* * Asynchronously create a new http connection for 'Url' * We'll set some socket parameters; the rest will be set later * when the IP is known. * ( Data1 = Requested Url; Data2 = Web structure ) * Return value: 0 on success, -1 otherwise */static gint Http_get(ChainLink *Info, void *Data1, void *Data2){   void *link;   const DilloUrl *Url = Data1;   SocketData_t *S;   gchar *hostname;   S = a_Klist_get_data(ValidSocks, GPOINTER_TO_INT(Info->LocalKey));   /* Reference Info data */   S->Info = Info;   /* Reference Web data */   S->web = Data2;   /* Proxy support */   if (Http_must_use_proxy(Url)) {      hostname = g_strdup(URL_HOST(HTTP_Proxy));      S->port = URL_PORT(HTTP_Proxy);      S->use_proxy = TRUE;   } else {      hostname = g_strdup(URL_HOST(Url));      S->port = URL_PORT(Url);      S->use_proxy = FALSE;   }   /* Set more socket parameters */   S->Url = Url;   /* Let the user know what we'll do */   BW_MSG(S->web, 1, "DNS solving %s", URL_HOST_(S->Url));   /* Let the DNS engine solve the hostname, and when done,    * we'll try to connect the socket */   link = a_Chain_link_new(Info, a_Http_ccc, BCK, a_Dns_ccc, 1, 1);   a_Chain_bcb(OpStart, Info, hostname, NULL);   g_free(hostname);   return 0;}/* * CCC function for the HTTP module */void a_Http_ccc(int Op, int Branch, int Dir, ChainLink *Info,                void *Data1, void *Data2){   gint SKey = GPOINTER_TO_INT(Info->LocalKey);   SocketData_t *S = a_Klist_get_data(ValidSocks, SKey);   a_Chain_debug_msg("a_Http_ccc", Op, Branch, Dir);   if ( Branch == 1 ) {      if (Dir == BCK) {        /* HTTP query branch */         switch (Op) {         case OpStart:            SKey = Http_sock_new();            Info->LocalKey = GINT_TO_POINTER(SKey);            if (Http_get(Info, Data1, Data2) < 0) {               S = a_Klist_get_data(ValidSocks, SKey);               BW_MSG(S->web, 1, "ERROR: %s", g_strerror(S->Err));               Http_socket_free(SKey);               a_Chain_fcb(OpAbort, Info, NULL, NULL);            }            break;         case OpAbort:            /* something bad happened... */            DEBUG_MSG(2, "Http: OpAbort [1B]\n");            Http_socket_free(SKey);            a_Chain_bcb(OpAbort, Info, NULL, NULL);            g_free(Info);            break;         }      } else {  /* FWD */        /* DNS answer branch */         switch (Op) {         case OpSend:            /* Successful DNS answer; save the IP */            if (S) {               S->addr_list = (GSList *)Data1;               S->addr_list_iter = S->addr_list;            }            break;         case OpEnd:            if (S) {               /* Unlink DNS_Info */               a_Chain_del_link(Info, BCK);               /* start connecting the socket */               if (Http_connect_socket(Info) < 0) {                  BW_MSG(S->web, 1, "ERROR: %s", g_strerror(S->Err));                  Http_socket_free(SKey);                  a_Chain_fcb(OpAbort, Info, NULL, NULL);               }            }            break;         case OpAbort:            /* DNS wasn't able to resolve the hostname */            if (S) {               /* Unlink DNS_Info */               a_Chain_del_link(Info, BCK);               BW_MSG(S->web, 0, "ERROR: Dns can't solve %s",                  (S->use_proxy) ? URL_HOST_(HTTP_Proxy) : URL_HOST_(S->Url));               Http_socket_free(SKey);               /* send abort message to higher-level functions */               a_Chain_fcb(OpAbort, Info, NULL, NULL);            }            break;         }      }   } else if ( Branch == 2 ) {      if (Dir == FWD) {         /* IO send-query status branch */         switch (Op) {         case OpStart:            /* LocalKey was set by branch 1 */            break;         case OpSend:            /* Not used */            break;         case OpEnd:            /* finished sending the HTTP query */            if (S) {               a_Chain_del_link(Info, BCK);               a_Chain_fcb(OpEnd, Info, &S->SockFD, (void *)S->Url);               BW_MSG(S->web, 1, "Query sent, waiting for reply...");               Http_socket_free(SKey);            }            break;         case OpAbort:            /* something bad happened... */            /* unlink IO_Info */            if (S) {               a_Chain_del_link(Info, BCK);               Http_socket_free(SKey);               a_Chain_fcb(OpAbort, Info, NULL, NULL);            }            break;         }      }   }}/* * Deallocate memory used by http module * (Call this one at exit time) */void a_Http_freeall(void){   a_Klist_free(&ValidSocks);   a_Url_free(HTTP_Proxy);   g_free(HTTP_Proxy_Auth_base64);}

⌨️ 快捷键说明

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