📄 ncbi_service_connector.c
字号:
user_header = "Connection-Mode: STATELESS\r\n"; /*default*/ user_header = s_AdjustNetParams(net_info, eReqMethod_Post, NCBID_WEBPATH, uuu->service, uuu->args, SERV_NCBID_ARGS(&info->u.ncbid), user_header, info->mime_t, info->mime_s, info->mime_e, iter_header); break; case fSERV_Http: case fSERV_HttpGet: case fSERV_HttpPost: user_header = "Client-Mode: STATELESS_ONLY\r\n"; /*default*/ user_header = s_AdjustNetParams(net_info, info->type == fSERV_HttpGet ? eReqMethod_Get : (info->type == fSERV_HttpPost ? eReqMethod_Post : eReqMethod_Any), SERV_HTTP_PATH(&info->u.http), 0, 0, SERV_HTTP_ARGS(&info->u.http), user_header, info->mime_t, info->mime_s, info->mime_e, iter_header); break; case fSERV_Standalone: case fSERV_Firewall: user_header = "Client-Mode: STATELESS_ONLY\r\n"; /*default*/ user_header = s_AdjustNetParams(net_info, eReqMethod_Post, uuu->net_info->path, uuu->service, uuu->args, uuu->net_info->args, user_header, info->mime_t, info->mime_s, info->mime_e, iter_header); break; default: assert(0); if (iter_header) free(iter_header); break; } }} if (!user_header) return 0/*false - not adjusted*/; 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/*false - not adjusted*/; if (info->type == fSERV_Ncbid || (info->type & fSERV_Http) != 0) { SOCK_ntoa(info->host, net_info->host, sizeof(net_info->host)); net_info->port = info->port; } else { strcpy(net_info->host, uuu->net_info->host); net_info->port = uuu->net_info->port; } if (net_info->http_proxy_adjusted) net_info->http_proxy_adjusted = 0/*false*/; return 1/*true - adjusted*/;}static CONNECTOR s_Open(SServiceConnector* uuu, const STimeout* timeout, const SSERV_Info* info, SConnNetInfo* net_info, int/*bool*/ second_try){ const char* user_header = 0; /*may assign "", or be non-empty dynamic str*/ EReqMethod req_method; if (info && info->type != fSERV_Firewall) { /* Not a firewall/relay connection here */ assert(!net_info->firewall && !second_try); /* We know the connection point, let's try to use it! */ 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 wait for conn-info back */ user_header = "Connection-Mode: STATEFUL\r\n"; req_method = eReqMethod_Get; } user_header = s_AdjustNetParams(net_info, req_method, NCBID_WEBPATH, uuu->service, uuu->args, SERV_NCBID_ARGS(&info->u.ncbid), user_header, info->mime_t, info->mime_s, info->mime_e, 0); if (!user_header) return 0; break; case fSERV_Http: case fSERV_HttpGet: case fSERV_HttpPost: /* Connection directly to CGI */ user_header = "Client-Mode: STATELESS_ONLY\r\n"; /*default*/ req_method = info->type == fSERV_HttpGet ? eReqMethod_Get : (info->type == fSERV_HttpPost ? eReqMethod_Post : eReqMethod_Any); user_header = s_AdjustNetParams(net_info, req_method, SERV_HTTP_PATH(&info->u.http), 0, 0, SERV_HTTP_ARGS(&info->u.http), user_header, info->mime_t, info->mime_s, info->mime_e, 0); if (!user_header) return 0; break; case fSERV_Standalone: if (net_info->stateless) { /* This will be a pass-thru connection, socket otherwise */ user_header = "Client-Mode: STATELESS_ONLY\r\n"; /*default*/ user_header = s_AdjustNetParams(net_info, eReqMethod_Post, 0, uuu->service, uuu->args, 0, user_header, info->mime_t, info->mime_s, info->mime_e, 0); if (!user_header) return 0; } break; default: assert(0); return 0; } } 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 = SERV_MIME_TYPE_UNDEFINED; mime_s = SERV_MIME_SUBTYPE_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(net_info, req_method, 0, second_try ? 0 : uuu->service, second_try ? 0 : uuu->args, 0, user_header, mime_t, mime_s, mime_e, 0); if (!user_header) return 0; } if (user_header) { /* We create HTTP connector here */ char* iter_header = SERV_Print(uuu->iter); size_t n; if (iter_header /*NB: <CR><LF>-terminated*/) { if ((n = strlen(user_header)) > 0) { if ((iter_header = (char*) realloc(iter_header, strlen(iter_header) + n + 1)) != 0) strcat(iter_header, user_header); 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 */ 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, 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 && 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 { CORE_LOGF(eLOG_Error, ("[SERVICE] Unable to create aux. %s", conn ? "connection" : "connector")); 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 ? eSCC_DebugPrintout : 0); } net_info->max_try = uuu->net_info->max_try; return HTTP_CreateConnectorEx(net_info, fHCC_AutoReconnect, s_ParseHeader, s_AdjustNetInfo, uuu/*adj.data*/, 0/*cleanup.data*/); } /* 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 ? eSCC_DebugPrintout :0);}static EIO_Status s_Close(CONNECTOR connector, const STimeout* timeout, int/*bool*/ close_dispatcher){ SServiceConnector* uuu = (SServiceConnector*) connector->handle; EIO_Status status = eIO_Success; if (uuu->meta.close) status = uuu->meta.close(uuu->meta.c_close, timeout); if (uuu->name) { free((void*) uuu->name); uuu->name = 0; } if (close_dispatcher) { s_CloseDispatcher(uuu); if (uuu->params.reset) uuu->params.reset(uuu->params.data); } if (uuu->meta.list) { SMetaConnector* meta = connector->meta; METACONN_Remove(meta, uuu->meta.list); uuu->meta.list = 0; s_Reset(meta); } uuu->status = status; return status;}static const char* s_VT_GetType(CONNECTOR connector){ SServiceConnector* uuu = (SServiceConnector*) connector->handle; return uuu->name ? uuu->name : "SERVICE";}static EIO_Status s_VT_Open(CONNECTOR connector, const STimeout* timeout){ SServiceConnector* uuu = (SServiceConnector*) connector->handle; SMetaConnector* meta = connector->meta; EIO_Status status = eIO_Unknown; const SSERV_Info* info; SConnNetInfo* net_info; CONNECTOR conn; assert(!uuu->meta.list && !uuu->name); if (!uuu->iter && !s_OpenDispatcher(uuu)) { uuu->status = status; return status; } for (;;) { if (uuu->net_info->firewall) info = 0; else if (!(info = s_GetNextInfo(uuu))) break; status = eIO_Unknown; if (!(net_info = ConnNetInfo_Clone(uuu->net_info))) break; conn = s_Open(uuu, timeout, info, net_info, 0/*second_try - false*/); ConnNetInfo_Destroy(net_info); if (!conn) { if (uuu->net_info->firewall) break; else continue; } /* Setup the new connector on a temporary meta-connector... */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -