📄 http.c
字号:
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 + -