示例#1
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;
}
示例#2
0
static void s_Resolve(SERV_ITER iter)
{
    struct SDISPD_Data* data = (struct SDISPD_Data*) iter->data;
    SConnNetInfo* net_info = data->net_info;
    EIO_Status status = eIO_Success;
    CONNECTOR c = 0;
    CONN conn;
    char* s;

    assert(!(data->eof | data->fail));
    assert(!!net_info->stateless == !!iter->stateless);
    /* Obtain additional header information */
    if ((!(s = SERV_Print(iter, 0, 0))
         ||  ConnNetInfo_OverrideUserHeader(net_info, s))
        &&
        ConnNetInfo_OverrideUserHeader(net_info,
                                       iter->ok_down  &&  iter->ok_suppressed
                                       ? "Dispatch-Mode: PROMISCUOUS\r\n"
                                       : iter->ok_down
                                       ? "Dispatch-Mode: OK_DOWN\r\n"
                                       : iter->ok_suppressed
                                       ? "Dispatch-Mode: OK_SUPPRESSED\r\n"
                                       : "Dispatch-Mode: INFORMATION_ONLY\r\n")
        &&
        ConnNetInfo_OverrideUserHeader(net_info, iter->reverse_dns
                                       ? "Client-Mode: REVERSE_DNS\r\n"
                                       : !net_info->stateless
                                       ? "Client-Mode: STATEFUL_CAPABLE\r\n"
                                       : "Client-Mode: STATELESS_ONLY\r\n")) {
        c = HTTP_CreateConnectorEx(net_info, fHTTP_Flushable, s_ParseHeader,
                                   iter/*data*/, s_Adjust, 0/*cleanup*/);
    }
    if (s) {
        ConnNetInfo_DeleteUserHeader(net_info, s);
        free(s);
    }
    if (c  &&  (status = CONN_Create(c, &conn)) == eIO_Success) {
        /* Send all the HTTP data... */
        CONN_Flush(conn);
        /* ...then trigger the header callback */
        CONN_Close(conn);
    } else {
        CORE_LOGF_X(5, eLOG_Error,
                    ("%s%s%sUnable to create auxiliary HTTP %s: %s",
                     &"["[!*iter->name], iter->name, *iter->name ? "]  " : "",
                     c              ? "connection" : "connector",
                     IO_StatusStr(c ? status       : eIO_Unknown)));
        if (c  &&  c->destroy)
            c->destroy(c);
        assert(0);
    }
}
示例#3
0
EIO_Status CConn_Streambuf::x_Close(bool close)
{
    if (!m_Conn)
        return close ? eIO_Closed : eIO_Success;
 
    EIO_Status status;
    // flush only if some data pending
    if (pbase() < pptr()) {
        if ((status = CONN_Status(m_Conn, eIO_Write)) != eIO_Success) {
            m_Status = status;
            if (CONN_Status(m_Conn, eIO_Open) == eIO_Success) {
                _TRACE(x_Message("Close():  Cannot finalize implicitly"
                                 ", data loss may result"));
            }
        } else if (sync() != 0)
            status = m_Status != eIO_Success ? m_Status : eIO_Unknown;
    } else
        status = eIO_Success;

    setg(0, 0, 0);
    setp(0, 0);

    CONN c = m_Conn;
    m_Conn = 0;  // NB: no re-entry

    if (close) {
        // here: not called from the close callback x_OnClose
        if (m_CbValid) {
            SCONN_Callback cb;
            CONN_SetCallback(c, eCONN_OnClose, &m_Cb, &cb);
            if ((void*) cb.func != (void*) x_OnClose  ||  cb.data != this)
                CONN_SetCallback(c, eCONN_OnClose, &cb, 0);
        }
        if (m_Close  &&  (m_Status = CONN_Close(c)) != eIO_Success) {
            _TRACE(x_Message("Close():  CONN_Close() failed"));
            if (status == eIO_Success)
                status  = m_Status;
        }
    } else if (m_CbValid  &&  m_Cb.func) {
        EIO_Status cbstat = m_Cb.func(c, eCONN_OnClose, m_Cb.data);
        if (cbstat != eIO_Success)
            status  = cbstat;
    }
    return status;
}
示例#4
0
NLM_EXTERN Nlm_Int4 QUERY_CheckQueue (
  QUEUE* queue
)
{
  static const STimeout kPollTimeout = { 0 };
  Nlm_Int4       count = 0;
  QueuePtr       curr;
  QueuePtr       next;
  QueuePtr PNTR  qptr;
  EIO_Status     status;

  qptr = (QueuePtr PNTR) queue;
  if (qptr == NULL || *qptr == NULL) return 0;

  curr = *qptr;

  while (curr != NULL) {
    next = curr->next;

    if (curr->conn != NULL && (! curr->protect)) {
      status = CONN_Wait (curr->conn, eIO_Read, &kPollTimeout);

      if (status == eIO_Success || status == eIO_Closed) {
        /* protect against reentrant calls if resultproc is GUI and processes timer */
        curr->protect = TRUE;
        if (curr->resultproc != NULL) {
          /* result could eventually be used to reconnect on timeout */
          curr->resultproc (curr->conn, curr->userdata, status);
        }
        if (curr->closeConn) {
          CONN_Close (curr->conn);
        }
        QUERY_RemoveFromQueue (queue, curr->conn);
      } else {
        count++;
      }
    }

    curr = next;
  }

  return count;
}
示例#5
0
NLM_EXTERN void QUERY_CloseQueue (
  QUEUE* queue
)
{
  QueuePtr       curr;
  QueuePtr       next;
  QueuePtr PNTR  qptr;

  qptr = (QueuePtr PNTR) queue;
  if (qptr == NULL || *qptr == NULL) return;

  curr = *qptr;

  while (curr != NULL) {
    next = curr->next;

    if (curr->conn != NULL) {
      CONN_Close (curr->conn);
      QUERY_RemoveFromQueue (queue, curr->conn);
    }

    curr = next;
  }
}
示例#6
0
int main(int argc, const char* argv[])
{
    CONN        conn;
    CONNECTOR   connector;
    EIO_Status  status;
    const char* inp_file;

    /* cmd.-line args */
    if (argc != 2) {
        Usage(argv[0], "Must specify the input file name");
    }
    inp_file = argv[1];

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

    /* run the test */
    fprintf(stderr,
            "Starting the FILE CONNECTOR test...\n"
            "Copy data from file \"%s\" to file \"%s\".\n\n",
            inp_file, OUT_FILE);

    /* create connector, and bind it to the connection */
    connector = FILE_CreateConnector(inp_file, OUT_FILE);
    if ( !connector ) {
        Usage(argv[0], "Failed to create FILE connector");
    }

    verify(CONN_Create(connector, &conn) == eIO_Success);
 
    /* pump the data from one file to another */
    for (;;) {
        char buf[100];
        size_t n_read, n_written;

        /* read */
        status = CONN_Read(conn, buf, sizeof(buf), &n_read, eIO_ReadPlain);
        if (status != eIO_Success) {
            fprintf(stderr, "CONN_Read() failed (status: %s)\n",
                    IO_StatusStr(status));
            break;
        }
        fprintf(stderr, "READ: %ld  bytes\n", (long) n_read);

        /* write */
        status = CONN_Write(conn, buf, n_read, &n_written, eIO_WritePersist);
        if (status != eIO_Success) {
            fprintf(stderr, "CONN_Write() failed (status: %s)\n",
                    IO_StatusStr(status));
            assert(0);
            break;
        }
        assert(n_written == n_read);
    }
    assert(status == eIO_Closed);
    
    /* cleanup, exit */
    verify(CONN_Close(conn) == eIO_Success);
    CORE_LOG(eLOG_Note, "TEST completed successfully");
    CORE_SetLOG(0);
    return 0;
}
示例#7
0
void CONN_TestConnector
(CONNECTOR       connector,
 const STimeout* timeout,
 FILE*           data_file,
 TTestConnFlags  flags)
{
    EIO_Status status;
    SConnector dummy;
    CONN       conn;

    memset(&dummy, 0, sizeof(dummy));

    TEST_LOG(eIO_Success, "[CONN_TestConnector]  Starting...");

    /* Fool around with dummy connector / connection
     */
    assert(CONN_Create(0,      &conn) != eIO_Success  &&  !conn);
    assert(CONN_Create(&dummy, &conn) != eIO_Success  &&  !conn);
    dummy.setup = s_DummySetup;
    assert(CONN_Create(&dummy, &conn) == eIO_Success);
    assert(CONN_Flush (conn)          != eIO_Success);
    assert(CONN_ReInit(conn, 0)       == eIO_Success);
    assert(CONN_ReInit(conn, 0)       != eIO_Success);
    assert(CONN_ReInit(conn, &dummy)  == eIO_Success);
    assert(CONN_Flush (conn)          != eIO_Success);
    assert(CONN_ReInit(conn, &dummy)  == eIO_Success);
    assert(CONN_ReInit(conn, 0)       == eIO_Success);
    assert(CONN_Close (conn)          == eIO_Success);

    /* CREATE new connection on the base of the connector, set
     * TIMEOUTs, try to RECONNECT, WAIT for the connection is writable
     */
    assert(CONN_Create(connector, &conn) == eIO_Success);

    assert(CONN_SetTimeout(conn, eIO_Open,      timeout) == eIO_Success);
    assert(CONN_SetTimeout(conn, eIO_ReadWrite, timeout) == eIO_Success);
    assert(CONN_SetTimeout(conn, eIO_Close,     timeout) == eIO_Success);

    assert(CONN_ReInit(conn, connector) == eIO_Success);

    status = CONN_Wait(conn, eIO_Write, timeout);
    if (status != eIO_Success) {
        TEST_LOG(status, "[CONN_TestConnector]  CONN_Wait(write) failed");
        assert(status == eIO_Timeout);
    }

    /* Run the specified TESTs
     */
    if ( !flags ) {
        flags = fTC_Everything;
    }
    if (flags & fTC_SingleBouncePrint) {
        s_SingleBouncePrint(conn, data_file);
    }
    if (flags & fTC_MultiBouncePrint) {
        s_MultiBouncePrint(conn, data_file);
    }
    if (flags & fTC_SingleBounceCheck) {
        s_SingleBounceCheck(conn, timeout, data_file);
    }

    /* And CLOSE the connection...
     */
    assert(CONN_Close(conn) == eIO_Success);

    TEST_LOG(eIO_Success, "[CONN_TestConnector]  Completed");
}
static CONNECTOR s_Open(SServiceConnector* uuu,
                        const STimeout*    timeout,
                        const SSERV_Info*  info,
                        SConnNetInfo*      net_info,
                        int/*bool*/        second_try)
{
    int/*bool*/ but_last = 0/*false*/;
    const char* user_header; /* either "" or non-empty dynamic string */
    char*       iter_header;
    EReqMethod  req_method;

    if (info  &&  info->type != fSERV_Firewall) {
        /* Not a firewall/relay connection here */
        assert(!second_try);
        /* We know the connection point, let's try to use it! */
        if (info->type != fSERV_Standalone  ||  !net_info->stateless) {
            SOCK_ntoa(info->host, net_info->host, sizeof(net_info->host));
            net_info->port = info->port;
        }

        switch (info->type) {
        case fSERV_Ncbid:
            /* Connection directly to NCBID, add NCBID-specific tags */
            if (net_info->stateless) {
                /* Connection request with data */
                user_header = "Connection-Mode: STATELESS\r\n"; /*default*/
                req_method  = eReqMethod_Post;
            } else {
                /* We will be waiting for conn-info back */
                user_header = "Connection-Mode: STATEFUL\r\n";
                req_method  = eReqMethod_Get;
            }
            user_header = s_AdjustNetParams(uuu->service, net_info, req_method,
                                            NCBID_WEBPATH,
                                            SERV_NCBID_ARGS(&info->u.ncbid),
                                            0, user_header, info->mime_t,
                                            info->mime_s, info->mime_e, 0);
            break;
        case fSERV_Http:
        case fSERV_HttpGet:
        case fSERV_HttpPost:
            /* Connection directly to CGI */
            req_method  = info->type == fSERV_HttpGet
                ? eReqMethod_Get : (info->type == fSERV_HttpPost
                                    ? eReqMethod_Post : eReqMethod_Any);
            user_header = "Client-Mode: STATELESS_ONLY\r\n"; /*default*/
            user_header = s_AdjustNetParams(uuu->service, net_info, req_method,
                                            SERV_HTTP_PATH(&info->u.http),
                                            SERV_HTTP_ARGS(&info->u.http),
                                            0, user_header, info->mime_t,
                                            info->mime_s, info->mime_e, 0);
            break;
        case fSERV_Standalone:
            if (!net_info->stateless)
                return s_CreateSocketConnector(net_info, 0, 0);
            /* Otherwise, it will be a pass-thru connection via dispatcher */
            user_header = "Client-Mode: STATELESS_ONLY\r\n"; /*default*/
            user_header = s_AdjustNetParams(uuu->service, net_info,
                                            eReqMethod_Post, 0, 0,
                                            0, user_header, info->mime_t,
                                            info->mime_s, info->mime_e, 0);
            but_last = 1/*true*/;
            break;
        default:
            user_header = 0;
            break;
        }
    } else {
        EMIME_Type     mime_t;
        EMIME_SubType  mime_s;
        EMIME_Encoding mime_e;
        if (net_info->stateless  ||
            (info  &&  (info->u.firewall.type & fSERV_Http))) {
            if (info) {
                req_method = info->u.firewall.type == fSERV_HttpGet
                    ? eReqMethod_Get : (info->u.firewall.type == fSERV_HttpPost
                                        ? eReqMethod_Post : eReqMethod_Any);
                net_info->stateless = 1/*true*/;
            } else
                req_method = eReqMethod_Any;
        } else
            req_method = eReqMethod_Get;
        if (info) {
            mime_t = info->mime_t;
            mime_s = info->mime_s;
            mime_e = info->mime_e;
        } else {
            mime_t = eMIME_T_Undefined;
            mime_s = eMIME_Undefined;
            mime_e = eENCOD_None;
        }
        /* Firewall/relay connection to dispatcher, special tags */
        user_header = net_info->stateless
            ? "Client-Mode: STATELESS_ONLY\r\n" /*default*/
            : "Client-Mode: STATEFUL_CAPABLE\r\n";
        user_header = s_AdjustNetParams(uuu->service, net_info, req_method,
                                        0, 0, 0, user_header,
                                        mime_t, mime_s, mime_e, 0);
    }
    if (!user_header)
        return 0;

    if ((iter_header = SERV_Print(uuu->iter, net_info, but_last)) != 0) {
        size_t uh_len;
        if ((uh_len = strlen(user_header)) > 0) {
            char*  ih;
            size_t ih_len = strlen(iter_header);
            if ((ih = (char*) realloc(iter_header, ih_len + uh_len + 1)) != 0){
                strcpy(ih + ih_len, user_header);
                iter_header = ih;
            }
            free((char*) user_header);
        }
        user_header = iter_header;
    } else if (!*user_header)
        user_header = 0; /* special case of assignment of literal "" */

    if (uuu->user_header) {
        ConnNetInfo_DeleteUserHeader(net_info, uuu->user_header);
        free((void*) uuu->user_header);
    }
    uuu->user_header = user_header;
    if (user_header && !ConnNetInfo_OverrideUserHeader(net_info, user_header))
        return 0;

    if (!second_try) {
        ConnNetInfo_ExtendUserHeader
            (net_info, "User-Agent: NCBIServiceConnector/"
             DISP_PROTOCOL_VERSION
#ifdef NCBI_CXX_TOOLKIT
             " (C++ Toolkit)"
#else
             " (C Toolkit)"
#endif
             "\r\n");
    }

    if (!net_info->stateless  &&  (!info                         ||
                                   info->type == fSERV_Firewall  ||
                                   info->type == fSERV_Ncbid)) {
        /* Auxiliary HTTP connector first */
        EIO_Status status = eIO_Success;
        CONNECTOR c;
        CONN conn;

        /* Clear connection info */
        uuu->host = 0;
        uuu->port = 0;
        uuu->ticket = 0;
        net_info->max_try = 1;
        c = HTTP_CreateConnectorEx(net_info,
                                   (uuu->params.flags & fHCC_Flushable)
                                   | fHCC_SureFlush/*flags*/,
                                   s_ParseHeader, 0/*adj.info*/,
                                   uuu/*adj.data*/, 0/*cleanup.data*/);
        /* Wait for connection info back (error-transparent by DISPD.CGI) */
        if (c  &&  (status = CONN_Create(c, &conn)) == eIO_Success) {
            CONN_SetTimeout(conn, eIO_Open,      timeout);
            CONN_SetTimeout(conn, eIO_ReadWrite, timeout);
            CONN_SetTimeout(conn, eIO_Close,     timeout);
            CONN_Flush(conn);
            /* This also triggers parse header callback */
            CONN_Close(conn);
        } else {
            const char* error = c ? IO_StatusStr(status) : 0;
            CORE_LOGF_X(4, eLOG_Error,
                        ("[%s]  Unable to create auxiliary HTTP %s%s%s",
                         uuu->service, c ? "connection" : "connector",
                         error  &&  *error ? ": " : "", error ? error : ""));
            assert(0);
        }
        if (!uuu->host)
            return 0/*failed, no connection info returned*/;
        if (uuu->host == (unsigned int)(-1)) {
            /* Firewall mode only in stateful mode, fallback requested */
            assert((!info  ||  info->type == fSERV_Firewall)  &&  !second_try);
            /* Try to use stateless mode instead */
            net_info->stateless = 1/*true*/;
            return s_Open(uuu, timeout, info, net_info, 1/*second try*/);
        }
        SOCK_ntoa(uuu->host, net_info->host, sizeof(net_info->host));
        net_info->port = uuu->port;
        return s_CreateSocketConnector(net_info, &uuu->ticket,
                                       uuu->ticket ? sizeof(uuu->ticket) : 0);
    }
    return HTTP_CreateConnectorEx(net_info,
                                  (uuu->params.flags
                                   & (fHCC_Flushable | fHCC_NoAutoRetry))
                                  | fHCC_AutoReconnect,
                                  s_ParseHeader, s_AdjustNetInfo,
                                  uuu/*adj.data*/, 0/*cleanup.data*/);
}
示例#9
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*/;
}
示例#10
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;
}