CConn_SocketStream::CConn_SocketStream(const string& host, unsigned short port, const void* data, size_t size, TSOCK_Flags flags, unsigned short max_try, const STimeout* timeout, size_t buf_size) : CConn_IOStream(TConn_Pair(SOCK_CreateConnectorEx(host.c_str(), port, max_try, data, size, flags), eIO_Unknown), timeout, buf_size) { return; }
static CONNECTOR s_CreateSocketConnector(const SConnNetInfo* net_info, const void* init_data, size_t init_size) { if (*net_info->http_proxy_host) { SOCK sock = 0; EIO_Status status = HTTP_CreateTunnelEx(net_info, fHCC_NoAutoRetry, init_data, init_size, &sock); if (status == eIO_Success) { assert(sock); return SOCK_CreateConnectorOnTop(sock, 1/*pass ownership*/); } assert(!sock); } return SOCK_CreateConnectorEx(net_info->firewall && *net_info->proxy_host ? net_info->proxy_host : net_info->host, net_info->port, 1/*max.try*/, init_data, init_size, net_info->debug_printout == eDebugPrintout_Data ? fSOCK_LogOn : fSOCK_LogDefault); }
static CONNECTOR s_Open(SServiceConnector* uuu, const STimeout* timeout, const SSERV_Info* info, SConnNetInfo* net_info, int/*bool*/ second_try) { int/*bool*/ but_last = 0/*false*/; const char* user_header; /* either "" or non-empty dynamic string */ char* iter_header; EReqMethod req_method; if (info && info->type != fSERV_Firewall) { /* Not a firewall/relay connection here */ assert(!second_try); /* We know the connection point, let's try to use it! */ if (info->type != fSERV_Standalone || !net_info->stateless) { SOCK_ntoa(info->host, net_info->host, sizeof(net_info->host)); net_info->port = info->port; } switch (info->type) { case fSERV_Ncbid: /* Connection directly to NCBID, add NCBID-specific tags */ if (net_info->stateless) { /* Connection request with data */ user_header = "Connection-Mode: STATELESS\r\n"; /*default*/ req_method = eReqMethod_Post; } else { /* We will be waiting for conn-info back */ user_header = "Connection-Mode: STATEFUL\r\n"; req_method = eReqMethod_Get; } user_header = s_AdjustNetParams(uuu->service, net_info, req_method, NCBID_WEBPATH, SERV_NCBID_ARGS(&info->u.ncbid), 0, user_header, info->mime_t, info->mime_s, info->mime_e, 0); break; case fSERV_Http: case fSERV_HttpGet: case fSERV_HttpPost: /* Connection directly to CGI */ req_method = info->type == fSERV_HttpGet ? eReqMethod_Get : (info->type == fSERV_HttpPost ? eReqMethod_Post : eReqMethod_Any); user_header = "Client-Mode: STATELESS_ONLY\r\n"; /*default*/ user_header = s_AdjustNetParams(uuu->service, net_info, req_method, SERV_HTTP_PATH(&info->u.http), SERV_HTTP_ARGS(&info->u.http), 0, user_header, info->mime_t, info->mime_s, info->mime_e, 0); break; case fSERV_Standalone: if (!net_info->stateless) { /* We create SOCKET connector here */ return SOCK_CreateConnectorEx(net_info->host, net_info->port, 1/*max.try*/, 0/*init.data*/, 0/*data.size*/, net_info->debug_printout == eDebugPrintout_Data ? fSOCK_LogOn : fSOCK_LogDefault); } /* Otherwise, it will be a pass-thru connection via dispatcher */ user_header = "Client-Mode: STATELESS_ONLY\r\n"; /*default*/ user_header = s_AdjustNetParams(uuu->service, net_info, eReqMethod_Post, 0, 0, 0, user_header, info->mime_t, info->mime_s, info->mime_e, 0); but_last = 1/*true*/; break; default: user_header = 0; break; } } else { EMIME_Type mime_t; EMIME_SubType mime_s; EMIME_Encoding mime_e; if (net_info->stateless || (info && (info->u.firewall.type & fSERV_Http))) { if (info) { req_method = info->u.firewall.type == fSERV_HttpGet ? eReqMethod_Get : (info->u.firewall.type == fSERV_HttpPost ? eReqMethod_Post : eReqMethod_Any); net_info->stateless = 1/*true*/; } else req_method = eReqMethod_Any; } else req_method = eReqMethod_Get; if (info) { mime_t = info->mime_t; mime_s = info->mime_s; mime_e = info->mime_e; } else { mime_t = eMIME_T_Undefined; mime_s = eMIME_Undefined; mime_e = eENCOD_None; } /* Firewall/relay connection to dispatcher, special tags */ user_header = net_info->stateless ? "Client-Mode: STATELESS_ONLY\r\n" /*default*/ : "Client-Mode: STATEFUL_CAPABLE\r\n"; user_header = s_AdjustNetParams(uuu->service, net_info, req_method, 0, 0, 0, user_header, mime_t, mime_s, mime_e, 0); } if (!user_header) return 0; if ((iter_header = SERV_Print(uuu->iter, net_info, but_last)) != 0) { size_t uh_len; if ((uh_len = strlen(user_header)) > 0) { char* ih; size_t ih_len = strlen(iter_header); if ((ih = (char*) realloc(iter_header, ih_len + uh_len + 1)) != 0){ strcpy(ih + ih_len, user_header); iter_header = ih; } free((char*) user_header); } user_header = iter_header; } else if (!*user_header) user_header = 0; /* special case of assignment of literal "" */ if (uuu->user_header) { ConnNetInfo_DeleteUserHeader(net_info, uuu->user_header); free((void*) uuu->user_header); } uuu->user_header = user_header; if (!ConnNetInfo_OverrideUserHeader(net_info, user_header)) return 0; if (!second_try) { ConnNetInfo_ExtendUserHeader (net_info, "User-Agent: NCBIServiceConnector/" DISP_PROTOCOL_VERSION #ifdef NCBI_CXX_TOOLKIT " (C++ Toolkit)" #else " (C Toolkit)" #endif "\r\n"); } if (!net_info->stateless && (!info || info->type == fSERV_Firewall || info->type == fSERV_Ncbid)) { /* HTTP connector is auxiliary only */ EIO_Status status = eIO_Success; CONNECTOR conn; CONN c; /* Clear connection info */ uuu->host = 0; uuu->port = 0; uuu->ticket = 0; net_info->max_try = 1; conn = HTTP_CreateConnectorEx(net_info, (uuu->params.flags & fHCC_Flushable) | fHCC_SureFlush/*flags*/, s_ParseHeader, 0/*adj.info*/, uuu/*adj.data*/, 0/*cleanup.data*/); /* Wait for connection info back (error-transparent by DISPD.CGI) */ if (conn && (status = CONN_Create(conn, &c)) == eIO_Success) { CONN_SetTimeout(c, eIO_Open, timeout); CONN_SetTimeout(c, eIO_ReadWrite, timeout); CONN_SetTimeout(c, eIO_Close, timeout); CONN_Flush(c); /* This also triggers parse header callback */ CONN_Close(c); } else { const char* error = conn ? IO_StatusStr(status) : 0; CORE_LOGF_X(4, eLOG_Error, ("[%s] Unable to create auxiliary HTTP %s%s%s", uuu->service, conn ? "connection" : "connector", error && *error ? ": " : "", error ? error : "")); assert(0); } if (!uuu->host) return 0/*failed, no connection info returned*/; if (uuu->host == (unsigned int)(-1)) { /* Firewall mode only in stateful mode, fallback requested */ assert((!info || info->type == fSERV_Firewall) && !second_try); /* Try to use stateless mode instead */ net_info->stateless = 1/*true*/; return s_Open(uuu, timeout, info, net_info, 1/*second try*/); } if (net_info->firewall && *net_info->proxy_host) strcpy(net_info->host, net_info->proxy_host); else SOCK_ntoa(uuu->host, net_info->host, sizeof(net_info->host)); net_info->port = uuu->port; /* Build and return target SOCKET connector */ return SOCK_CreateConnectorEx(net_info->host, net_info->port, 1/*max.try*/, &uuu->ticket, sizeof(uuu->ticket), net_info->debug_printout == eDebugPrintout_Data ? fSOCK_LogOn : fSOCK_LogDefault); } return HTTP_CreateConnectorEx(net_info, (uuu->params.flags & fHCC_Flushable) | fHCC_AutoReconnect/*flags*/, s_ParseHeader, s_AdjustNetInfo, uuu/*adj.data*/, 0/*cleanup.data*/); }