Beispiel #1
0
static CConn_IOStream::TConn_Pair
s_ServiceConnectorBuilder(const char*           service,
                          TSERV_Type            types,
                          const SConnNetInfo*   net_info,
                          const char*           user_header,
                          const SSERVICE_Extra* params,
                          const STimeout*       timeout)
{
    AutoPtr<SConnNetInfo>
        x_net_info(net_info ?
                   ConnNetInfo_Clone(net_info) : ConnNetInfo_Create(service));
    if (!x_net_info.get()) {
        NCBI_THROW(CIO_Exception, eUnknown,
                   "CConn_ServiceStream::CConn_ServiceStream(): "
                   " Out of memory");
    }
    if (user_header  &&  *user_header)
        ConnNetInfo_OverrideUserHeader(x_net_info.get(), user_header);
    x_SetupUserAgent(x_net_info.get());
    if (timeout != kDefaultTimeout)
        x_net_info->timeout = timeout;
    CONNECTOR c = SERVICE_CreateConnectorEx(service,
                                            types,
                                            x_net_info.get(),
                                            params);
    return CConn_IOStream::TConn_Pair(c, eIO_Unknown);
}
Beispiel #2
0
SERV_ITER SERV_OpenSimple(const char* service)
{
    SConnNetInfo* net_info = ConnNetInfo_Create(service);
    SERV_ITER iter = SERV_Open(service, fSERV_Any, 0, net_info);
    ConnNetInfo_Destroy(net_info);
    return iter;
}
Beispiel #3
0
NLM_EXTERN CONN QUERY_OpenServiceQueryEx (
  const char* service,
  const char* parameters,
  Nlm_Uint4   timeoutsec,
  const char* arguments
)
{
  CONN           conn;
  CONNECTOR      connector;
  SConnNetInfo*  net_info;
  size_t         n_written;
  EIO_Status     status;

  /* fill in connection info fields and create the connection */
  net_info = ConnNetInfo_Create (service);
  ASSERT ( net_info );

  /* let the user agent be set with a program name */
  x_SetupUserHeader (net_info,
                     NULL, eMIME_T_Unknown, eMIME_Unknown, eENCOD_None);

  if (timeoutsec == (Nlm_Uint4)(-1L)) {
    net_info->timeout  = kInfiniteTimeout;
  } else if ( timeoutsec ) {
    net_info->tmo.sec  = timeoutsec;
    net_info->tmo.usec = timeoutsec;
    net_info->timeout  = &net_info->tmo;
  }

  ConnNetInfo_PostOverrideArg (net_info, arguments, 0);

  connector = SERVICE_CreateConnectorEx (service, fSERV_Any, net_info, 0);

  ConnNetInfo_Destroy (net_info);

  if (connector == NULL) {
    ErrPostEx (SEV_ERROR, 0, 0, "QUERY_OpenServiceQuery failed in SERVICE_CreateConnectorEx");
    conn = NULL;
  } else if ((status = CONN_Create (connector, &conn)) != eIO_Success) {
    ErrPostEx (SEV_ERROR, 0, 0, "QUERY_OpenServiceQuery failed in CONN_Create:"
               " %s", IO_StatusStr (status));
    ASSERT (conn == NULL);
  } else if (StringDoesHaveText (parameters)) {
    status = CONN_Write (conn, parameters, StringLen (parameters),
                         &n_written, eIO_WritePersist);
    if (status != eIO_Success) {
      ErrPostEx (SEV_ERROR, 0, 0, "QUERY_OpenServiceQuery failed to write service parameters in CONN_Write: %s", IO_StatusStr (status));
      CONN_Close (conn);
      conn = NULL;
    }
  }

  return conn;
}
extern CONNECTOR SERVICE_CreateConnectorEx
(const char*           service,
 TSERV_Type            types,
 const SConnNetInfo*   net_info,
 const SSERVICE_Extra* params)
{
    char*              x_service;
    CONNECTOR          ccc;
    SServiceConnector* xxx;

    if (!service  ||  !*service  ||  !(x_service = SERV_ServiceName(service)))
        return 0;

    ccc = (SConnector*)        malloc(sizeof(SConnector));
    xxx = (SServiceConnector*) calloc(1, sizeof(*xxx) + strlen(service));

    /* initialize connector structures */
    ccc->handle   = xxx;
    ccc->next     = 0;
    ccc->meta     = 0;
    ccc->setup    = s_Setup;
    ccc->destroy  = s_Destroy;

    xxx->types    = types;
    xxx->net_info = (net_info
                     ? ConnNetInfo_Clone(net_info)
                     : ConnNetInfo_Create(service));

    if (!ConnNetInfo_SetupStandardArgs(xxx->net_info, x_service)) {
        free(x_service);
        s_Destroy(ccc);
        return 0;
    }
    strcpy((char*) xxx->service, service);
    free(x_service);

    /* now get ready for first probe dispatching */
    if (types & fSERV_Stateless)
        xxx->net_info->stateless = 1/*true*/;
    if (types & fSERV_Firewall)
        xxx->net_info->firewall = 1/*true*/;
    if (!s_OpenDispatcher(xxx)) {
        s_Destroy(ccc);
        return 0;
    }
    assert(xxx->iter);

    /* finally, store all callback parameters */
    if (params)
        memcpy(&xxx->params, params, sizeof(xxx->params));

    /* done */
    return ccc;
}
Beispiel #5
0
inline
void CRPCClient<TRequest, TReply>::x_Connect(void)
{
    _ASSERT( !m_Service.empty() );
    SConnNetInfo* net_info = ConnNetInfo_Create(m_Service.c_str());
    if (!m_Affinity.empty()) {
        ConnNetInfo_PostOverrideArg(net_info, m_Affinity.c_str(), 0);
    }
    x_SetStream(new CConn_ServiceStream(m_Service, fSERV_Any, net_info, 0,
                                        m_Timeout));
    ConnNetInfo_Destroy(net_info);
}
Beispiel #6
0
EIO_Status CConnTest::DispatcherOkay(string* reason)
{
    SConnNetInfo* net_info = ConnNetInfo_Create(0, m_DebugPrintout);
    ConnNetInfo_SetupStandardArgs(net_info, kTest);

    PreCheck(eDispatcher, 0/*main*/,
             "Checking whether NCBI dispatcher is okay");

    int okay = 0;
    SAuxData* auxdata = new SAuxData(m_Canceled, &okay);
    CConn_HttpStream http(net_info, kEmptyStr/*user_header*/, s_SvcHeader,
                          auxdata, s_Adjust, s_Cleanup, 0/*flags*/, m_Timeout);
    http.SetCanceledCallback(m_Canceled);
    char buf[1024];
    http.read(buf, sizeof(buf));
    CTempString str(buf, (size_t) http.gcount());
    EIO_Status status = ConnStatus
        (okay != 1  ||
         NStr::FindNoCase(str, "NCBI Dispatcher Test Page") == NPOS  ||
         NStr::FindNoCase(str, "Welcome") == NPOS, &http);

    string temp;
    if (status == eIO_Interrupt)
        temp = kCanceled;
    else if (status == eIO_Success)
        temp = "OK";
    else {
        if (status != eIO_Timeout) {
            if (okay) {
                temp = "Make sure there are no stray [CONN]{HOST|PORT|PATH}"
                    " settings in the way in your configuration\n";
            }
            if (okay == 1) {
                temp += "Service response was not recognized; please contact "
                    + HELP_EMAIL + '\n';
            }
        } else
            temp += x_TimeoutMsg();
        if (!(okay & 1)) {
            temp += "Check with your network administrator that your network"
                " neither filters out nor blocks non-standard HTTP headers\n";
        }
    }

    PostCheck(eDispatcher, 0/*main*/, status, temp);

    ConnNetInfo_Destroy(net_info);
    if (reason)
        reason->swap(temp);
    return status;
}
void CBlastHitMatrixCGIApplication::x_GetSeqAnnot(CCgiContext& ctx)
{
        const CNcbiRegistry & reg = ctx.GetConfig();
        string blastURL = reg.Get("NetParams", "BlastURL");
        string url = (string)blastURL + "?CMD=Get&RID=" + m_RID + "&FORMAT_TYPE=ASN.1&FORMAT_OBJECT=Alignment";
        
        SConnNetInfo* net_info = ConnNetInfo_Create(NULL);
        // create HTTP connection
        CConn_HttpStream inHttp(url,net_info);   

        try {
            m_Annot.Reset(new CSeq_annot);
            auto_ptr<CObjectIStream> is
                    (CObjectIStream::Open(eSerial_AsnText, inHttp));
            *is >> *m_Annot;                                    
        }
         catch (CException& e) {
              m_Annot.Reset();              
              NCBI_THROW(CBlastHitMatrixCGIException, eInvalidSeqAnnot, "Exception reading SeqAnnot via url " + url + ", exception message: " + e.GetMsg());              
        }               
}
void
CDBLB_ServiceMapper::GetServersList(const string& service, list<string>* serv_list) const
{
    serv_list->clear();
    SConnNetInfo* net_info = ConnNetInfo_Create(service.c_str());
    SERV_ITER srv_it = SERV_Open(service.c_str(),
                                 fSERV_Standalone | fSERV_IncludeDown,
                                 0, net_info);
    ConnNetInfo_Destroy(net_info);
    const SSERV_Info* sinfo;
    while ((sinfo = SERV_GetNextInfo(srv_it)) != NULL) {
        if (sinfo->time > 0  &&  sinfo->time != NCBI_TIME_INFINITE) {
            string server_name(CSocketAPI::ntoa(sinfo->host));
            if (sinfo->port != 0) {
                server_name.append(1, ':');
                server_name.append(NStr::UIntToString(sinfo->port));
            }
            serv_list->push_back(server_name);
        }
    }
    SERV_Close(srv_it);
}
Beispiel #9
0
extern
NCBI_XCONNECT_EXPORT  // FIXME: To remove once the API is fully official
CConn_IOStream* NcbiOpenURL(const string& url, size_t buf_size)
{
    {
        class CInPlaceConnIniter : protected CConnIniter
        {
        } conn_initer;
    }
    bool svc = x_IsIdentifier(url);

    AutoPtr<SConnNetInfo> net_info = ConnNetInfo_Create(svc ? url.c_str() : 0);

    if (svc)
        return new CConn_ServiceStream(url, fSERV_Any, net_info.get());

    unsigned int   host;
    unsigned short port;
    if (url.size() == CSocketAPI::StringToHostPort(url, &host, &port)  &&  port
        &&  net_info.get()) {
        net_info->req_method = eReqMethod_Connect;
    }

    if (ConnNetInfo_ParseURL(net_info.get(), url.c_str())) {
        _ASSERT(net_info);  // otherwise ConnNetInfo_ParseURL() would fail
        if (net_info->req_method == eReqMethod_Connect) {
            return new CConn_SocketStream(*net_info, 0, 0, fSOCK_LogDefault,
                                          net_info->timeout, buf_size);
        }
        switch (net_info->scheme) {
        case eURL_Https:
        case eURL_Http:
            return new CConn_HttpStream(net_info.get(), kEmptyStr, 0, 0, 0, 0,
                                        fHTTP_AutoReconnect,
                                        kDefaultTimeout, buf_size);
        case eURL_File:
            if (*net_info->host  ||  net_info->port)
                break; /*not supported*/
            _ASSERT(!*net_info->args);
            if (net_info->debug_printout) {
                net_info->req_method = eReqMethod_Any;
                net_info->firewall = 0;
                net_info->stateless = 0;
                net_info->lb_disable = 0;
                net_info->http_proxy_leak = 0;
                net_info->http_proxy_host[0] = '\0';
                net_info->http_proxy_port    =   0;
                net_info->http_proxy_user[0] = '\0';
                net_info->http_proxy_pass[0] = '\0';
                net_info->proxy_host[0]      = '\0';
                net_info->max_try = 0;
                net_info->timeout = kInfiniteTimeout;
                ConnNetInfo_SetUserHeader(net_info.get(), 0);
                if (net_info->http_referer) {
                    free((void*) net_info->http_referer);
                    net_info->http_referer = 0;
                }
                ConnNetInfo_Log(net_info.get(), eLOG_Note, CORE_GetLOG());
            }
            return new CConn_FileStream(net_info->path);
        case eURL_Ftp:
            if (!net_info->user[0]) {
                strcpy(net_info->user, "ftp");
                if (!net_info->pass[0])
                    strcpy(net_info->pass, "-none@");
            }
            return new CConn_FTPDownloadStream(*net_info, 0, 0, 0,
                                               net_info->timeout, buf_size);
        default:
            break;
        }
    }
    return 0;
}
Beispiel #10
0
EIO_Status CConnTest::ServiceOkay(string* reason)
{
    static const char kService[] = "bounce";

    SConnNetInfo* net_info = ConnNetInfo_Create(kService, m_DebugPrintout);
    if (net_info)
        net_info->lb_disable = 1/*no local LB to use even if available*/;

    PreCheck(eStatelessService, 0/*main*/,
             "Checking whether NCBI services operational");

    CConn_ServiceStream svc(kService, fSERV_Stateless, net_info,
                            0/*extra*/, m_Timeout);
    svc.SetCanceledCallback(m_Canceled);

    svc << kTest << NcbiEndl;
    string temp;
    svc >> temp;
    bool responded = temp.size() > 0 ? true : false;
    EIO_Status status = ConnStatus(NStr::Compare(temp, kTest) != 0, &svc);

    if (status == eIO_Interrupt)
        temp = kCanceled;
    else if (status == eIO_Success)
        temp = "OK";
    else {
        char* str = net_info ? SERV_ServiceName(kService) : 0;
        if (str  &&  NStr::CompareNocase(str, kService) == 0) {
            free(str);
            str = 0;
        }
        SERV_ITER iter = SERV_OpenSimple(kService);
        if (!iter  ||  !SERV_GetNextInfo(iter)) {
            // Service not found
            SERV_Close(iter);
            iter = SERV_OpenSimple(kTest);
            if (!iter  ||  !SERV_GetNextInfo(iter)
                ||  NStr::CompareNocase(SERV_MapperName(iter), "DISPD") != 0) {
                // Make sure there will be a mapper error printed
                SERV_Close(iter);
                temp.clear();
                iter = 0;
            } else {
                // kTest service can be located but not kService
                temp = str ? "Substituted service" : "Service";
                temp += " cannot be located";
            }
        } else {
            temp = responded ? "Unrecognized" : "No";
            temp += " response from ";
            temp += str ? "substituted service" : "service";
        }
        if (!temp.empty()) {
            if (str) {
                temp += "; please remove [";
                string upper(kService);
                temp += NStr::ToUpper(upper);
                temp += "]CONN_SERVICE_NAME=\"";
                temp += str;
                temp += "\" from your configuration\n";
            } else if (status != eIO_Timeout  ||  m_Timeout > kTimeout)
                temp += "; please contact " + HELP_EMAIL + '\n';
        }
        if (status != eIO_Timeout) {
            const char* mapper = SERV_MapperName(iter);
            if (!mapper  ||  NStr::CompareNocase(mapper, "DISPD") != 0) {
                temp += "Network dispatcher is not enabled as a service"
                    " locator;  please review your configuration to purge any"
                    " occurrences of [CONN]DISPD_DISABLE off your settings\n";
            }
        } else
            temp += x_TimeoutMsg();
        SERV_Close(iter);
        if (str)
            free(str);
    }

    PostCheck(eStatelessService, 0/*main*/, status, temp);

    ConnNetInfo_Destroy(net_info);
    if (reason)
        reason->swap(temp);
    return status;
}
Beispiel #11
0
EIO_Status CConnTest::GetFWConnections(string* reason)
{
    SConnNetInfo* net_info = ConnNetInfo_Create(0, m_DebugPrintout);
    if (net_info) {
        const char* user_header;
        net_info->req_method = eReqMethod_Post;
        if (net_info->firewall) {
            user_header = "NCBI-RELAY: FALSE";
            m_Firewall = true;
        } else
            user_header = "NCBI-RELAY: TRUE";
        if (net_info->stateless)
            m_Stateless = true;
        ConnNetInfo_OverrideUserHeader(net_info, user_header);
        ConnNetInfo_SetupStandardArgs(net_info, 0/*w/o service*/);
    }

    string temp(m_Firewall ? "FIREWALL" : "RELAY (legacy)");
    temp += " connection mode has been detected for stateful services\n";
    if (m_Firewall) {
        temp += "This mode requires your firewall to be configured in such a"
            " way that it allows outbound connections to the port range ["
            STRINGIFY(CONN_FWD_PORT_MIN) ".." STRINGIFY(CONN_FWD_PORT_MAX)
            "] (inclusive) at the two fixed NCBI addresses, "
            NCBI_FWD_BEMD " and " NCBI_FWD_STVA ".\n"
            "To set that up correctly, please have your network administrator"
            " read the following (if they have not already done so):"
            " " NCBI_FWDOC_URL "\n";
    } else {
        temp += "This is an obsolescent mode that requires keeping a wide port"
            " range [4444..4544] (inclusive) open to let through connections"
            " to the entire NCBI site (130.14.xxx.xxx/165.112.xxx.xxx) -- this"
            " mode was designed for unrestricted networks when firewall port"
            " blocking had not been an issue\n";
    }
    if (m_Firewall) {
        _ASSERT(net_info);
        switch (net_info->firewall) {
        case eFWMode_Adaptive:
            temp += "Also, there are usually a few additional ports such as "
                STRINGIFY(CONN_PORT_SSH) " and " STRINGIFY(CONN_PORT_HTTPS)
                " at " NCBI_FWD_BEMD ", which can be used if connections to"
                " the ports in the range described above, have failed\n";
            break;
        case eFWMode_Firewall:
            temp += "Furthermore, your configuration explicitly forbids to use"
                " any fallback firewall ports that may exist to improve"
                " reliability of connection experience\n";
            break;
        case eFWMode_Fallback:
            temp += "There are usually a few backup connection ports such as "
                STRINGIFY(CONN_PORT_SSH) " and " STRINGIFY(CONN_PORT_HTTPS)
                " at " NCBI_FWD_BEMD ", which can be used as a failover if"
                " connections to the port range above fail.  However, your "
                " configuration explicitly requests that only those fallback"
                " firewall ports (if any exist) are to be used for"
                " connections:  this also implies that no conventional ports"
                " from the default range will be used\n";
            break;
        default:
            temp += "Internal program error, please report!\n";
            _ASSERT(0);
            break;
        }
    } else {
        temp += "This mode may not be reliable if your site has a restraining"
            " firewall imposing a fine-grained control over which hosts and"
            " ports the outbound connections are allowed to use\n";
    }
    if (m_HttpProxy) {
        temp += "Connections to the aforementioned ports will be made via an"
            " HTTP proxy at '";
        temp += net_info->http_proxy_host;
        temp += ':';
        temp += NStr::UIntToString(net_info->http_proxy_port);
        temp += "'";
        if (net_info->http_proxy_leak) {	 
            temp += ".  If that is unsuccessful, a link bypassing the proxy"
                " will then be attempted";
        }
    }
    temp += '\n';

    PreCheck(eFirewallConnPoints, 0/*main*/, temp);

    PreCheck(eFirewallConnPoints, 1/*sub*/,
             "Obtaining current NCBI " +
             string(m_Firewall ? "firewall settings" : "service entries"));

    EIO_Status status = x_GetFirewallConfiguration(net_info);

    if (status == eIO_Interrupt)
        temp = kCanceled;
    else if (status == eIO_Success) {
        if (!m_Fwd.empty()
            ||  (!m_FwdFB.empty()
                 &&  m_Firewall  &&  net_info->firewall == eFWMode_Fallback)) {
            temp = "OK: ";
            if (!m_Fwd.empty()) {
                stable_sort(m_Fwd.begin(),   m_Fwd.end());
                temp += NStr::UInt8ToString(m_Fwd.size());
            }
            size_t down = 0;
            if (!m_FwdFB.empty()) {
                stable_sort(m_FwdFB.begin(), m_FwdFB.end());
                if (!m_Fwd.empty())
                    temp += " + ";
                temp += NStr::UInt8ToString(m_FwdFB.size());
                ITERATE(vector<CConnTest::CFWConnPoint>, cp, m_FwdFB) {
                    if (cp->status != eIO_Success)
                        ++down;
                }
                if (down)
                    temp += " - " + NStr::UInt8ToString(down);
            }
            temp +=
                m_Fwd.size() + m_FwdFB.size() - down == 1 ? " port" : " ports";
        } else {
Beispiel #12
0
EIO_Status CConnTest::HttpOkay(string* reason)
{
    SConnNetInfo* net_info = ConnNetInfo_Create(0, m_DebugPrintout);
    if (net_info) {
        if (net_info->http_proxy_host[0]  &&  net_info->http_proxy_port)
            m_HttpProxy = true;
        // Make sure there are no extras
        ConnNetInfo_SetUserHeader(net_info, 0);
        net_info->args[0] = '\0';
    }

    PreCheck(eHttp, 0/*main*/,
             "Checking whether NCBI is HTTP accessible");

    string host(net_info ? net_info->host : DEF_CONN_HOST);
    string port(net_info  &&  net_info->port
                ? ':' + NStr::UIntToString(net_info->port)
                : kEmptyStr);
    SAuxData* auxdata = new SAuxData(m_Canceled, 0);
    CConn_HttpStream http("/Service/index.html",
                          net_info, kEmptyStr/*user_header*/, s_GoodHeader,
                          auxdata, s_Adjust, s_Cleanup, 0/*flags*/, m_Timeout);
    http.SetCanceledCallback(m_Canceled);
    string temp;
    http >> temp;
    EIO_Status status = ConnStatus(temp.empty(), &http);

    if (status == eIO_Interrupt)
        temp = kCanceled;
    else if (status == eIO_Success)
        temp = "OK";
    else {
        if (status == eIO_Timeout)
            temp = x_TimeoutMsg();
        else
            temp.clear();
        if (NStr::CompareNocase(host, DEF_CONN_HOST) != 0  ||  !port.empty()) {
            int n = 0;
            temp += "Make sure that ";
            if (host != DEF_CONN_HOST) {
                n++;
                temp += "[CONN]HOST=\"";
                temp += host;
                temp += port.empty() ? "\"" : "\" and ";
            }
            if (!port.empty()) {
                n++;
                temp += "[CONN]PORT=\"";
                temp += port.c_str() + 1;
                temp += '"';
            }
            _ASSERT(n);
            temp += n > 1 ? " are" : " is";
            temp += " redefined correctly\n";
        }
        if (m_HttpProxy) {
            temp += "Make sure that the HTTP proxy server \'";
            temp += net_info->http_proxy_host;
            temp += ':';
            temp += NStr::UIntToString(net_info->http_proxy_port);
            temp += "' specified with [CONN]HTTP_PROXY_{HOST|PORT} is correct";
        } else {
            if (net_info->http_proxy_host[0]  ||  net_info->http_proxy_port) {
                temp += "Note that your HTTP proxy seems to have been"
                    " specified only partially, and thus cannot be used: the ";
                if (net_info->http_proxy_port) {
                    temp += "host part is missing (for port :"
                        + NStr::UIntToString(net_info->http_proxy_port);
                } else {
                    temp += "port part is missing (for host \'"
                        + string(net_info->http_proxy_host) + '\'';
                }
                temp += ")\n";
            }
            temp += "If your network access requires the use of an HTTP proxy"
                " server, please contact your network administrator and set"
                " [CONN]HTTP_PROXY_{HOST|PORT} (both must be set) in your"
                " configuration accordingly";
        }
        temp += "; and if your proxy server requires authorization, please"
            " check that appropriate [CONN]HTTP_PROXY_{USER|PASS} have been"
            " set\n";
        if (net_info  &&  (*net_info->user  ||  *net_info->pass)) {
            temp += "Make sure there are no stray [CONN]{USER|PASS} that"
                " appear in your configuration -- NCBI services neither"
                " require nor use them\n";
        }
    }

    PostCheck(eHttp, 0/*main*/, status, temp);

    ConnNetInfo_Destroy(net_info);
    if (reason)
        reason->swap(temp);
    return status;
}
int main(int argc, char* argv[])
{
    char*         user_header = 0;
    CONNECTOR     connector;
    FILE*         data_file;
    SConnNetInfo* net_info;
    STimeout      timeout;
    THTTP_Flags   flags;

    /* Log and data-log streams */
    CORE_SetLOGFormatFlags(fLOG_None          | fLOG_Level   |
                           fLOG_OmitNoteLevel | fLOG_DateTime);
    CORE_SetLOGFILE(stderr, 0/*false*/);

    SOCK_SetupSSL(NcbiSetupTls);

    data_file = fopen("test_ncbi_http_connector.log", "ab");
    assert(data_file);

    /* Tune to the test URL using hard-coded pseudo-registry */
    CORE_SetREG( REG_Create(0, s_REG_Get, 0, 0, 0) );

    /* Connection timeout */
    timeout.sec  = 5;
    timeout.usec = 123456;

    if (argc > 1) {
        /* Generate user header and check graceful failure with
         * bad request status if the header ends up too large. */
        static const char kHttpHeader[] = "My-Header: ";
        size_t n, header_size = (size_t) atoi(argv[1]);
        user_header = (char*) malloc(sizeof(kHttpHeader) + header_size);
        if (user_header) {
            header_size += sizeof(kHttpHeader)-1;
            memcpy(user_header, kHttpHeader, sizeof(kHttpHeader)-1);
            for (n = sizeof(kHttpHeader)-1;  n < header_size;  n++)
                user_header[n] = '.';
            user_header[n] = '\0';
        }
    }

    if (atoi(TEST_PORT) == CONN_PORT_HTTPS) {
        verify((net_info = ConnNetInfo_Create(0)) != 0);
        assert(net_info->port == CONN_PORT_HTTPS);
        net_info->scheme = eURL_Https;
    } else
        net_info = 0;

    /* Run the tests */
    flags = fHTTP_KeepHeader | (fHCC_UrlCodec|fHCC_UrlEncodeArgs)/*obsolete*/;
    connector = HTTP_CreateConnector(net_info, user_header, flags);
    CONN_TestConnector(connector, &timeout, data_file, fTC_SingleBouncePrint);

    flags = 0;
    connector = HTTP_CreateConnector(net_info, user_header, flags);
    CONN_TestConnector(connector, &timeout, data_file, fTC_SingleBounceCheck);

    flags = fHTTP_AutoReconnect;
    connector = HTTP_CreateConnector(net_info, user_header, flags);
    CONN_TestConnector(connector, &timeout, data_file, fTC_Everything);

    flags = fHTTP_AutoReconnect | fHCC_UrlCodec/*obsolete*/;
    connector = HTTP_CreateConnector(net_info, user_header, flags);
    CONN_TestConnector(connector, &timeout, data_file, fTC_Everything);

    ConnNetInfo_Destroy(net_info);

    /* Cleanup and Exit */
    CORE_SetREG(0);
    fclose(data_file);

    if (user_header)
        free(user_header);

    CORE_LOG(eLOG_Note, "TEST completed successfully");
    CORE_SetLOG(0);
    return 0;
}
Beispiel #14
0
EIO_Status CConnTest::GetFWConnections(string* reason)
{
    SConnNetInfo* net_info = ConnNetInfo_Create(0);
    if (net_info) {
        const char* user_header;
        net_info->req_method = eReqMethod_Post;
        if (net_info->firewall) {
            user_header = "NCBI-RELAY: FALSE";
            m_Firewall = true;
        } else
            user_header = "NCBI-RELAY: TRUE";
        if (net_info->stateless)
            m_Stateless = true;
        ConnNetInfo_OverrideUserHeader(net_info, user_header);
        ConnNetInfo_SetupStandardArgs(net_info, 0/*w/o service*/);
    }

    string temp(m_Firewall ? "FIREWALL" : "RELAY (legacy)");
    temp += " connection mode has been detected for stateful services\n";
    if (m_Firewall) {
        temp += "This mode requires your firewall to be configured in such a"
            " way that it allows outbound connections to the port range ["
            STRINGIFY(CONN_FWD_PORT_MIN) ".." STRINGIFY(CONN_FWD_PORT_MAX)
            "] (inclusive) at the two fixed NCBI hosts, 130.14.29.112"
            " and 165.112.7.12\n"
            "To set that up correctly, please have your network administrator"
            " read the following (if they have not already done so):"
            " " NCBI_FW_URL "\n";
    } else {
        temp += "This is an obsolescent mode that requires keeping a wide port"
            " range [4444..4544] (inclusive) open to let through connections"
            " to any NCBI host (130.14.2x.xxx/165.112.xx.xxx) -- this mode was"
            " designed for unrestricted networks when firewall port blocking"
            " was not an issue\n";
    }
    if (m_Firewall) {
        _ASSERT(net_info);
        switch (net_info->firewall) {
        case eFWMode_Adaptive:
            temp += "There are also fallback connection ports such as 22 and"
                " 443 at 130.14.29.112.  They will be used if connections to"
                " the ports in the range described above have failed\n";
            break;
        case eFWMode_Firewall:
            temp += "Also, your configuration explicitly forbids to use any"
                " fallback firewall ports that may exist to improve network"
                " connectivity\n";
            break;
        case eFWMode_Fallback:
            temp += "However, your configuration explicitly requests that only"
                " fallback firewall ports (if any exist) are to be used for"
                " connections: this also implies that no conventional ports"
                " from the range above will be used\n";
            break;
        default:
            temp += "Internal program error, please report!\n";
            _ASSERT(0);
            break;
        }
    } else {
        temp += "This mode may not be reliable if your site has a restrictive"
            " firewall imposing fine-grained control over which hosts and"
            " ports the outbound connections are allowed to use\n";
    }
    if (m_HttpProxy) {
        temp += "Connections to the aforementioned ports will be made via an"
            " HTTP proxy at '";
        temp += net_info->http_proxy_host;
        temp += ':';
        temp += NStr::UIntToString(net_info->http_proxy_port);
        temp += "'";
        if (net_info  &&  net_info->http_proxy_leak) {
            temp += ".  If that is unsuccessful, a link bypassing the proxy"
                " will then be attempted";
        }
        if (m_Firewall  &&  *net_info->proxy_host)
            temp += ". In addition, your";
    }
    if (m_Firewall  &&  *net_info->proxy_host) {
        if (!m_HttpProxy)
            temp += "Your";
        temp += " configuration specifies that instead of connecting directly"
            " to NCBI addresses, a forwarding non-transparent proxy host '";
        temp += net_info->proxy_host;
        temp += "' should be used for all links";
        if (m_HttpProxy)
            temp += " (including those originating from the HTTP proxy)";
    }
    temp += '\n';

    PreCheck(eFirewallConnPoints, 0/*main*/, temp);

    PreCheck(eFirewallConnPoints, 1/*sub*/,
             "Obtaining current NCBI " +
             string(m_Firewall ? "firewall settings" : "service entries"));

    EIO_Status status = x_GetFirewallConfiguration(net_info);

    if (status == eIO_Interrupt)
        temp = kCanceled;
    else if (status == eIO_Success) {
        if (!m_Fwd.empty()
            ||  (!m_FwdFB.empty()
                 &&  m_Firewall  &&  net_info->firewall == eFWMode_Fallback)) {
            temp = "OK: ";
            if (!m_Fwd.empty()) {
                stable_sort(m_Fwd.begin(),   m_Fwd.end());
                temp += NStr::UInt8ToString(m_Fwd.size());
            }
            if (!m_FwdFB.empty()) {
                stable_sort(m_FwdFB.begin(), m_FwdFB.end());
                if (!m_Fwd.empty())
                    temp += " + ";
                temp += NStr::UInt8ToString(m_FwdFB.size());
            }
            temp += m_Fwd.size() + m_FwdFB.size() == 1 ? " port" : " ports";
        } else {
            status = eIO_Unknown;
            temp = "No connection ports found, please contact " + HELP_EMAIL;
        }
    } else if (status == eIO_Timeout) {
        temp = x_TimeoutMsg();
        if (m_Timeout > kTimeout)
            temp += "You may want to contact " + HELP_EMAIL;
    } else
        temp = "Please contact " + HELP_EMAIL;

    PostCheck(eFirewallConnPoints, 1/*sub*/, status, temp);

    ConnNetInfo_Destroy(net_info);

    if (status == eIO_Success) {
        PreCheck(eFirewallConnPoints, 2/*sub*/,
                 "Verifying configuration for consistency");

        bool firewall = true;
        // Check primary ports only
        ITERATE(vector<CConnTest::CFWConnPoint>, cp, m_Fwd) {
            if (cp->port < CONN_FWD_PORT_MIN  ||  CONN_FWD_PORT_MAX < cp->port)
                firewall = false;
            if (cp->status != eIO_Success) {
                status = cp->status;
                temp  = CSocketAPI::HostPortToString(cp->host, cp->port);
                temp += " is not operational, please contact " + HELP_EMAIL;
                break;
            }
        }
        if (status == eIO_Success) {
            if (!m_Firewall  &&  !m_FwdFB.empty()) {
                status = eIO_Unknown;
                temp = "Fallback ports found in non-firewall mode, please"
                    " contact " + HELP_EMAIL;
            } else if (m_Firewall != firewall) {
                status = eIO_Unknown;
                temp  = "Firewall ";
                temp += firewall ? "wrongly" : "not";
                temp += " acknowledged, please contact " + HELP_EMAIL;
            } else
                temp.resize(2);
        }

        PostCheck(eFirewallConnPoints, 2/*sub*/, status, temp);
    }
Beispiel #15
0
EIO_Status CConnTest::ExtraCheckOnFailure(void)
{
    static const STimeout kTimeout   = { 5,      0 };
    static const STimeout kTimeSlice = { 0, 100000 };
    static const struct {
        const char*  host;
        const char* vhost;
    } kTests[] = {
        // 0. NCBI default
        { "",                           0                      }, // NCBI
        // 1. External server(s)
        { "www.google.com",             0                      },
        //    NB: Google's public DNS (also @8.8.8.8), responds at :80 as well
        { "8.8.4.4",                    "www.google.com"       },
        // 2. NCBI servers, explicitly
        { "www.be-md.ncbi.nlm.nih.gov", "www.ncbi.nlm.nih.gov" }, // NCBI main
        { "www.st-va.ncbi.nlm.nih.gov", "www.ncbi.nlm.nih.gov" }, // NCBI colo
        { "130.14.29.110",              "www.ncbi.nlm.nih.gov" }, // NCBI main
        { "165.112.7.20",               "www.ncbi.nlm.nih.gov" }  // NCBI colo
    };

    m_CheckPoint.clear();
    PreCheck(eNone, 0/*main*/, "Failback HTTP access check");

    SConnNetInfo* net_info = ConnNetInfo_Create(0, eDebugPrintout_Data);
    if (!net_info) {
        PostCheck(eNone, 0/*main*/,
                  eIO_Unknown, "Cannot create network info structure");
        return eIO_Unknown;
    }

    net_info->req_method = eReqMethod_Head;
    net_info->timeout    = &kTimeout;
    net_info->max_try    = 0;
    m_Timeout = 0;

    CDeadline deadline(kTimeout.sec, kTimeout.usec * 1000);
    time_t           sec;
    unsigned int nanosec;
    deadline.GetExpirationTime(&sec, &nanosec);
    ::sprintf(net_info->path, "/NcbiTest%08lX%08lX",
              (unsigned long) sec, (unsigned long) nanosec);

    vector< AutoPtr<CConn_HttpStream> > http;
    for (size_t n = 0;  n < sizeof(kTests) / sizeof(kTests[0]);  ++n) {
        char user_header[80];
        _ASSERT(::strlen(kTests[n].host) < sizeof(net_info->host) - 1);
        if (kTests[n].host[0])
            ::strcpy(net_info->host, kTests[n].host);
        if (kTests[n].vhost) {
            _ASSERT(::strlen(kTests[n].vhost) + 6 < sizeof(user_header) - 1);
            ::sprintf(user_header, "Host: %s", kTests[n].vhost);
        } else
            *user_header = '\0';
        SAuxData* auxdata = new SAuxData(m_Canceled, 0);
        http.push_back(new CConn_HttpStream(net_info, user_header, s_AnyHeader,
                                            auxdata, s_Adjust, s_Cleanup));
        http.back()->SetCanceledCallback(m_Canceled);
    }

    EIO_Status status = eIO_Success;
    do {
        if (!http.size())
            break;
        ERASE_ITERATE(vector< AutoPtr<CConn_HttpStream> >, h, http) {
            CONN conn = (*h)->GetCONN();
            if (!conn) {
                VECTOR_ERASE(h, http);
                if (status == eIO_Success)
                    status  = eIO_Unknown;
                continue;
            }
            EIO_Status readst = CONN_Wait(conn, eIO_Read, &kTimeSlice);
            if (readst > eIO_Timeout) {
                if (readst == eIO_Interrupt) {
                    status  = eIO_Interrupt;
                    break;
                }
                if (status < readst  &&  (*h)->GetStatusCode() != 404)
                    status = readst;
                VECTOR_ERASE(h, http);
                continue;
            }
        }
    } while (status != eIO_Interrupt  &&  !deadline.IsExpired());

    if (status == eIO_Success  &&  http.size())
        status  = eIO_Timeout;

    PostCheck(eNone, 0/*main*/, status, kEmptyStr);

    return status;
}
Beispiel #16
0
static CConn_IOStream::TConn_Pair
s_HttpConnectorBuilder(const SConnNetInfo* net_info,
                       const char*         url,
                       const char*         host,
                       unsigned short      port,
                       const char*         path,
                       const char*         args,
                       const char*         user_header,
                       FHTTP_ParseHeader   parse_header,
                       void*               user_data,
                       FHTTP_Adjust        adjust,
                       FHTTP_Cleanup       cleanup,
                       THTTP_Flags         flags,
                       const STimeout*     timeout)
{
    size_t len;
    AutoPtr<SConnNetInfo>
        x_net_info(net_info
                   ? ConnNetInfo_Clone(net_info) : ConnNetInfo_Create(0));
    if (!x_net_info.get()) {
        NCBI_THROW(CIO_Exception, eUnknown,
                   "CConn_HttpStream::CConn_HttpStream():  Out of memory");
    }
    if (url  &&  !ConnNetInfo_ParseURL(x_net_info.get(), url)) {
        NCBI_THROW(CIO_Exception, eInvalidArg,
                   "CConn_HttpStream::CConn_HttpStream():  Bad URL");
    }
    if (host) {
        if ((len = *host ? strlen(host) : 0) >= sizeof(x_net_info->host)) {
            NCBI_THROW(CIO_Exception, eInvalidArg,
                       "CConn_HttpStream::CConn_HttpStream():  Host too long");
        }
        memcpy(x_net_info->host, host, ++len);
    }
    if (port)
        x_net_info->port = port;
    if (path) {
        if ((len = *path ? strlen(path) : 0) >= sizeof(x_net_info->path)) {
            NCBI_THROW(CIO_Exception, eInvalidArg,
                       "CConn_HttpStream::CConn_HttpStream():  Path too long");
        }
        memcpy(x_net_info->path, path, ++len);
    }
    if (args) {
        if ((len = *args ? strlen(args) : 0) >= sizeof(x_net_info->args)) {
            NCBI_THROW(CIO_Exception, eInvalidArg,
                       "CConn_HttpStream::CConn_HttpStream():  Args too long");
        }
        memcpy(x_net_info->args, args, ++len);
    }
    if (user_header  &&  *user_header)
        ConnNetInfo_OverrideUserHeader(x_net_info.get(), user_header);
    x_SetupUserAgent(x_net_info.get());
    if (timeout != kDefaultTimeout)
        x_net_info->timeout = timeout;
    CONNECTOR c = HTTP_CreateConnectorEx(x_net_info.get(),
                                         flags,
                                         parse_header,
                                         user_data,
                                         adjust,
                                         cleanup);
    return CConn_IOStream::TConn_Pair(c, eIO_Unknown);
}
Beispiel #17
0
static void TEST_ConnNetInfo(void)
{
    size_t n;
    char* str;
    char buf[80];
    SConnNetInfo* net_info;

    CORE_LOG(eLOG_Note, "ConnNetInfo test started");

    net_info = ConnNetInfo_Create(0);
    assert(net_info);

    assert(ConnNetInfo_ParseURL(net_info,
                                "ftp://*****:*****@host:8888/ro.t/p@th"
                                "?arg/arg:arg@arg:arg/arg"));
    assert(net_info->scheme                           == eURL_Ftp);
    assert(strcmp(net_info->user, "user")                    == 0);
    assert(strcmp(net_info->pass, "pass")                    == 0);
    assert(strcmp(net_info->host, "host")                    == 0);
    assert(       net_info->port                             == 8888);
    assert(strcmp(net_info->path, "/ro.t/p@th")              == 0);
    assert(strcmp(net_info->args, "arg/arg:arg@arg:arg/arg") == 0);

    assert(ConnNetInfo_ParseURL(net_info, "https://www/path"
                                "?arg:arg@arg#frag"));
    assert(       net_info->scheme            == eURL_Https);
    assert(      *net_info->user                       == 0);
    assert(      *net_info->pass                       == 0);
    assert(strcmp(net_info->host, "www")               == 0);
    assert(       net_info->port                       == 0);
    assert(strcmp(net_info->path, "/path")             == 0);
    assert(strcmp(net_info->args, "arg:arg@arg#frag")  == 0);

    assert(ConnNetInfo_ParseURL(net_info, "/path1?arg1#frag2"));
    assert(strcmp(net_info->args, "arg1#frag2")        == 0);

    assert(ConnNetInfo_ParseURL(net_info, "path0/0"));
    assert(strcmp(net_info->path, "/path0/0")          == 0);
    assert(strcmp(net_info->args, "#frag2")            == 0);

    assert(ConnNetInfo_ParseURL(net_info, "#frag3"));
    assert(strcmp(net_info->path, "/path0/0")          == 0);
    assert(strcmp(net_info->args, "#frag3")            == 0);

    assert(ConnNetInfo_ParseURL(net_info, "path2"));
    assert(strcmp(net_info->path, "/path0/path2")      == 0);
    assert(strcmp(net_info->args, "#frag3")            == 0);

    assert(ConnNetInfo_ParseURL(net_info, "/path3?arg3"));
    assert(strcmp(net_info->path, "/path3")            == 0);
    assert(strcmp(net_info->args, "arg3#frag3")        == 0);

    strcpy(net_info->user, "user");
    strcpy(net_info->pass, "pass");
    str = ConnNetInfo_URL(net_info);
    assert(str);
    assert(strcmp(str, "https://www/path3?arg3#frag3") == 0);
    free(str);

    assert(ConnNetInfo_ParseURL(net_info, "path4/path5?arg4#"));
    assert(strcmp(net_info->user, "user")              == 0);
    assert(strcmp(net_info->pass, "pass")              == 0);
    assert(strcmp(net_info->path, "/path4/path5")      == 0);
    assert(strcmp(net_info->args, "arg4")              == 0);

    assert(ConnNetInfo_ParseURL(net_info, "../path6"));
    assert(strcmp(net_info->path, "/path4/../path6")   == 0);
    assert(strcmp(net_info->args, "")                  == 0);

    ConnNetInfo_SetUserHeader(net_info, "");
    str = UTIL_PrintableString(net_info->http_user_header, 0, buf, 0);
    printf("HTTP User Header after set:\n%s%s%s\n",
           "\"" + !str, str ? buf : "NULL", "\"" + !str);
    assert(!net_info->http_user_header  &&  !str);

    ConnNetInfo_AppendUserHeader(net_info,
                                 "T0: V0\n"
                                 "T1:V1\r\n"
                                 "T2: V2\r\n"
                                 "T3: V3\n"
                                 "T4: V4\n"
                                 "T1: V6");
    str = UTIL_PrintableString(net_info->http_user_header, 0, buf, 0);
    if (str)
        *str = '\0';
    printf("HTTP User Header after append:\n%s%s%s\n",
           "\"" + !str, str ? buf : "NULL", "\"" + !str);
    assert(strcmp(net_info->http_user_header,
                  "T0: V0\n"
                  "T1:V1\r\n"
                  "T2: V2\r\n"
                  "T3: V3\n"
                  "T4: V4\n"
                  "T1: V6\r\n") == 0);

    ConnNetInfo_OverrideUserHeader(net_info,
                                   "T0\r\n"
                                   "T5: V5\n"
                                   "T1:    \t  \r\n"
                                   "T2:V2.1\r\n"
                                   "T3:V3\r\n"
                                   "T4: W4");
    str = UTIL_PrintableString(net_info->http_user_header, 0, buf, 0);
    if (str)
        *str = '\0';
    printf("HTTP User Header after override:\n%s%s%s\n",
           "\"" + !str, str ? buf : "NULL", "\"" + !str);
    assert(strcmp(net_info->http_user_header,
                  "T0: V0\n"
                  "T2:V2.1\r\n"
                  "T3:V3\n"
                  "T4: W4\r\n"
                  "T5: V5\r\n") == 0);

    ConnNetInfo_ExtendUserHeader(net_info,
                                 "T0: V0\n"
                                 "T1:V1\r\n"
                                 "T2:V2\n"
                                 "T3: T3:V3\n"
                                 "T4:\n"
                                 "T5");
    str = UTIL_PrintableString(net_info->http_user_header, 0, buf, 0);
    if (str)
        *str = '\0';
    printf("HTTP User Header after extend:\n%s%s%s\n",
           "\"" + !str, str ? buf : "NULL", "\"" + !str);
    assert(strcmp(net_info->http_user_header,
                  "T0: V0\n"
                  "T2:V2.1 V2\r\n"
                  "T3:V3 T3:V3\n"
                  "T4: W4\r\n"
                  "T5: V5\r\n"
                  "T1:V1\r\n") == 0);

    ConnNetInfo_SetUserHeader(net_info, 0);
    str = UTIL_PrintableString(net_info->http_user_header, 0, buf, 0);
    if (str)
        *str = '\0';
    printf("HTTP User Header after reset:\n%s%s%s\n",
           "\"" + !str, str ? buf : "NULL", "\"" + !str);
    assert(!net_info->http_user_header);

    for (n = 0; n < sizeof(net_info->args); n++)
        net_info->args[n] = "0123456789"[rand() % 10];

    strncpy0(net_info->args, "a=b&b=c&c=d", sizeof(net_info->args) - 1);
    printf("HTTP Arg: \"%s\"\n", net_info->args);

    ConnNetInfo_PrependArg(net_info, "d=e", 0);
    ConnNetInfo_PrependArg(net_info, "e", "f");
    printf("HTTP Arg after prepend: \"%s\"\n", net_info->args);

    ConnNetInfo_AppendArg(net_info, "f=g", 0);
    ConnNetInfo_AppendArg(net_info, "g", "h");
    printf("HTTP Arg after append: \"%s\"\n", net_info->args);

    ConnNetInfo_PreOverrideArg(net_info, "a=z&b", "y");
    ConnNetInfo_PreOverrideArg(net_info, "c", "x");
    printf("HTTP Arg after pre-override: \"%s\"\n", net_info->args);

    ConnNetInfo_PostOverrideArg(net_info, "d=w&e", "v");
    ConnNetInfo_PostOverrideArg(net_info, "f", "u");
    printf("HTTP Arg after post-override: \"%s\"\n", net_info->args);

    ConnNetInfo_DeleteArg(net_info, "g");
    ConnNetInfo_DeleteArg(net_info, "h=n");
    printf("HTTP Arg after delete: \"%s\"\n", net_info->args);

    ConnNetInfo_DeleteAllArgs(net_info, "a=b&p=q&f=d");
    printf("HTTP Arg after delete-all: \"%s\"\n", net_info->args);

    ConnNetInfo_LogEx(net_info, eLOG_Note, CORE_GetLOG());

    ConnNetInfo_Destroy(net_info);

    CORE_LOG(eLOG_Note, "ConnNetInfo test completed");
}
Beispiel #18
0
/* One can define env.var. 'service'_CONN_HOST to reroute dispatching
 * information to particular dispatching host (instead of default).
 */
int main(int argc, const char* argv[])
{
    static const char kParameter[] = "test_parameter";
    const char* service = argc > 1 ? argv[1] : "bounce";
    SConnNetInfo* net_info;
    const SSERV_Info* info;
    const char* value;
    int n_found = 0;
    SERV_ITER iter;

    CORE_SetLOGFormatFlags(fLOG_None          | fLOG_Level   |
                           fLOG_OmitNoteLevel | fLOG_DateTime);
    CORE_SetLOGFILE(stderr, 0/*false*/);
    if (argc > 2) {
        if (strcasecmp(argv[2],"heap") == 0 || strcasecmp(argv[2],"all") == 0){
            HEAP_Options(eOff, eDefault);
            CORE_LOG(eLOG_Note, "Using slow heap access (w/checks)");
        }
        if (strcasecmp(argv[2],"lbsm") == 0 || strcasecmp(argv[2],"all") == 0){
#ifdef NCBI_OS_MSWIN
            if (strcasecmp(argv[2],"lbsm") == 0) {
                CORE_LOG(eLOG_Warning,
                         "Option \"lbsm\" has no useful effect on MS-Windows");
            }
#else
            LBSMD_FastHeapAccess(eOn);
            CORE_LOG(eLOG_Note, "Using live (faster) LBSM heap access");
#endif /*NCBI_OS_MSWIN*/
        }
        if (strcasecmp(argv[2],"lbsm") != 0  &&
            strcasecmp(argv[2],"heap") != 0  &&
            strcasecmp(argv[2],"all")  != 0)
            CORE_LOGF(eLOG_Fatal, ("Unknown option `%s'", argv[2]));
    }

    value = LBSMD_GetHostParameter(SERV_LOCALHOST, kParameter);
    CORE_LOGF(eLOG_Note, ("Querying host parameter `%s': %s%s%s", kParameter,
                          "`" + !value,
                          value ? value : "Not found",
                          "'" + !value));
    if (value)
        free((void*) value);

    CORE_LOGF(eLOG_Note, ("Looking for service `%s'", service));
    net_info = ConnNetInfo_Create(service);
    CORE_LOG(eLOG_Trace, "Opening service mapper");
    iter = SERV_OpenP(service, (fSERV_All & ~fSERV_Firewall) |
                      (strpbrk(service, "?*") ? fSERV_Promiscuous : 0),
                      SERV_LOCALHOST, 0/*port*/, 0.0/*preference*/,
                      net_info, 0/*skip*/, 0/*n_skip*/,
                      0/*external*/, 0/*arg*/, 0/*val*/);
    ConnNetInfo_Destroy(net_info);
    if (iter) {
        HOST_INFO hinfo;
        CORE_LOGF(eLOG_Trace,("%s service mapper has been successfully opened",
                              SERV_MapperName(iter)));
        while ((info = SERV_GetNextInfoEx(iter, &hinfo)) != 0) {
            char* info_str = SERV_WriteInfo(info);
            CORE_LOGF(eLOG_Note, ("Server #%d `%s' = %s", ++n_found,
                                  SERV_CurrentName(iter), info_str));
            if (hinfo) {
                static const char kTimeFormat[] = "%m/%d/%y %H:%M:%S";
                time_t t;
                char buf[80];
                double array[5];
                SHINFO_Params params;
                const char* e = HINFO_Environment(hinfo);
                const char* a = HINFO_AffinityArgument(hinfo);
                const char* v = HINFO_AffinityArgvalue(hinfo);
                CORE_LOG(eLOG_Note, "  Host info available:");
                CORE_LOGF(eLOG_Note, ("    Number of CPUs:      %d",
                                      HINFO_CpuCount(hinfo)));
                CORE_LOGF(eLOG_Note, ("    Number of CPU units: %d @ %.0fMHz",
                                      HINFO_CpuUnits(hinfo),
                                      HINFO_CpuClock(hinfo)));
                CORE_LOGF(eLOG_Note, ("    Number of tasks:     %d",
                                      HINFO_TaskCount(hinfo)));
                if (HINFO_MachineParams(hinfo, &params)) {
                    CORE_LOGF(eLOG_Note, ("    Arch:       %d",
                                          params.arch));
                    CORE_LOGF(eLOG_Note, ("    OSType:     %d",
                                          params.ostype));
                    t = (time_t) params.bootup;
                    strftime(buf, sizeof(buf), kTimeFormat, localtime(&t));
                    CORE_LOGF(eLOG_Note, ("    Kernel:     %hu.%hu.%hu @ %s",
                                          params.kernel.major,
                                          params.kernel.minor,
                                          params.kernel.patch, buf));
                    CORE_LOGF(eLOG_Note, ("    Bits:       %hu",
                                          params.bits));
                    CORE_LOGF(eLOG_Note, ("    Page size:  %lu",
                                          (unsigned long) params.pgsize));
                    t = (time_t) params.start;
                    strftime(buf, sizeof(buf), kTimeFormat, localtime(&t));
                    CORE_LOGF(eLOG_Note, ("    LBSMD:      %hu.%hu.%hu @ %s",
                                          params.daemon.major,
                                          params.daemon.minor,
                                          params.daemon.patch, buf));
                } else
                    CORE_LOG (eLOG_Note,  "    Machine params: unavailable");
                if (HINFO_Memusage(hinfo, array)) {
                    CORE_LOGF(eLOG_Note, ("    Total RAM:  %.2fMB", array[0]));
                    CORE_LOGF(eLOG_Note, ("    Cache RAM:  %.2fMB", array[1]));
                    CORE_LOGF(eLOG_Note, ("    Free  RAM:  %.2fMB", array[2]));
                    CORE_LOGF(eLOG_Note, ("    Total Swap: %.2fMB", array[3]));
                    CORE_LOGF(eLOG_Note, ("    Free  Swap: %.2fMB", array[4]));
                } else
                    CORE_LOG (eLOG_Note,  "    Memory usage: unavailable");
                if (HINFO_LoadAverage(hinfo, array)) {
                    CORE_LOGF(eLOG_Note, ("    Load averages: %f, %f (BLAST)",
                                          array[0], array[1]));
                } else
                    CORE_LOG (eLOG_Note,  "    Load averages: unavailable");
                if (a) {
                    assert(*a);
                    CORE_LOGF(eLOG_Note, ("    Affinity argument: %s", a));
                }
                if (a  &&  v)
                    CORE_LOGF(eLOG_Note, ("    Affinity value:    %s%s%s",
                                          *v ? "" : "\"", v, *v ? "" : "\""));
                CORE_LOGF(eLOG_Note, ("    Host environment: %s%s%s",
                                      e? "\"": "", e? e: "NULL", e? "\"": ""));
                free(hinfo);
            }
            free(info_str);
        }
        CORE_LOG(eLOG_Trace, "Resetting service mapper");
        SERV_Reset(iter);
        CORE_LOG(eLOG_Trace, "Service mapper has been reset");
        if (n_found && !(info = SERV_GetNextInfo(iter)))
            CORE_LOG(eLOG_Fatal, "Service not found after reset");
        CORE_LOG(eLOG_Trace, "Closing service mapper");
        SERV_Close(iter);
    }

    if (n_found != 0)
        CORE_LOGF(eLOG_Note, ("%d server(s) found", n_found));
    else
        CORE_LOG(eLOG_Fatal, "Requested service not found");

#if 0
    {{
        SConnNetInfo* net_info;
        net_info = ConnNetInfo_Create(service);
        iter = SERV_Open(service, fSERV_Http, SERV_LOCALHOST, net_info);
        ConnNetInfo_Destroy(net_info);
    }}

    if (iter != 0) {
        while ((info = SERV_GetNextInfo(iter)) != 0) {
            char* info_str = SERV_WriteInfo(info);
            CORE_LOGF(eLOG_Note, ("Service `%s' = %s", service, info_str));
            free(info_str);
            n_found++;
        }
        SERV_Close(iter);
    }
#endif

    CORE_LOG(eLOG_Note, "TEST completed successfully");
    CORE_SetLOG(0);
    return 0;
}
Beispiel #19
0
const char* DBLB_GetServer(const char*             lb_name,
                           TDBLB_Flags             flags,
                           const SDBLB_Preference* preference,
                           const char* const       skip_servers[],
                           SDBLB_ConnPoint*        conn_point,
                           char*                   server_name_buf,
                           size_t                  server_name_buflen,
                           EDBLB_Status*           result)
{
    static const char kPrefix[] = "DB_IP__";
    size_t          len, n, a_skip, n_skip;
    SConnNetInfo*   net_info;
    int/*bool*/     failed;
    unsigned int    x_host;
    unsigned short  x_port;
    double          x_pref;
    SSERV_InfoCPtr* skip;
    SSERV_Info*     info;
    SDBLB_ConnPoint cp;
    EDBLB_Status    x;
    const char*     c;

    if (!result)
        result = &x;
    if (server_name_buf) {
        assert(server_name_buflen);
        server_name_buf[0] = '\0';
    }
    if (!conn_point)
        conn_point = &cp;
    memset(conn_point, 0, sizeof(*conn_point));
    if (!lb_name  ||  !*lb_name) {
        *result = eDBLB_BadName;
        return 0/*failure*/;
    }
    *result = eDBLB_Success;

    if (strchr(lb_name, '.')) {
        cp.host = SOCK_gethostbyname(lb_name);
        if (cp.host == SOCK_GetLoopbackAddress())
            cp.host = /*FIXME?*/SERV_LOCALHOST;
    } else
        cp.host = 0;

    skip = 0;
    n_skip = 0;
    a_skip = 0;
    net_info = 0;
    failed = 0/*false*/;
    if (skip_servers) {
        for (n = 0;  !failed  &&  skip_servers[n];  n++) {
            const char* server = skip_servers[n];
            SSERV_Info* info;
            if (!(len = strlen(server))) {
                continue;
            }
            if (strncasecmp(server, kPrefix, sizeof(kPrefix)-1) == 0
                &&  isdigit((unsigned char) server[sizeof(kPrefix)-1])) {
                c = strstr(server + sizeof(kPrefix)-1, "__");
                if (c) {
                    size_t i = (size_t)(c - server) - (sizeof(kPrefix)-1);
                    char* temp = strdup(server + sizeof(kPrefix)-1);
                    if (temp) {
                        char* s = temp + i;
                        *s++ = ':';
                        memmove(s, s + 1, strlen(s + 1) + 1);
                        server = temp;
                        while (++temp < s) {
                            if (*temp == '_')
                                *temp =  '.';
                        }
                        len -= sizeof(kPrefix);
                    }
                }
            }
            if (SOCK_StringToHostPort(server, &x_host, &x_port)
                != server + len) {
                int/*bool*/ resolved = 0/*false*/;
                const SSERV_Info* temp;
                SERV_ITER iter;

                if (!net_info)
                    net_info = ConnNetInfo_Create(lb_name);
                iter = SERV_Open(skip_servers[n],
                                 fSERV_Standalone | fSERV_Dns
                                 | fSERV_Promiscuous,
                                 0, net_info);
                do {
                    SSERV_Info* dns;
                    temp = SERV_GetNextInfo(iter);
                    if (temp) {
                        x_host = temp->host;
                        if (x_host  &&  s_IsSkipHost(x_host, cp.host)) {
                            failed = 1/*true*/;
                            break;
                        }
                        x_port = temp->port;
                    } else if (!resolved) {
                        x_host = 0;
                        x_port = 0;
                    } else
                        break;
                    if ((dns = SERV_CreateDnsInfo(x_host)) != 0) {
                        dns->port = x_port;
                        s_AddSkip(&skip, &a_skip, &n_skip, x_host
                                  ? dns
                                  : SERV_CopyInfoEx(dns, skip_servers[n]));
                        if (!x_host)
                            free(dns);
                    }
                    resolved = 1/*true*/;
                } while (temp);
                SERV_Close(iter);
                info = 0;
            } else if (s_IsSkipHost(x_host, cp.host)) {
                failed = 1/*true*/;
                info = 0;
            } else if (server != skip_servers[n]) {
                info = SERV_CreateStandaloneInfo(x_host, x_port);
            } else if ((info = SERV_CreateDnsInfo(x_host)) != 0)
                info->port = x_port;
            if (server != skip_servers[n])
                free((void*) server);
            if (info)
                s_AddSkip(&skip, &a_skip, &n_skip, info);
        }
    }

    if (!failed  &&  !cp.host) {
        if (preference) {
            x_host = preference->host;
            x_port = preference->port;
            if ((x_pref = preference->pref) < 0.0)
                x_pref  =  0.0;
            else if (x_pref >= 100.0)
                x_pref  = -1.0;
        } else {
            x_host = 0;
            x_port = 0;
            x_pref = 0.0;
        }

        if (!net_info)
            net_info = ConnNetInfo_Create(lb_name);
        info = SERV_GetInfoP(lb_name, fSERV_ReverseDns | fSERV_Standalone,
                             x_host, x_port, x_pref, net_info,
                             skip, n_skip, 0/*not external*/,
                             0, 0, 0); /* NCBI_FAKE_WARNING: GCC */
        if (!info  &&  (flags & fDBLB_AllowFallbackToStandby)) {
            /*FIXME: eliminate second pass by fix in ordering in ncbi_lbsmd.c*/
            info = SERV_GetInfoP(lb_name, fSERV_ReverseDns | fSERV_Standalone
                                 | fSERV_IncludeSuppressed,
                                 x_host, x_port, x_pref, net_info,
                                 skip, n_skip, 0/*not external*/,
                                 0, 0, 0); /* NCBI_FAKE_WARNING: GCC */
        }
    } else
        info = 0;

    if (!info) {
        if (!failed) {
            if (!cp.host) {
                if (n_skip  &&  (x_host = SOCK_gethostbyname(lb_name)) != 0) {
                    for (n = 0;  n < n_skip;  n++) {
                        if (x_host == skip[n]->host) {
                            failed = 1/*true*/;
                            break;
                        }
                    }
                }
                if (!failed  &&  skip_servers) {
                    for (n = 0;  (c = skip_servers[n]) != 0;  n++) {
                        if (strcasecmp(c, lb_name) == 0) {
                            failed = 1/*true*/;
                            break;
                        }
                    }
                }
            } else if (conn_point != &cp) {
                conn_point->host = cp.host;
                conn_point->time = NCBI_TIME_INFINITE;
            }
        }
        if (!failed  &&  server_name_buf)
            strncpy0(server_name_buf, lb_name, server_name_buflen - 1);
        *result = eDBLB_NotFound;
    } else {
        if (info->type != fSERV_Dns) {
            char* s, buf[80];
            strncpy0(buf, kPrefix, sizeof(buf) - 1);
            SOCK_HostPortToString(info->host, info->port,
                                  buf + sizeof(kPrefix) - 1,
                                  sizeof(buf) - sizeof(kPrefix));
            len = strlen(buf);
            if ((s = strchr(buf, ':')) != 0)
                memmove(s + 1, s, strlen(s) + 1);
            for (n = 0;  n < len;  n++) {
                if (buf[n] == '.'  ||  buf[n] == ':')
                    buf[n] = '_';
            }
            if (server_name_buf)
                strncpy0(server_name_buf, buf, server_name_buflen - 1);
            *result = eDBLB_NoDNSEntry;
        } else if (info->host) {
            c = SERV_NameOfInfo(info);
            assert(c);
            if (server_name_buf)
                strncpy0(server_name_buf, c, server_name_buflen - 1);
        } else {
            failed = 1/*true*/;
            *result = eDBLB_ServiceDown;
        }
        if (!failed) {
            conn_point->host = info->host;
            conn_point->port = info->port;
            conn_point->time = info->time;
        }
        free(info);
    }

    for (n = 0;  n < n_skip;  n++)
        free((void*) skip[n]);
    if (skip)
        free((void*) skip);

    if (net_info)
        ConnNetInfo_Destroy(net_info);

    return failed ? 0 : (server_name_buf ? server_name_buf : lb_name);
}
Beispiel #20
0
static int run_a_test(size_t test_idx, int live, const char *svc,
                      const char *hdr, int check_for_match, int exp_err,
                      const char *mock_body_in, int repop, int reset)
{
    const SSERV_Info    *info = NULL;
    SConnNetInfo        *net_info;
    SERV_ITER           iter;
    const char          *mock_body = NULL;
    char                *mock_body_adj = NULL;
    int                 n_matches_perfect = 0, n_matches_near = 0;
    int                 success = 0, errors = 0;
    int                 retval = -1;

    s_n_hits_got = 0;

    /* Adjust mock data for current time, if necessary. */
    adjust_mock_times(mock_body_in, &mock_body_adj);
    mock_body = mock_body_adj ? mock_body_adj : mock_body_in;

    /* Select the HTTP data source (live or mock). */
    s_results[test_idx].live = live;
    if ( ! s_results[test_idx].live  &&
        ( ! mock_body  ||  ! *mock_body))
    {
        CORE_TRACE("Mock HTTP data source unavailable.");
        s_results[test_idx].live = 1;
    }
    if (s_results[test_idx].live) {
        CORE_TRACE("Using a live HTTP data source.");
        SERV_NAMERD_SetConnectorSource(NULL); /* use live HTTP */
    } else {
        CORE_TRACE("Using a mock HTTP data source.");
        if ( ! SERV_NAMERD_SetConnectorSource(mock_body)) {
            CORE_LOG(eLOG_Error, "Unable to create mock HTTP data source.");
            retval = 1;
            goto out;
        }
    }

    /* Set up the server iterator. */
    net_info = ConnNetInfo_Create(svc);
    if (*hdr)  ConnNetInfo_SetUserHeader(net_info, hdr);
    iter = SERV_OpenP(svc, fSERV_All |
                      (strpbrk(svc, "?*") ? fSERV_Promiscuous : 0),
                      SERV_LOCALHOST, 0/*port*/, 0.0/*preference*/,
                      net_info, 0/*skip*/, 0/*n_skip*/,
                      0/*external*/, 0/*arg*/, 0/*val*/);
    ConnNetInfo_Destroy(net_info);

    /* Fetch the server hits from namerd. */
    if (iter) {
        for (; s_n_hits_got < MAX_HITS  &&  (info = SERV_GetNextInfo(iter));
             ++s_n_hits_got)
        {
            if (info->type & fSERV_Http) {
                CORE_LOGF(eLOG_Note, ("    HTTP extra (path): %s",
                                      SERV_HTTP_PATH(&info->u.http)));
            }
            strcpy(s_hits_got[s_n_hits_got].type, SERV_TypeStr(info->type));
            strcpy(s_hits_got[s_n_hits_got].xtra,
                (info->type & fSERV_Http) ? SERV_HTTP_PATH(&info->u.http) : "");
            strcpy(s_hits_got[s_n_hits_got].loc ,
                (info->site & fSERV_Local   ) ? "yes" : "no");
            strcpy(s_hits_got[s_n_hits_got].priv,
                (info->site & fSERV_Private ) ? "yes" : "no");
            strcpy(s_hits_got[s_n_hits_got].stfl,
                (info->mode & fSERV_Stateful) ? "yes" : "no");

            SOCK_ntoa(info->host, s_hits_got[s_n_hits_got].host, LEN_HOST);

            s_hits_got[s_n_hits_got].port = info->port;

            s_hits_got[s_n_hits_got].match = 0;

            char    *info_str;
            info_str = SERV_WriteInfo(info);
            CORE_LOGF(eLOG_Note, ("    Found server %d:   %s",
                                  s_n_hits_got, info_str ? info_str : "?"));
            if (info_str)
                free(info_str);
        }

        /* Make sure endpoint data can be repopulated and reset. */
        if (repop  &&  s_n_hits_got) {
            /* repopulate */
            CORE_LOG(eLOG_Trace, "Repopulating the service mapper.");
            if ( ! info  &&  ! SERV_GetNextInfo(iter)) {
                CORE_LOG(eLOG_Error, "Unable to repopulate endpoint data.");
                errors = 1;
            }
        }
        if (reset  &&  s_n_hits_got) {
            /* reset */
            CORE_LOG(eLOG_Trace, "Resetting the service mapper.");
            SERV_Reset(iter);
            if ( ! SERV_GetNextInfo(iter)) {
                CORE_LOG(eLOG_Error, "No services found after reset.");
                errors = 1;
            }
        }

        SERV_Close(iter);
    } else {
        errors = 1;
    }

    /* Search for matches unless this is a standalone run. */
    if (check_for_match) {
        /* Search for perfect matches first (order is unknown). */
        int it_exp, it_got;
        for (it_got=0; it_got < s_n_hits_got; ++it_got) {
            for (it_exp=0; it_exp < s_n_hits_exp; ++it_exp) {
                if (s_hits_exp[it_exp].match) continue;

                /*if (check_match(fMatch_Default, it_exp, it_got)) {*/
                if (check_match(fMatch_All, it_exp, it_got)) {
                    CORE_LOGF(eLOG_Note, (
                        "    Found server %d perfectly matched expected server "
                        "%d.", it_got, it_exp));
                    s_hits_exp[it_exp].match = 1;
                    s_hits_got[it_got].match = 1;
                    ++n_matches_perfect;
                    break;
                }
            }
        }
        /* If not all found, search again but exclude host:port from match. */
        for (it_got=0; it_got < s_n_hits_got; ++it_got) {
            if (s_hits_got[it_got].match) continue;
            for (it_exp=0; it_exp < s_n_hits_exp; ++it_exp) {
                if (s_hits_exp[it_exp].match) continue;

                if (check_match(fMatch_NoHostPort, it_exp, it_got)) {
                    CORE_LOGF(eLOG_Note, (
                       "    Found server %d nearly matched expected server %d.",
                        it_got, it_exp));
                    s_hits_exp[it_exp].match = 1;
                    s_hits_got[it_got].match = 1;
                    ++n_matches_near;
                    log_match_diffs(it_exp, it_got);
                    break;
                }
            }
        }
        /* List any non-matching servers. */
        for (it_exp=0; it_exp < s_n_hits_exp; ++it_exp) {
            if ( ! s_hits_exp[it_exp].match)
                CORE_LOGF(eLOG_Note, (
                    "    Expected server %d didn't match any found servers.",
                    it_exp));
        }
        for (it_got=0; it_got < s_n_hits_got; ++it_got) {
            if ( ! s_hits_got[it_got].match)
                CORE_LOGF(eLOG_Note, (
                    "    Found server %d didn't match any expected servers.",
                    it_got));
        }

        CORE_LOGF(n_matches_perfect + n_matches_near == s_n_hits_got ?
                  eLOG_Note : eLOG_Error,
                  ("Expected %d servers; found %d (%d perfect matches, %d near "
                   "matches, and %d non-matches).",
                  s_n_hits_exp, s_n_hits_got, n_matches_perfect, n_matches_near,
                  s_n_hits_got - n_matches_perfect - n_matches_near));

        if (!errors  &&
            s_n_hits_got == s_n_hits_exp  &&
            s_n_hits_got == n_matches_perfect + n_matches_near)
        {
            success = 1;
        }
        retval = (success != exp_err ? 1 : 0);
        CORE_LOGF(eLOG_Note, ("Test result:  %s.",
            retval ?
            (success ? "PASS" : "PASS (with expected error)") :
            (success ? "FAIL (success when error expected)" : "FAIL")));
    }

out:
    if (mock_body_adj)
        free(mock_body_adj);
    return retval == -1 ? (success != exp_err ? 1 : 0) : retval;
}
Beispiel #21
0
int main(int argc, const char* argv[])
{
    const char* inp_file    = (argc > 5) ? argv[5] : "";
    const char* user_header = (argc > 6) ? argv[6] : "";

    SConnNetInfo* net_info;
    CONNECTOR     connector;
    CONN          conn;
    EIO_Status    status;

    char   buffer[100];
    size_t n_read, n_written;

    /* Prepare to connect:  parse and check cmd.-line args, etc. */
    s_Args.host         = (argc > 1) ? argv[1] : "";
    s_Args.port         = (argc > 2) ? argv[2] : "";
    s_Args.path         = (argc > 3) ? argv[3] : "";
    s_Args.args         = (argc > 4) ? argv[4] : "";

    fprintf(stderr, "Running '%s':\n"
            "  URL host:        '%s'\n"
            "  URL port:        '%s'\n"
            "  URL path:        '%s'\n"
            "  URL args:        '%s'\n"
            "  Input data file: '%s'\n"
            "  User header:     '%s'\n"
            "Reply(if any) from the hit URL goes to the standard output.\n\n",
            argv[0],
            s_Args.host, s_Args.port, s_Args.path, s_Args.args,
            inp_file, user_header);

    /* Log stream */
    CORE_SetLOGFormatFlags(fLOG_None          | fLOG_Level   |
                           fLOG_OmitNoteLevel | fLOG_DateTime);
    CORE_SetLOGFILE(stderr, 0/*false*/);

    /* Tune to the test URL using hard-coded pseudo-registry */
    CORE_SetREG( REG_Create(0, s_REG_Get, 0, 0, 0) );

    SOCK_SetupSSL(NcbiSetupTls);

    /* Usage */
    if (argc < 4) {
        fprintf(stderr,
                "Usage:   %s host port path [args] [inp_file] [user_header]\n"
                "Example: %s www.ncbi.nlm.nih.gov 80 "
                "/Service/bounce.cgi 'arg1+arg2+arg3'\n",
                argv[0], argv[0]);
        CORE_LOG(eLOG_Fatal, "Too few arguments");
        return 1;
    }

    /* Connect */
    if (atoi(s_Args.port) == CONN_PORT_HTTPS) {
        verify((net_info = ConnNetInfo_Create(0)) != 0);
        net_info->scheme = eURL_Https;
    } else
        net_info = 0;

    connector = HTTP_CreateConnector(net_info, user_header, 0);
    assert(connector);
    verify(CONN_Create(connector, &conn) == eIO_Success);

    ConnNetInfo_Destroy(net_info);

    /* If input file specified, then send its content (as HTTP request body) */
    if (*inp_file) {
        FILE* inp_fp;

        if (strcmp(inp_file, "-") != 0) {
            static const char kDevNull[] =
#ifdef NCBI_OS_MSWIN
                "NUL"
#else
                "/dev/null"
#endif /*NCBI_OS_MSWIN*/
                ;
            if (strcmp(inp_file, "+") == 0)
                inp_file = kDevNull;
            if (!(inp_fp = fopen(inp_file, "rb"))) {
                CORE_LOGF(eLOG_Fatal,
                          ("Cannot open file '%s' for reading", inp_file));
            }
        } else
            inp_fp = stdin;

        for (;;) {
            n_read = fread(buffer, 1, sizeof(buffer), inp_fp);
            if (n_read <= 0) {
                assert(feof(inp_fp));
                break; /* EOF */
            }

            status = CONN_Write(conn, buffer, n_read,
                                &n_written, eIO_WritePersist);
            if (status != eIO_Success) {
                CORE_LOGF(eLOG_Fatal,
                          ("Unable to write to URL: %s",IO_StatusStr(status)));
            }
            assert(n_written == n_read);
        }
        fclose(inp_fp);
    }

    /* Read reply from connection, write it to standard output */
    for (;;) {
        status = CONN_Read(conn,buffer,sizeof(buffer),&n_read,eIO_ReadPlain);
        if (status != eIO_Success)
            break;
        if (connector)
            puts("----- [BEGIN] HTTP Content -----");
        fwrite(buffer, 1, n_read, stdout);
        fflush(stdout);
        connector = 0;
    }
    if (!connector) {
        puts("\n----- [END] HTTP Content -----");
        fclose(stdout);
    }

    if (status != eIO_Closed) {
        CORE_LOGF(eLOG_Fatal,
                  ("Unable to read from URL: %s", IO_StatusStr(status)));
    }

    /* Success:  close the connection, cleanup, and exit */
    CONN_Close(conn);
    CORE_SetREG(0);
    CORE_LOG(eLOG_Note, "TEST completed successfully");
    CORE_SetLOG(0);
    return 0;
}
Beispiel #22
0
int main(int argc, const char* argv[])
{
    const char* service = argc > 1 && *argv[1] ? argv[1] : "bounce";
    static char obuf[8192 + 2];
    SConnNetInfo* net_info;
    CONNECTOR connector;
    EIO_Status status;
    char ibuf[1024];
    CONN conn;
    size_t n;

    setlocale(LC_ALL, "");
    g_NCBI_ConnectRandomSeed = (int) time(0) ^ NCBI_CONNECT_SRAND_ADDEND;
    srand(g_NCBI_ConnectRandomSeed);

    CORE_SetLOGFormatFlags(fLOG_None          | fLOG_Level   |
                           fLOG_OmitNoteLevel | fLOG_DateTime);
    CORE_SetLOGFILE(stderr, 0/*false*/);

    net_info = ConnNetInfo_Create(service);
    ConnNetInfo_AppendArg(net_info, "testarg",  "val");
    ConnNetInfo_AppendArg(net_info, "service",  "none");
    ConnNetInfo_AppendArg(net_info, "platform", "none");
    ConnNetInfo_AppendArg(net_info, "address",  "2010");
    ConnNetInfo_Log(net_info, eLOG_Note, CORE_GetLOG());

    connector = SERVICE_CreateConnectorEx(service, fSERV_Any, net_info, 0);

    if (!connector)
        CORE_LOG(eLOG_Fatal, "Failed to create service connector");

    if (CONN_Create(connector, &conn) != eIO_Success)
        CORE_LOG(eLOG_Fatal, "Failed to create connection");

    if (argc > 2) {
        strncpy0(obuf, argv[2], sizeof(obuf) - 2);
        obuf[n = strlen(obuf)] = '\n';
        obuf[++n]              = '\0';
        if (CONN_Write(conn, obuf, strlen(obuf), &n, eIO_WritePersist)
            != eIO_Success) {
            CONN_Close(conn);
            CORE_LOG(eLOG_Fatal, "Cannot write to connection");
        }
        assert(n == strlen(obuf));
    } else {
        for (n = 0; n < 10; n++) {
            size_t m;
            for (m = 0; m < sizeof(obuf) - 2; m++)
                obuf[m] = "0123456789\n"[rand() % 11];
            obuf[m++] = '\n';
            obuf[m]   = '\0';

            if (CONN_Write(conn, obuf, strlen(obuf), &m, eIO_WritePersist)
                != eIO_Success) {
                if (!n) {
                    CONN_Close(conn);
                    CORE_LOG(eLOG_Fatal, "Cannot write to connection");
                } else
                    break;
            }
            assert(m == strlen(obuf));
        }
    }

    for (;;) {
       if (CONN_Wait(conn, eIO_Read, net_info->timeout) != eIO_Success) {
            CONN_Close(conn);
            CORE_LOG(eLOG_Fatal, "Failed to wait for reading");
        }

        status = CONN_Read(conn, ibuf, sizeof(ibuf), &n, eIO_ReadPersist);
        if (n) {
            char* descr = CONN_Description(conn);
            CORE_DATAF(eLOG_Note, ibuf, n,
                       ("%lu bytes read from service (%s%s%s):",
                        (unsigned long) n, CONN_GetType(conn),
                        descr ? ", " : "", descr ? descr : ""));
            if (descr)
                free(descr);
        }
        if (status != eIO_Success) {
            if (status != eIO_Closed)
                CORE_LOGF(n ? eLOG_Error : eLOG_Fatal,
                          ("Read error: %s", IO_StatusStr(status)));
            break;
        }
    }

    ConnNetInfo_Destroy(net_info);
    CONN_Close(conn);

#if 0
    CORE_LOG(eLOG_Note, "Trying ID1 service");

    net_info = ConnNetInfo_Create(service);
    connector = SERVICE_CreateConnectorEx("ID1", fSERV_Any, net_info);
    ConnNetInfo_Destroy(net_info);

    if (!connector)
        CORE_LOG(eLOG_Fatal, "Service ID1 not available");

    if (CONN_Create(connector, &conn) != eIO_Success)
        CORE_LOG(eLOG_Fatal, "Failed to create connection");

    if (CONN_Write(conn, "\xA4\x80\x02\x01\x02\x00", 7, &n, eIO_WritePersist)
        != eIO_Success) {
        CONN_Close(conn);
        CORE_LOG(eLOG_Fatal, "Cannot write to service ID1");
    }
    assert(n == 7);

    if (CONN_Read(conn, ibuf, sizeof(ibuf), &n, eIO_ReadPlain) != eIO_Success){
        CONN_Close(conn);
        CORE_LOG(eLOG_Fatal, "Cannot read from service ID1");
    }

    CORE_LOGF(eLOG_Note, ("%d bytes read from service ID1", n));
    CONN_Close(conn);
#endif

    CORE_LOG(eLOG_Note, "TEST completed successfully");
    CORE_SetLOG(0);
    return 0/*okay*/;
}
static CONNECTOR s_CreateConnector
(const SConnNetInfo*  net_info,
 const char*          user_header,
 THCC_Flags           flags,
 FHttpParseHTTPHeader parse_http_hdr,
 FHttpAdjustNetInfo   adjust_net_info,
 void*                adjust_data,
 FHttpAdjustCleanup   adjust_cleanup)
{
    char            value[32];
    CONNECTOR       ccc;
    SHttpConnector* uuu;
    SConnNetInfo*   xxx;

    xxx = net_info ? ConnNetInfo_Clone(net_info) : ConnNetInfo_Create(0);
    if (!xxx)
        return 0;

    if ((xxx->scheme != eURL_Unspec  && 
         xxx->scheme != eURL_Https   &&
         xxx->scheme != eURL_Http)   ||
        !ConnNetInfo_AdjustForHttpProxy(xxx)) {
        ConnNetInfo_Destroy(xxx);
        return 0;
    }

    if (!(ccc = (SConnector    *) malloc(sizeof(SConnector    )))  ||
        !(uuu = (SHttpConnector*) malloc(sizeof(SHttpConnector)))) {
        if (ccc)
            free(ccc);
        ConnNetInfo_Destroy(xxx);
        return 0;
    }
    if (user_header)
        ConnNetInfo_OverrideUserHeader(xxx, user_header);
    s_AddReferer(xxx);

    ConnNetInfo_GetValue(0, "HTTP_INSECURE_REDIRECT", value, sizeof(value),"");
    if (*value  &&  (strcmp    (value, "1")    == 0  ||
                     strcasecmp(value, "true") == 0  ||
                     strcasecmp(value, "yes")  == 0  ||
                     strcasecmp(value, "on")   == 0)) {
        flags |= fHCC_InsecureRedirect;
    }

    /* initialize internal data structure */
    uuu->net_info         = xxx;

    uuu->parse_http_hdr   = parse_http_hdr;
    uuu->adjust_net_info  = adjust_net_info;
    uuu->adjust_cleanup   = adjust_cleanup;
    uuu->adjust_data      = adjust_data;

    uuu->flags            = flags;
    uuu->reserved         = 0;
    uuu->can_connect      = eCC_Once;         /* will be properly set at open*/

    ConnNetInfo_GetValue(0, "HTTP_ERROR_HEADER_ONLY", value, sizeof(value),"");
    uuu->error_header = (*value  &&  (strcmp    (value, "1")    == 0  ||
                                      strcasecmp(value, "true") == 0  ||
                                      strcasecmp(value, "yes")  == 0  ||
                                      strcasecmp(value, "on")   == 0));

    uuu->sock             = 0;
    uuu->o_timeout        = kDefaultTimeout;  /* deliberately bad values --  */
    uuu->w_timeout        = kDefaultTimeout;  /* must be reset prior to use  */
    uuu->http             = 0;
    uuu->r_buf            = 0;
    uuu->w_buf            = 0;
    /* there are some unintialized fields left -- they are initted later */

    /* initialize connector structure */
    ccc->handle  = uuu;
    ccc->next    = 0;
    ccc->meta    = 0;
    ccc->setup   = s_Setup;
    ccc->destroy = s_Destroy;

    return ccc;
}
Beispiel #24
0
NLM_EXTERN CONN QUERY_OpenUrlQuery (
  const char*     host_machine,
  Nlm_Uint2       host_port,
  const char*     host_path,
  const char*     arguments,
  const char*     appName,
  Nlm_Uint4       timeoutsec,
  EMIME_Type      type,
  EMIME_SubType   subtype,
  EMIME_Encoding  encoding,
  THCC_Flags      flags
)
{
  CONN           conn;
  CONNECTOR      connector;
  SConnNetInfo*  net_info;
  EIO_Status     status;

  if (StringHasNoText (host_path))
    return NULL;

  /* fill in connection info fields and create the connection */
  net_info = ConnNetInfo_Create(0);
  ASSERT ( net_info );

  x_SetupUserHeader (net_info, appName, type, subtype, encoding);

  if (StringDoesHaveText (host_machine)) {
    StringNCpy_0 (net_info->host, host_machine, sizeof (net_info->host));
  }
  if ( host_port ) {
    net_info->port = host_port;
  }
  StringNCpy_0 (net_info->path, host_path, sizeof (net_info->path));
  if (StringDoesHaveText (arguments)) {
    StringNCpy_0 (net_info->args, arguments, sizeof (net_info->args));
  }

  if (timeoutsec == (Nlm_Uint4)(-1L)) {
    net_info->timeout  = kInfiniteTimeout;
  } else if ( timeoutsec ) {
    net_info->tmo.sec  = timeoutsec;
    net_info->tmo.usec = timeoutsec;
    net_info->timeout  = &net_info->tmo;
  }

  connector = HTTP_CreateConnector (net_info, NULL, flags);

  ConnNetInfo_Destroy (net_info);

  if (connector == NULL) {
    ErrPostEx (SEV_ERROR, 0, 0, "QUERY_OpenUrlQuery failed in HTTP_CreateConnector");
    conn = NULL;
  } else if ((status = CONN_Create (connector, &conn)) != eIO_Success) {
    ErrPostEx (SEV_ERROR, 0, 0, "QUERY_OpenUrlQuery failed in CONN_Create: %s",
              IO_StatusStr (status));
    ASSERT (conn == NULL);
  }

  return conn;
}