Пример #1
0
/* Connect to the HTTP server, specified by uuu->net_info's "port:host".
 * Return eIO_Success only if socket connection has succeeded and uuu->sock
 * is non-zero. If unsuccessful, try to adjust uuu->net_info by s_Adjust(),
 * and then re-try the connection attempt.
 */
static EIO_Status s_Connect(SHttpConnector* uuu,
                            EReadMode       read_mode)
{
    EIO_Status status;

    assert(!uuu->sock);
    if (uuu->can_connect == eCC_None) {
        CORE_LOG_X(5, eLOG_Error, "[HTTP]  Connector no longer usable");
        return eIO_Closed;
    }

    /* the re-try loop... */
    for (;;) {
        int/*bool*/ reset_user_header = 0;
        char*       http_user_header = 0;
        char*       null = 0;
        TSOCK_Flags flags;

        uuu->w_len = BUF_Size(uuu->w_buf);
        if (uuu->net_info->http_user_header)
            http_user_header = strdup(uuu->net_info->http_user_header);
        if (!uuu->net_info->http_user_header == !http_user_header) {
            ConnNetInfo_ExtendUserHeader
                (uuu->net_info, "User-Agent: NCBIHttpConnector"
#ifdef NCBI_CXX_TOOLKIT
                 " (C++ Toolkit)"
#else
                 " (C Toolkit)"
#endif
                 "\r\n");
            reset_user_header = 1;
        }
        if (uuu->net_info->debug_printout)
            ConnNetInfo_Log(uuu->net_info, CORE_GetLOG());
        flags = (uuu->net_info->debug_printout == eDebugPrintout_Data
                 ? fSOCK_LogOn : fSOCK_LogDefault);
        if (uuu->net_info->scheme == eURL_Https)
            flags |= fSOCK_Secure;
        if (!(uuu->flags & fHCC_NoUpread))
            flags |= fSOCK_ReadOnWrite;
        /* connect & send HTTP header */
        if ((status = URL_ConnectEx
             (uuu->net_info->host,       uuu->net_info->port,
              uuu->net_info->path,       uuu->net_info->args,
              uuu->net_info->req_method, uuu->w_len,
              uuu->o_timeout,            uuu->w_timeout,
              uuu->net_info->http_user_header,
              (int/*bool*/)(uuu->flags & fHCC_UrlEncodeArgs),
              flags, &uuu->sock)) != eIO_Success) {
            uuu->sock = 0;
        }
        if (reset_user_header) {
            ConnNetInfo_SetUserHeader(uuu->net_info, 0);
            uuu->net_info->http_user_header = http_user_header;
        }
        if (uuu->sock)
            break/*success*/;

        /* connection failed, no socket was created */
        if (!s_Adjust(uuu, &null, read_mode))
            break/*closed*/;
    }

    return status;
}
Пример #2
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;
}
Пример #3
0
static CConn_IOStream::TConn_Pair
s_SocketConnectorBuilder(const SConnNetInfo* net_info,
                         const STimeout*     timeout,
                         const void*         data,
                         size_t              size,
                         TSOCK_Flags         flags)
{
    EIO_Status status = eIO_Success;
    bool       proxy = false;
    SOCK       sock = 0;

    _ASSERT(net_info);
    if ((flags & (fSOCK_LogOn | fSOCK_LogDefault)) == fSOCK_LogDefault
        &&  net_info->debug_printout == eDebugPrintout_Data) {
        flags &= ~fSOCK_LogDefault;
        flags |=  fSOCK_LogOn;
    }
    if (*net_info->http_proxy_host  &&  net_info->http_proxy_port) {
        status = HTTP_CreateTunnel(net_info, fHTTP_NoAutoRetry, &sock);
        _ASSERT(!sock ^ !(status != eIO_Success));
        if (status == eIO_Success
            &&  ((flags & ~(fSOCK_LogOn | fSOCK_LogDefault))  ||  size)) {
            SOCK s;
            status = SOCK_CreateOnTopEx(sock, 0, &s,
                                        data, size, flags);
            _ASSERT(!s ^ !(status != eIO_Success));
            SOCK_Destroy(sock);
            sock = s;
        }
        proxy = true;
    }
    if (!sock  &&  (!proxy  ||  net_info->http_proxy_leak)) {
        const char* host = (net_info->firewall  &&  *net_info->proxy_host
                            ? net_info->proxy_host : net_info->host);
        if (timeout == kDefaultTimeout)
            timeout  = net_info->timeout;
        if (!proxy  &&  net_info->debug_printout) {
            SConnNetInfo* x_net_info = ConnNetInfo_Clone(net_info);
            if (x_net_info) {
                x_net_info->req_method = eReqMethod_Any;
                x_net_info->stateless = 0;
                x_net_info->lb_disable = 0;
                x_net_info->http_proxy_host[0] = '\0';
                x_net_info->http_proxy_port    =   0;
                x_net_info->http_proxy_user[0] = '\0';
                x_net_info->http_proxy_pass[0] = '\0';
                x_net_info->proxy_host[0]      = '\0';
                ConnNetInfo_SetUserHeader(x_net_info, 0);
                if (x_net_info->http_referer) {
                    free((void*) x_net_info->http_referer);
                    x_net_info->http_referer = 0;
                }
                x_net_info->timeout = timeout;
            }
            ConnNetInfo_Log(x_net_info, eLOG_Note, CORE_GetLOG());
            ConnNetInfo_Destroy(x_net_info);
        }
        status = SOCK_CreateEx(host, net_info->port, timeout, &sock,
                               data, size, flags);
        _ASSERT(!sock ^ !(status != eIO_Success));
    }
    string hostport(net_info->host);
    hostport += ':';
    hostport += NStr::UIntToString(net_info->port);
    CONNECTOR c = SOCK_CreateConnectorOnTopEx(sock,
                                              1/*own*/,
                                              hostport.c_str());
    if (!c) {
        SOCK_Abort(sock);
        SOCK_Close(sock);
        status = eIO_Unknown;
    }
    return CConn_IOStream::TConn_Pair(c, status);
}
Пример #4
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*/;
}