END_NCBI_SCOPE int main(int argc, char* argv[]) { USING_NCBI_SCOPE; // Setup error posting SetDiagTrace(eDT_Enable); SetDiagPostLevel(eDiag_Trace); SetDiagPostAllFlags(SetDiagPostAllFlags(eDPF_Default) | eDPF_All | eDPF_OmitInfoSev); UnsetDiagPostFlag(eDPF_Line); UnsetDiagPostFlag(eDPF_File); UnsetDiagPostFlag(eDPF_Location); UnsetDiagPostFlag(eDPF_LongFilename); SetDiagTraceAllFlags(SetDiagPostAllFlags(eDPF_Default)); // Init the library explicitly (this sets up the log) CONNECT_Init(0); STimeout tmo = { 5, 0 }; EIO_Status status = Soaker(argv[1], "Hello", &tmo, &tmo); cout << "Status = " << IO_StatusStr(status) << endl; return !(status == eIO_Success); }
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; }
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); } }
static void TEST_CORE_Io(void) { /* EIO_Status, IO_StatusStr() */ int x_status; for (x_status = 0; x_status <= (int) eIO_Unknown; x_status++) { switch ( (EIO_Status) x_status ) { case eIO_Success: case eIO_Timeout: case eIO_Closed: case eIO_Interrupt: case eIO_InvalidArg: case eIO_NotSupported: case eIO_Unknown: assert(IO_StatusStr((EIO_Status) x_status)); printf("IO_StatusStr(status = %d): \"%s\"\n", x_status, IO_StatusStr((EIO_Status) x_status)); break; default: assert(0); } } }
static void s_ReadSocket(CSocket& sock, void* buffer, size_t buffer_size, size_t* bytes_read) { EIO_Status status; while ((status = sock.Read(buffer, buffer_size, bytes_read)) == eIO_Interrupt) /* no-op */; if (status != eIO_Success) { // eIO_Timeout, eIO_Closed, eIO_InvalidArg, // eIO_NotSupported, eIO_Unknown NCBI_THROW_FMT(CNetStorageException, eIOError, "I/O error while reading from NetStorage server " << sock.GetPeerAddress() << ". " "Socket status: " << IO_StatusStr(status) << '.'); } }
static void s_WriteToSocket(CSocket& sock, const char* output_buffer, size_t output_buffer_size) { size_t bytes_written; while (output_buffer_size > 0) { EIO_Status status = sock.Write(output_buffer, output_buffer_size, &bytes_written); if (status != eIO_Success) { // Error writing to the socket. // Log what we can. string message_start; if (output_buffer_size > 32) { CTempString buffer_head(output_buffer, 32); message_start = NStr::PrintableString(buffer_head); message_start += " (TRUNCATED)"; } else { CTempString buffer_head(output_buffer, output_buffer_size); message_start = NStr::PrintableString(buffer_head); } NCBI_THROW_FMT(CNetStorageException, eIOError, "Error writing message to the NetStorage server " << sock.GetPeerAddress() << ". " "Socket write error status: " << IO_StatusStr(status) << ". " "Bytes written: " << NStr::NumericToString(bytes_written) << ". " "Message begins with: " << message_start); } output_buffer += bytes_written; output_buffer_size -= bytes_written; } }
BEGIN_NCBI_SCOPE string CConn_Streambuf::x_Message(const char* msg) { const char* type = m_Conn ? CONN_GetType (m_Conn) : 0; char* text = m_Conn ? CONN_Description(m_Conn) : 0; string result("CConn_Streambuf::"); result += msg; if (type || text) { result += " ("; result += type ? type : "UNDEF"; if (text) { _ASSERT(*text); result += "; "; result += text; free(text); } result += ')'; } result += ": "; result += IO_StatusStr(m_Status); return result; }
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; }
static void TEST__server_2(SOCK sock, LSOCK lsock) { EIO_Status status; size_t n_io, n_io_done; char buf[TEST_BUFSIZE]; STimeout r_to, w_to, rc_to; size_t i; CORE_LOG(eLOG_Note, "TEST__server_2(TS2)"); r_to.sec = 0; r_to.usec = 0; w_to = r_to; rc_to.sec = 30; rc_to.usec = 123456; /* goto */ l_reconnect: /* reconnection loopback */ SOCK_SetDataLogging(sock, eOn); status = SOCK_SetTimeout(sock, eIO_Read, &r_to); assert(status == eIO_Success); status = SOCK_SetTimeout(sock, eIO_Write, &w_to); assert(status == eIO_Success); for (i = 0; ; i++) { char* x_buf; /* read data from socket */ n_io = sizeof(buf); status = SOCK_Read(sock, buf, n_io, &n_io_done, eIO_ReadPlain); switch ( status ) { case eIO_Success: CORE_LOGF(eLOG_Note, ("TS2::read:" " [%lu], status=%7s, n_io=%5lu, n_io_done=%5lu", (unsigned long)i, IO_StatusStr(status), (unsigned long)n_io, (unsigned long)n_io_done)); assert(n_io_done > 0); break; case eIO_Closed: CORE_LOG(eLOG_Note, "TS2::read: connection closed"); assert(SOCK_Status(sock, eIO_Read) == eIO_Closed); /* close connection */ status = SOCK_Close(sock); assert(status == eIO_Success || status == eIO_Closed); /* reconnect */ if ( !lsock ) return; CORE_LOG(eLOG_Note, "TS2::reconnect"); if ((status = LSOCK_Accept(lsock, &rc_to, &sock)) != eIO_Success) return; assert(SOCK_Status(sock, eIO_Read) == eIO_Success); /* !!! */ goto l_reconnect; case eIO_Timeout: CORE_LOGF(eLOG_Note, ("TS2::read:" " [%lu] timeout expired: %5u sec, %6u usec", (unsigned long)i, r_to.sec, r_to.usec)); assert(n_io_done == 0); s_DoubleTimeout(&r_to); status = SOCK_SetTimeout(sock, eIO_Read, &r_to); assert(status == eIO_Success); assert(SOCK_Status(sock, eIO_Read) == eIO_Timeout); break; default: CORE_LOGF(eLOG_Fatal, ("TS2::read: status = %d", (int) status)); } /* switch */ /* write(just the same) data back to client */ n_io = n_io_done; x_buf = buf; while ( n_io ) { status = SOCK_Write(sock, buf, n_io, &n_io_done, eIO_WritePersist); switch ( status ) { case eIO_Success: CORE_LOGF(eLOG_Note, ("TS2::write:" " [%lu], status=%7s, n_io=%5lu, n_io_done=%5lu", (unsigned long)i, IO_StatusStr(status), (unsigned long)n_io, (unsigned long)n_io_done)); assert(n_io_done > 0); break; case eIO_Closed: CORE_LOG(eLOG_Fatal, "TS2::write: connection closed"); return; case eIO_Timeout: CORE_LOGF(eLOG_Note, ("TS2::write:" " [%lu] timeout expired: %5u sec, %6u usec", (unsigned long)i, w_to.sec, w_to.usec)); assert(n_io_done == 0); s_DoubleTimeout(&w_to); status = SOCK_SetTimeout(sock, eIO_Write, &w_to); assert(status == eIO_Success); break; default: CORE_LOGF(eLOG_Fatal, ("TS2::write: status = %d", (int) status)); } /* switch */ n_io -= n_io_done; x_buf += n_io_done; } } }
static void TEST__client_2(SOCK sock) { #define W_FIELD 10 #define N_FIELD 1000 #define N_REPEAT 10 #define N_RECONNECT 3 EIO_Status status; size_t n_io, n_io_done, i; char buf[W_FIELD * N_FIELD + 1]; CORE_LOGF(eLOG_Note, ("TEST__client_2(TC2) @:%hu", SOCK_GetLocalPort(sock, eNH_HostByteOrder))); /* fill out a buffer to send to server */ memset(buf, 0, sizeof(buf)); for (i = 0; i < N_FIELD; i++) { sprintf(buf + i * W_FIELD, "%10lu", (unsigned long)i); } /* send the buffer to server, then get it back */ for (i = 0; i < N_REPEAT; i++) { char buf1[sizeof(buf)]; STimeout w_to, r_to; int/*bool*/ w_timeout_on = (int)(i%2); /* if to start from */ int/*bool*/ r_timeout_on = (int)(i%2); /* zero or inf. timeout */ char* x_buf; /* set timeout */ w_to.sec = 0; w_to.usec = 0; status = SOCK_SetTimeout(sock, eIO_Write, w_timeout_on ? &w_to : 0); assert(status == eIO_Success); /* reconnect */ if ((i % N_RECONNECT) == 0) { size_t j = i / N_RECONNECT; do { SOCK_SetDataLogging(sock, eOn); status = SOCK_Reconnect(sock, 0, 0, 0); SOCK_SetDataLogging(sock, eDefault); CORE_LOGF(eLOG_Note, ("TC2::reconnect @:%hu: i=%lu, j=%lu, status=%s", SOCK_GetLocalPort(sock, eNH_HostByteOrder), (unsigned long) i, (unsigned long) j, IO_StatusStr(status))); assert(status == eIO_Success); assert(SOCK_Status(sock, eIO_Read) == eIO_Success); assert(SOCK_Status(sock, eIO_Write) == eIO_Success); /* give a break to let server reset the listening socket */ X_SLEEP(1); } while ( j-- ); } /* send */ x_buf = buf; n_io = sizeof(buf); do { X_SLEEP(1); status = SOCK_Write(sock, x_buf, n_io, &n_io_done, eIO_WritePersist); if (status == eIO_Closed) CORE_LOG(eLOG_Fatal, "TC2::write: connection closed"); CORE_LOGF(eLOG_Note, ("TC2::write:" " i=%d, status=%7s, n_io=%5lu, n_io_done=%5lu" " timeout(%d): %5u.%06us", (int) i, IO_StatusStr(status), (unsigned long) n_io, (unsigned long) n_io_done, (int) w_timeout_on, w_to.sec, w_to.usec)); if ( !w_timeout_on ) { assert(status == eIO_Success && n_io_done == n_io); } else { const STimeout* x_to; assert(status == eIO_Success || status == eIO_Timeout); x_to = SOCK_GetTimeout(sock, eIO_Write); assert(w_to.sec == x_to->sec && w_to.usec == x_to->usec); } n_io -= n_io_done; x_buf += n_io_done; if (status == eIO_Timeout) s_DoubleTimeout(&w_to); status = SOCK_SetTimeout(sock, eIO_Write, &w_to); assert(status == eIO_Success); w_timeout_on = 1/*true*/; } while ( n_io ); /* get back the just sent data */ r_to.sec = 0; r_to.usec = 0; status = SOCK_SetTimeout(sock, eIO_Read, r_timeout_on ? &r_to : 0); assert(status == eIO_Success); x_buf = buf1; n_io = sizeof(buf1); do { if (i%2 == 0) { /* peek a little piece twice and compare */ char xx_buf1[128], xx_buf2[128]; size_t xx_io_done1, xx_io_done2; if (SOCK_Read(sock, xx_buf1, sizeof(xx_buf1), &xx_io_done1, eIO_ReadPeek) == eIO_Success && SOCK_Read(sock, xx_buf2, xx_io_done1, &xx_io_done2, eIO_ReadPeek) == eIO_Success) { assert(xx_io_done1 >= xx_io_done2); assert(memcmp(xx_buf1, xx_buf2, xx_io_done2) == 0); } } status = SOCK_Read(sock, x_buf, n_io, &n_io_done, eIO_ReadPlain); if (status == eIO_Closed) { assert(SOCK_Status(sock, eIO_Read) == eIO_Closed); CORE_LOG(eLOG_Fatal, "TC2::read: connection closed"); } CORE_LOGF(eLOG_Note, ("TC2::read: " " i=%d, status=%7s, n_io=%5lu, n_io_done=%5lu" " timeout(%d): %5u.%06us", (int) i, IO_StatusStr(status), (unsigned long) n_io, (unsigned long) n_io_done, (int) r_timeout_on, r_to.sec, r_to.usec)); if ( !r_timeout_on ) { assert(status == eIO_Success && n_io_done > 0); } else { const STimeout* x_to; assert(status == eIO_Success || status == eIO_Timeout); x_to = SOCK_GetTimeout(sock, eIO_Read); assert(r_to.sec == x_to->sec && r_to.usec == x_to->usec); } n_io -= n_io_done; x_buf += n_io_done; if (status == eIO_Timeout) s_DoubleTimeout(&r_to); status = SOCK_SetTimeout(sock, eIO_Read, &r_to); assert(status == eIO_Success); r_timeout_on = 1/*true*/; } while ( n_io ); assert(memcmp(buf, buf1, sizeof(buf)) == 0); } }
int main(int argc, char** argv) { /* Prepare to connect: parse and check cmd.-line args, etc. */ const char* host = argc > 1 ? argv[1] : ""; unsigned short port = argc > 2 ? atoi(argv[2]) : CONN_PORT_HTTP; const char* path = argc > 3 ? argv[3] : ""; const char* args = argc > 4 ? argv[4] : ""; const char* inp_file = argc > 5 ? argv[5] : ""; const char* user_header = argc > 6 ? argv[6] : ""; size_t content_length; STimeout timeout; SOCK sock; EIO_Status status; char buffer[10000]; CORE_SetLOGFormatFlags(fLOG_None | fLOG_Level | fLOG_OmitNoteLevel | fLOG_DateTime); CORE_SetLOGFILE(stderr, 0/*false*/); SOCK_SetupSSL(NcbiSetupTls); fprintf(stderr, "Running...\n" " Executable: '%s'\n" " URL host: '%s'\n" " URL port: %hu\n" " URL path: '%s'\n" " URL args: '%s'\n" " Input data file: '%s'\n" " User header: '%s'\n" "Response(if any) from the hit URL goes to standard output.\n\n", argv[0], host, port, path, args, inp_file, user_header); if ( argc < 4 ) { fprintf(stderr, "Usage: %s host port path args inp_file [user_header]\n", argv[0]); CORE_LOG(eLOG_Fatal, "Two few arguments"); return 1; } {{ FILE *fp = fopen(inp_file, "rb"); long offset; if ( !fp ) { CORE_LOGF(eLOG_Fatal, ("Non-existent file '%s'", inp_file)); return 2; } if ( fseek(fp, 0, SEEK_END) != 0 || (offset = ftell(fp)) < 0 ) { CORE_LOGF(eLOG_Fatal, ("Cannot obtain size of file '%s'", inp_file)); return 2; } fclose(fp); content_length = (size_t) offset; }} timeout.sec = 10; timeout.usec = 0; /* Connect */ sock = URL_Connect(host, port, path, args, /*NCBI_FAKE_WARNING*/ eReqMethod_Any, content_length, &timeout, &timeout, user_header, 1/*true*/, port == CONN_PORT_HTTPS ? fSOCK_LogDefault | fSOCK_Secure : fSOCK_LogDefault); if ( !sock ) return 3; {{ /* Pump data from the input file to socket */ FILE* fp = fopen(inp_file, "rb"); if ( !fp ) { CORE_LOGF(eLOG_Fatal, ("Cannot open file '%s' for reading", inp_file)); return 4; } for (;;) { size_t n_written; size_t n_read = fread(buffer, 1, sizeof(buffer), fp); if ( n_read <= 0 ) { if ( content_length ) { CORE_LOGF(eLOG_Fatal, ("Cannot read last %lu bytes from file '%s'", (unsigned long) content_length, inp_file)); return 5; } break; } assert(content_length >= n_read); content_length -= n_read; status = SOCK_Write(sock, buffer, n_read, &n_written, eIO_WritePersist); if ( status != eIO_Success ) { CORE_LOGF(eLOG_Fatal, ("Error writing to socket: %s", IO_StatusStr(status))); return 6; } } fclose(fp); }} /* Read reply from socket, write it to STDOUT */ {{ size_t n_read; for (;;) { status = SOCK_Read(sock, buffer, sizeof(buffer), &n_read, eIO_ReadPlain); if (status != eIO_Success) break; fwrite(buffer, 1, n_read, stdout); } if ( status != eIO_Closed ) { CORE_LOGF(eLOG_Error, ("Read error after %ld byte(s) from socket: %s", (long) content_length, IO_StatusStr(status))); } fprintf(stdout, "\n"); }} /* Success: close the socket, cleanup, and exit */ SOCK_Close(sock); CORE_LOG(eLOG_Note, "TEST completed successfully"); CORE_SetLOG(0); return 0; }
static EIO_Status s_VT_Open(CONNECTOR connector, const STimeout* timeout) { SServiceConnector* uuu = (SServiceConnector*) connector->handle; SMetaConnector* meta = connector->meta; EIO_Status status; for (;;) { const SSERV_Info* info; SConnNetInfo* net_info; CONNECTOR conn; int stateless; assert(!uuu->meta.list && !uuu->name && !uuu->descr); if (!uuu->iter && !s_OpenDispatcher(uuu)) { status = eIO_Closed; break; } if (uuu->net_info->firewall && strcasecmp(uuu->iter->name, "local")) info = 0; else if (!(info = s_GetNextInfo(uuu))) { status = eIO_Closed; break; } if (!(net_info = ConnNetInfo_Clone(uuu->net_info))) { status = eIO_Unknown; break; } net_info->scheme = eURL_Unspec; conn = s_Open(uuu, timeout, info, net_info, 0/*!second_try*/); if (conn) uuu->descr = ConnNetInfo_URL(net_info); stateless = net_info->stateless; ConnNetInfo_Destroy(net_info); if (!conn) { if (!info) { status = eIO_Closed; break; } continue; } /* Setup the new connector on a temporary meta-connector... */ memset(&uuu->meta, 0, sizeof(uuu->meta)); METACONN_Add(&uuu->meta, conn); /* ...then link it in using current connection's meta */ conn->meta = meta; conn->next = meta->list; meta->list = conn; if (!uuu->descr && uuu->meta.descr) CONN_SET_METHOD(meta, descr, uuu->meta.descr, uuu->meta.c_descr); CONN_SET_METHOD (meta, wait, uuu->meta.wait, uuu->meta.c_wait); CONN_SET_METHOD (meta, write, uuu->meta.write, uuu->meta.c_write); CONN_SET_METHOD (meta, flush, uuu->meta.flush, uuu->meta.c_flush); CONN_SET_METHOD (meta, read, uuu->meta.read, uuu->meta.c_read); CONN_SET_METHOD (meta, status,uuu->meta.status,uuu->meta.c_status); if (uuu->meta.get_type) { const char* type; if ((type = uuu->meta.get_type(uuu->meta.c_get_type)) != 0) { size_t slen = strlen(uuu->service); size_t tlen = strlen(type); char* name = (char*) malloc(slen + tlen + 2); if (name) { memcpy(name, uuu->service, slen); name[slen++] = '/'; memcpy(name + slen, type, tlen); tlen += slen; name[tlen] = '\0'; uuu->name = name; } } } status = uuu->meta.open ? uuu->meta.open(uuu->meta.c_open, timeout) : eIO_Success; if (status == eIO_Success) break; if (!stateless && (!info || info->type == fSERV_Firewall)) { static const char kFWLink[] = { "http://www.ncbi.nlm.nih.gov" "/IEB/ToolBox/NETWORK" "/dispatcher.html#Firewalling"}; CORE_LOGF_X(6, eLOG_Error, ("[%s] %s connection failed (%s) indicating possible " "firewall configuration problem; please consult <%s>", uuu->service, !info ? "Firewall" : "Stateful relay", IO_StatusStr(status), kFWLink)); } s_Close(connector, timeout, 0/*don't close dispatcher just as yet*/); } uuu->status = status; return status; }
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*/); }
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*/; }
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; }
/* Connect to the server specified by uuu->net_info, then compose and form * relevant HTTP header, and flush the accumulated output data(uuu->w_buf) * after the HTTP header. If connection/write unsuccessful, retry to reconnect * and send the data again until permitted by s_Adjust(). */ static EIO_Status s_ConnectAndSend(SHttpConnector* uuu, EReadMode read_mode) { EIO_Status status; for (;;) { char* null = 0; if (!uuu->sock) { if ((status = s_Connect(uuu, read_mode)) != eIO_Success) break; assert(uuu->sock); uuu->read_header = 1/*true*/; uuu->shut_down = 0/*false*/; uuu->expected = 0; uuu->received = 0; uuu->code = 0; } else status = eIO_Success; if (uuu->w_len) { size_t off = BUF_Size(uuu->w_buf) - uuu->w_len; SOCK_SetTimeout(uuu->sock, eIO_Write, uuu->w_timeout); do { char buf[4096]; size_t n_written; size_t n_write = BUF_PeekAt(uuu->w_buf, off, buf, sizeof(buf)); status = SOCK_Write(uuu->sock, buf, n_write, &n_written, eIO_WritePlain); if (status != eIO_Success) break; uuu->w_len -= n_written; off += n_written; } while (uuu->w_len); } else if (!uuu->shut_down) status = SOCK_Write(uuu->sock, 0, 0, 0, eIO_WritePlain); if (status == eIO_Success) { assert(uuu->w_len == 0); if (!uuu->shut_down) { /* 10/07/03: While this call here is perfectly legal, it could * cause connection severed by a buggy CISCO load-balancer. */ /* 10/28/03: CISCO's beta patch for their LB shows that the * problem has been fixed; no more 2'30" drops in connections * that shut down for write. We still leave this commented * out to allow unpatched clients to work seamlessly... */ /*SOCK_Shutdown(uuu->sock, eIO_Write);*/ uuu->shut_down = 1; } break; } if (status == eIO_Timeout && uuu->w_timeout && !(uuu->w_timeout->sec | uuu->w_timeout->usec)) { break; } CORE_LOGF_X(6, eLOG_Error, ("[HTTP] Error writing body at offset %lu (%s)", (unsigned long)(BUF_Size(uuu->w_buf) - uuu->w_len), IO_StatusStr(status))); /* write failed; close and try to use another server */ SOCK_Abort(uuu->sock); s_DropConnection(uuu, 0/*no wait*/); if (!s_Adjust(uuu, &null, read_mode)) { uuu->can_connect = eCC_None; status = eIO_Closed; break; } } return status; }
/* Parse HTTP header */ static EIO_Status s_ReadHeader(SHttpConnector* uuu, char** retry, EReadMode read_mode) { ERetry redirect = eRetry_None; int server_error = 0; int http_status; EIO_Status status; char* header; size_t size; assert(uuu->sock && uuu->read_header); *retry = 0; /* line by line HTTP header input */ for (;;) { /* do we have full header yet? */ size = BUF_Size(uuu->http); if (!(header = (char*) malloc(size + 1))) { CORE_LOGF_X(7, eLOG_Error, ("[HTTP] Cannot allocate header, %lu bytes", (unsigned long) size)); return eIO_Unknown; } verify(BUF_Peek(uuu->http, header, size) == size); header[size] = '\0'; if (size >= 4 && strcmp(&header[size - 4], "\r\n\r\n") == 0) break/*full header captured*/; free(header); status = SOCK_StripToPattern(uuu->sock, "\r\n", 2, &uuu->http, 0); if (status != eIO_Success) { ELOG_Level level; if (status == eIO_Timeout) { const STimeout* tmo = SOCK_GetTimeout(uuu->sock, eIO_Read); if (!tmo) level = eLOG_Error; else if (tmo->sec | tmo->usec) level = eLOG_Warning; else if (read_mode != eRM_WaitCalled) level = eLOG_Trace; else return status; } else level = eLOG_Error; CORE_LOGF_X(8, level, ("[HTTP] Error reading header (%s)", IO_StatusStr(status))); return status; } } /* the entire header has been read */ uuu->read_header = 0/*false*/; status = eIO_Success; if (BUF_Read(uuu->http, 0, size) != size) { CORE_LOG_X(9, eLOG_Error, "[HTTP] Cannot discard HTTP header buffer"); status = eIO_Unknown; assert(0); } /* HTTP status must come on the first line of the response */ if (sscanf(header, "HTTP/%*d.%*d %d ", &http_status) != 1 || !http_status) http_status = -1; if (http_status < 200 || 299 < http_status) { server_error = http_status; if (http_status == 301 || http_status == 302) redirect = eRetry_Redirect; else if (http_status == 401) redirect = eRetry_Authenticate; else if (http_status == 407) redirect = eRetry_ProxyAuthenticate; else if (http_status < 0 || http_status == 403 || http_status == 404) uuu->net_info->max_try = 0; } uuu->code = http_status < 0 ? -1 : http_status; if ((server_error || !uuu->error_header) && uuu->net_info->debug_printout == eDebugPrintout_Some) { /* HTTP header gets printed as part of data logging when uuu->net_info->debug_printout == eDebugPrintout_Data. */ const char* header_header; if (!server_error) header_header = "HTTP header"; else if (uuu->flags & fHCC_KeepHeader) header_header = "HTTP header (error)"; else if (uuu->code == 301 || uuu->code == 302) header_header = "HTTP header (moved)"; else if (!uuu->net_info->max_try) header_header = "HTTP header (unrecoverable error)"; else header_header = "HTTP header (server error, can retry)"; CORE_DATA_X(19, header, size, header_header); } {{ /* parsing "NCBI-Message" tag */ static const char kNcbiMessageTag[] = "\n" HTTP_NCBI_MESSAGE " "; const char* s; for (s = strchr(header, '\n'); s && *s; s = strchr(s + 1, '\n')) { if (strncasecmp(s, kNcbiMessageTag, sizeof(kNcbiMessageTag)-1)==0){ const char* message = s + sizeof(kNcbiMessageTag) - 1; while (*message && isspace((unsigned char)(*message))) message++; if (!(s = strchr(message, '\r'))) s = strchr(message, '\n'); assert(s); do { if (!isspace((unsigned char) s[-1])) break; } while (--s > message); if (message != s) { if (s_MessageHook) { if (s_MessageIssued <= 0) { s_MessageIssued = 1; s_MessageHook(message); } } else { s_MessageIssued = -1; CORE_LOGF_X(10, eLOG_Critical, ("[NCBI-MESSAGE] %.*s", (int)(s - message), message)); } } break; } } }} if (uuu->flags & fHCC_KeepHeader) { if (!BUF_Write(&uuu->r_buf, header, size)) { CORE_LOG_X(11, eLOG_Error, "[HTTP] Cannot keep HTTP header"); status = eIO_Unknown; } free(header); return status; } if (uuu->parse_http_hdr && !(*uuu->parse_http_hdr)(header, uuu->adjust_data, server_error)) { server_error = 1/*fake, but still boolean true*/; } if (redirect == eRetry_Redirect) { /* parsing "Location" pointer */ static const char kLocationTag[] = "\nLocation: "; char* s; for (s = strchr(header, '\n'); s && *s; s = strchr(s + 1, '\n')) { if (strncasecmp(s, kLocationTag, sizeof(kLocationTag) - 1) == 0) { char* location = s + sizeof(kLocationTag) - 1; while (*location && isspace((unsigned char)(*location))) location++; if (!(s = strchr(location, '\r'))) s = strchr(location, '\n'); assert(s); do { if (!isspace((unsigned char) s[-1])) break; } while (--s > location); if (s != location) { size_t len = (size_t)(s - location); memmove(header, location, len); header[len] = '\0'; *retry = header; } break; } } } else if (redirect != eRetry_None) { /* parsing "Authenticate" tags */ static const char kAuthenticateTag[] = "-Authenticate: "; char* s; for (s = strchr(header, '\n'); s && *s; s = strchr(s + 1, '\n')) { if (strncasecmp(s + (redirect == eRetry_Authenticate ? 4 : 6), kAuthenticateTag, sizeof(kAuthenticateTag)-1)==0){ if ((redirect == eRetry_Authenticate && strncasecmp(s, "\nWWW", 4) != 0) || (redirect == eRetry_ProxyAuthenticate && strncasecmp(s, "\nProxy", 6) != 0)) { continue; } /* TODO */ } } } else if (!server_error) { static const char kContentLengthTag[] = "\nContent-Length: "; const char* s; for (s = strchr(header, '\n'); s && *s; s = strchr(s + 1, '\n')) { if (!strncasecmp(s,kContentLengthTag,sizeof(kContentLengthTag)-1)){ const char* expected = s + sizeof(kContentLengthTag) - 1; while (*expected && isspace((unsigned char)(*expected))) expected++; if (!(s = strchr(expected, '\r'))) s = strchr(expected, '\n'); assert(s); do { if (!isspace((unsigned char) s[-1])) break; } while (--s > expected); if (s != expected) { char* e; errno = 0; uuu->expected = (size_t) strtol(expected, &e, 10); if (errno || e != s) uuu->expected = 0; else if (!uuu->expected) uuu->expected = (size_t)(-1L); } break; } } } if (!*retry) free(header); /* skip & printout the content, if server error was flagged */ if (server_error && uuu->net_info->debug_printout == eDebugPrintout_Some) { BUF buf = 0; char* body; SOCK_SetTimeout(uuu->sock, eIO_Read, 0); /* read until EOF */ SOCK_StripToPattern(uuu->sock, 0, 0, &buf, 0); if (!(size = BUF_Size(buf))) { CORE_LOG_X(12, eLOG_Trace, "[HTTP] No HTTP body received with this error"); } else if ((body = (char*) malloc(size)) != 0) { size_t n = BUF_Read(buf, body, size); if (n != size) { CORE_LOGF_X(13, eLOG_Error, ("[HTTP] Cannot read server error " "body from buffer (%lu out of %lu)", (unsigned long) n, (unsigned long) size)); } CORE_DATA_X(20, body, n, "Server error body"); free(body); } else { CORE_LOGF_X(14, eLOG_Error, ("[HTTP] Cannot allocate server error " "body, %lu bytes", (unsigned long) size)); } BUF_Destroy(buf); } return server_error ? eIO_Unknown : status; }
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; }