NCBI C++ ToolKit
ncbi_conn_stream.cpp
Go to the documentation of this file.

Go to the SVN repository for this file.

1 /* $Id: ncbi_conn_stream.cpp 101304 2023-11-28 18:43:41Z lavr $
2  * ===========================================================================
3  *
4  * PUBLIC DOMAIN NOTICE
5  * National Center for Biotechnology Information
6  *
7  * This software/database is a "United States Government Work" under the
8  * terms of the United States Copyright Act. It was written as part of
9  * the author's official duties as a United States Government employee and
10  * thus cannot be copyrighted. This software/database is freely available
11  * to the public for use. The National Library of Medicine and the U.S.
12  * Government have not placed any restriction on its use or reproduction.
13  *
14  * Although all reasonable efforts have been taken to ensure the accuracy
15  * and reliability of the software and data, the NLM and the U.S.
16  * Government do not and cannot warrant the performance or results that
17  * may be obtained by using this software or data. The NLM and the U.S.
18  * Government disclaim all warranties, express or implied, including
19  * warranties of performance, merchantability or fitness for any particular
20  * purpose.
21  *
22  * Please cite the author in any work or product based on this material.
23  *
24  * ===========================================================================
25  *
26  * Authors: Anton Lavrentiev, Denis Vakatov
27  *
28  * File Description:
29  * CONN-based C++ streams
30  *
31  * See file <connect/ncbi_conn_stream.hpp> for more detailed information.
32  *
33  */
34 
35 #include <ncbi_pch.hpp>
36 #include "ncbi_ansi_ext.h"
37 #include "ncbi_conn_streambuf.hpp"
38 #include "ncbi_priv.h"
39 #include "ncbi_servicep.h"
40 #include "ncbi_socketp.h"
44 #include <stdlib.h>
45 
46 
48 
49 
50 const STimeout CConn_IOStream::kZeroTimeout = { 0, 0 };
51 
52 
54 
55 
57  const STimeout* timeout,
58  size_t buf_size, TConn_Flags flgs,
59  CT_CHAR_TYPE* ptr, size_t size)
60  : CNcbiIostream(0/*the stream is "bad" initially (27.4.4.1.3)*/),
61  m_CSb(0), x_CSb(new CConn_Streambuf(connector.first, connector.second,
62  timeout, buf_size, flgs,
63  ptr, size))
64 {
65  if (x_CSb->Status(eIO_Close) == eIO_Success)
66  init(m_CSb = x_CSb.get());
67 }
68 
69 
71  const STimeout* timeout,
72  size_t buf_size, TConn_Flags flgs,
73  CT_CHAR_TYPE* ptr, size_t size)
74  : CNcbiIostream(0/*the stream is "bad" initially (27.4.4.1.3)*/),
75  m_CSb(0), x_CSb(new CConn_Streambuf(conn, close,
76  timeout, buf_size, flgs,
77  ptr, size))
78 {
79  if (x_CSb->Status(eIO_Close) == eIO_Success)
80  init(m_CSb = x_CSb.get());
81 }
82 
83 
85 {
86  x_Destroy();
87 }
88 
89 
90 #define GET_CONN(sb) ((sb) ? (sb)->GetCONN() : 0)
91 
92 
94 {
95  return GET_CONN(m_CSb);
96 }
97 
98 
99 string CConn_IOStream::GetType(void) const
100 {
101  CONN conn = GET_CONN(m_CSb);
102  const char* type = conn ? CONN_GetType(conn) : 0;
103  return type ? type : kEmptyStr;
104 }
105 
106 
108 {
109  CONN conn = GET_CONN(m_CSb);
111  return text ? text.get() : kEmptyStr;
112 }
113 
114 
116  const STimeout* timeout) const
117 {
118  CONN conn = GET_CONN(m_CSb);
119  return conn ? CONN_SetTimeout(conn, direction, timeout) : eIO_NotSupported;
120 }
121 
122 
124 {
125  CONN conn = GET_CONN(m_CSb);
126  return conn ? CONN_GetTimeout(conn, direction) : kDefaultTimeout;
127 }
128 
129 
131 {
132  return m_CSb ? m_CSb->Status(dir) : eIO_NotSupported;
133 }
134 
135 
137 {
138  EIO_Status status;
139  CONN conn = GET_CONN(m_CSb);
140  if (!conn) {
141  setstate(NcbiBadbit);
142  status = eIO_NotSupported;
143  } else
144  status = m_CSb->Fetch(timeout);
145  return status;
146 }
147 
148 
150  streamsize size,
151  bool push)
152 {
153  EIO_Status status
154  = m_CSb ? m_CSb->Pushback(data, size, push) : eIO_NotSupported;
155  if (status != eIO_Success)
156  clear(NcbiBadbit);
157  return status;
158 }
159 
160 
162 {
163  SOCK sock;
164  CONN conn = GET_CONN(m_CSb);
165  if (!conn)
166  sock = 0;
167  else if (CONN_GetSOCK(conn, &sock) != eIO_Success)
168  _ASSERT(!sock);
169  return sock;
170 }
171 
172 
174 {
175  CONN conn = GET_CONN(m_CSb);
176  return conn ? CONN_Wait(conn, event, timeout) : eIO_Closed;
177 }
178 
179 
181 {
182  if (!m_CSb)
183  return eIO_Closed;
185  EIO_Status status = m_CSb->Close();
186  if (status != eIO_Success && status != eIO_Closed)
187  clear(NcbiBadbit);
189  m_Canceled.Reset(0);
190  return status;
191 }
192 
193 
195 {
196  x_CSb.reset();
197  m_CSb = 0;
198 }
199 
200 
202 {
203  CONN conn = GET_CONN(m_CSb);
204  if (!conn)
205  return eIO_NotSupported;
206 
207  bool isset = m_Canceled.NotNull() ? 1 : 0;
208 
209  if (canceled) {
210  SCONN_Callback cb;
211  m_Canceled = canceled;
212  memset(&cb, 0, sizeof(cb));
213  cb.func = sx_IsCanceled;
214  cb.data = this;
215  CONN_SetCallback(conn, eCONN_OnOpen, &cb, isset ? 0 : &m_CB[0]);
216  CONN_SetCallback(conn, eCONN_OnRead, &cb, isset ? 0 : &m_CB[1]);
217  CONN_SetCallback(conn, eCONN_OnWrite, &cb, isset ? 0 : &m_CB[2]);
218  CONN_SetCallback(conn, eCONN_OnFlush, &cb, isset ? 0 : &m_CB[3]);
219  } else if (isset) {
224  m_Canceled = 0;
225  }
226 
227  return eIO_Success;
228 }
229 
230 
233  void* data)
234 {
235  _ASSERT(conn && data);
236  CConn_IOStream* io = reinterpret_cast<CConn_IOStream*>(data);
237  if (/* io && */ io->m_Canceled.NotNull() && io->m_Canceled->IsCanceled())
238  return eIO_Interrupt;
239  int n = (int) type & (int) eIO_ReadWrite;
240  _ASSERT(0 <= n && (size_t) n < sizeof(io->m_CB) / sizeof(io->m_CB[0]));
241  _ASSERT((n == 0 && type == eCONN_OnOpen) ||
242  (n == 1 && type == eCONN_OnRead) ||
243  (n == 2 && type == eCONN_OnWrite) ||
244  (n == 3 && type == eCONN_OnFlush));
245  return io->m_CB[n].func
246  ? io->m_CB[n].func(conn, type, io->m_CB[n].data)
247  : eIO_Success;
248 
249 }
250 
251 
253  unsigned short port,
254  unsigned short max_try,
255  const STimeout* timeout,
256  size_t buf_size,
259  port,
260  max_try)),
261  timeout, buf_size, flags)
262 {
263  return;
264 }
265 
266 
268 s_SocketConnectorBuilder(const string& ahost,
269  unsigned short aport,
270  unsigned short max_try,
271  const void* data,
272  size_t size,
273  TSOCK_Flags flgs)
274 {
275  size_t len = ahost.size();
276  string x_host, xx_port;
277  unsigned int x_port;
278  const string* host;
279  unsigned short port;
280  CONNECTOR c;
281  if ((port = aport) != 0 && len) {
282  host = &ahost;
283  } else if (!len || NCBI_HasSpaces(ahost.c_str(), len)
284  || !NStr::SplitInTwo(ahost, ":", x_host, xx_port)
285  || x_host.empty() || xx_port.empty()
286  || !isdigit((unsigned char) xx_port[0]) || xx_port[0] == '0'
287  || !(x_port = NStr::StringToUInt(xx_port,
289  || (x_port ^ (x_port & 0xFFFF))) {
290  NCBI_THROW(CIO_Exception, eInvalidArg,
291  "CConn_SocketStream::CConn_SocketStream(\""
292  + ahost + "\", " + NStr::NumericToString(aport) + "): "
293  " Invalid/insufficient destination address");
294  } else {
295  port = x_port;
296  host = &x_host;
297  }
298  c = SOCK_CreateConnectorEx(host->c_str(), port, max_try,
299  data, size, flgs);
300  return CConn_IOStream::TConnector(c);
301 }
302 
303 
305  unsigned short port,
306  const void* data,
307  size_t size,
308  TSOCK_Flags flgs,
309  unsigned short max_try,
310  const STimeout* timeout,
311  size_t buf_size,
313  : CConn_IOStream(s_SocketConnectorBuilder(host, port, max_try,
314  data, size, flgs),
315  timeout, buf_size, flags)
316 {
317  return;
318 }
319 
320 
322  EOwnership if_to_own,
323  const STimeout* timeout,
324  size_t buf_size,
327  if_to_own
328  != eNoOwnership)),
329  timeout, buf_size, flags)
330 {
331  return;
332 }
333 
334 
335 static SOCK s_GrabSOCK(CSocket& socket)
336 {
337  SOCK sock = socket.GetSOCK();
338  if (!sock) {
339  NCBI_THROW(CIO_Exception, eInvalidArg,
340  "CConn_SocketStream::CConn_SocketStream(): "
341  " Socket may not be empty");
342  }
343  if (socket.SetOwnership(eNoOwnership) == eNoOwnership) {
344  NCBI_THROW(CIO_Exception, eInvalidArg,
345  "CConn_SocketStream::CConn_SocketStream(): "
346  " Socket must be owned");
347  }
348  socket.Reset(0/*empty*/,
349  eNoOwnership/*irrelevant*/,
350  eCopyTimeoutsFromSOCK/*irrelevant*/);
351  return sock;
352 }
353 
354 
356  const STimeout* timeout,
357  size_t buf_size,
360  1/*own*/)),
361  timeout, buf_size, flags)
362 {
363  return;
364 }
365 
366 
367 template<>
368 struct Deleter<SConnNetInfo>
369 {
370  static void Delete(SConnNetInfo* net_info)
371  { ConnNetInfo_Destroy(net_info); }
372 };
373 
374 
377  const STimeout* timeout,
378  const void* data,
379  size_t size,
380  TSOCK_Flags flgs)
381 {
382  EIO_Status status = eIO_Success;
383  bool proxy = false;
384  SOCK sock = 0;
385 
386  _ASSERT(net_info);
387  if ((flgs & (fSOCK_LogOn | fSOCK_LogDefault)) == fSOCK_LogDefault
388  && net_info->debug_printout == eDebugPrintout_Data) {
389  flgs &= ~fSOCK_LogDefault;
390  flgs |= fSOCK_LogOn;
391  }
392  if (net_info->http_proxy_host[0] && net_info->http_proxy_port
393  && !net_info->http_proxy_only) {
394  status = HTTP_CreateTunnel(net_info, fHTTP_NoAutoRetry, &sock);
395  _ASSERT(!sock ^ !(status != eIO_Success));
396  if (status == eIO_Success
397  && (size || (flgs & ~(fSOCK_LogOn | fSOCK_LogDefault)))) {
399  memset(&init, 0, sizeof(init));
400  init.data = data;
401  init.size = size;
402  init.host = net_info->host;
403  init.cred = net_info->credentials;
404  SOCK s;
405  status = SOCK_CreateOnTopInternal(sock, 0, &s, &init, flgs);
406  _ASSERT(!s ^ !(status != eIO_Success));
407  SOCK_Destroy(sock);
408  sock = s;
409  }
410  proxy = true;
411  }
412  if (!sock && (!proxy || net_info->http_proxy_leak)) {
413  if (timeout == kDefaultTimeout)
414  timeout = net_info->timeout;
415  if (!proxy && net_info->debug_printout) {
416  AutoPtr<SConnNetInfo> x_net_info(ConnNetInfo_Clone(net_info));
417  if (x_net_info) {
418  // NB: This is only for logging! (so no throw on NULL)
419  // Manual cleanup of most fields req'd :-/
420  x_net_info->scheme = eURL_Unspec;
421  x_net_info->req_method = eReqMethod_Any;
422  x_net_info->external = 0;
423  x_net_info->firewall = 0;
424  x_net_info->stateless = 0;
425  x_net_info->lb_disable = 0;
426  x_net_info->http_version = 0;
427  x_net_info->http_push_auth = 0;
428  x_net_info->http_proxy_leak = 0;
429  x_net_info->http_proxy_skip = 0;
430  x_net_info->http_proxy_only = 0;
431  x_net_info->user[0] = '\0';
432  x_net_info->pass[0] = '\0';
433  x_net_info->path[0] = '\0';
434  x_net_info->http_proxy_host[0] = '\0';
435  x_net_info->http_proxy_port = 0;
436  x_net_info->http_proxy_user[0] = '\0';
437  x_net_info->http_proxy_pass[0] = '\0';
438  ConnNetInfo_SetUserHeader(x_net_info.get(), 0);
439  if (x_net_info->http_referer) {
440  free((void*) x_net_info->http_referer);
441  x_net_info->http_referer = 0;
442  }
443  x_net_info->timeout = timeout;
444  }
446  ConnNetInfo_Log(x_net_info.get(), eLOG_Note, CORE_GetLOG());
447  CORE_UNLOCK;
448  }
450  memset(&init, 0, sizeof(init));
451  init.data = data;
452  init.size = size;
453  init.host = net_info->host;
454  init.cred = net_info->credentials;
455  status = SOCK_CreateInternal(net_info->host, net_info->port, timeout,
456  &sock, &init, flgs);
457  _ASSERT(!sock ^ !(status != eIO_Success));
458  }
459  string hostport(net_info->host);
460  hostport += ':';
461  hostport += NStr::UIntToString(net_info->port);
462  CONNECTOR c = SOCK_CreateConnectorOnTopEx(sock, 1/*own*/,hostport.c_str());
463  if (!c) {
464  SOCK_Abort(sock);
465  SOCK_Close(sock);
466  }
467  return CConn_IOStream::TConnector(c, status);
468 }
469 
470 
472  const void* data,
473  size_t size,
474  TSOCK_Flags flgs,
475  const STimeout* timeout,
476  size_t buf_size,
478  : CConn_IOStream(s_SocketConnectorBuilder(&net_info, timeout,
479  data, size, flgs),
480  timeout, buf_size, flags)
481 {
482  return;
483 }
484 
485 
486 //
487 // WARNING: All sx_ callbacks that operate on data members of non-primitive
488 // types MUST NOT be indirectly called before the respective stream's
489 // constructor body, and may not be used after that stream's dtor!!!
490 //
491 // Notably, sx_ParseHeader operates on SHTTP_StatusData, or SERVICE connector's
492 // sx_Adjust (with failure_count == -1) gets called from that connector's Open,
493 // which is done by default from the CConn_Streambuf's ctor unless
494 // fConn_DelayOpen is set in the stream's flags.
495 //
496 
497 
499 {
500  Clear();
501  const char* eol = strstr(header, HTTP_EOL);
502  if (!eol)
503  return eHTTP_HeaderError;
504  int c, n;
505  if (sscanf(header, "HTTP/%*[0-9.] %u%n", &c, &n) < 1 || eol < header + n)
506  return eHTTP_HeaderError;
507  m_Header = header;
508  const char* str = m_Header.c_str();
509  eol = str + (size_t)(eol - header);
510  str += n;
511  str += strspn(str, " \t");
512  while (eol > str) {
513  if (!isspace((unsigned char) eol[-1]))
514  break;
515  --eol;
516  }
517  m_Code = c;
518  m_Text.assign(str, (size_t)(eol - str));
519  return eHTTP_HeaderSuccess;
520 }
521 
522 
525  EReqMethod method,
526  const char* url,
527  const char* host,
528  unsigned short port,
529  const char* path,
530  const char* args,
531  const char* user_header,
532  void* x_data,
533  FHTTP_Adjust x_adjust,
534  FHTTP_Cleanup x_cleanup,
535  FHTTP_ParseHeader x_parse_header,
536  THTTP_Flags flgs,
537  const STimeout* timeout,
538  void** user_data_ptr,
539  FHTTP_Cleanup* user_cleanup_ptr,
540  void* user_data = 0,
541  FHTTP_Cleanup user_cleanup = 0)
542 {
543  EReqMethod x_req_method;
544  AutoPtr<SConnNetInfo> x_net_info(net_info
545  ? ConnNetInfo_Clone(net_info)
547  if (!x_net_info) {
549  "CConn_HttpStream::CConn_HttpStream(): "
550  " Out of memory");
551  }
552  x_req_method = (EReqMethod)(method & ~eReqMethod_v1);
553  if (x_req_method == eReqMethod_Connect) {
554  NCBI_THROW(CIO_Exception, eInvalidArg,
555  "CConn_HttpStream::CConn_HttpStream(): "
556  " Bad request method (CONNECT)");
557  }
558  if (x_req_method)
559  x_net_info->req_method = method;
560  else if (method/*ANY/1.1*/)
561  x_net_info->http_version = 1;
562  if (url && !ConnNetInfo_ParseURL(x_net_info.get(), url)) {
563  NCBI_THROW(CIO_Exception, eInvalidArg,
564  "CConn_HttpStream::CConn_HttpStream(): "
565  " Bad URL \"" + string(url) + '"');
566  }
567  if (host) {
568  size_t len;
569  if ((len = *host ? strlen(host) : 0) >= sizeof(x_net_info->host)) {
570  NCBI_THROW(CIO_Exception, eInvalidArg,
571  "CConn_HttpStream::CConn_HttpStream(): "
572  " Host too long \"" + string(host) + '"');
573  }
574  memcpy(x_net_info->host, host, ++len);
575  }
576  if (port)
577  x_net_info->port = port;
578  if (path && !ConnNetInfo_SetPath(x_net_info.get(), path)) {
579  NCBI_THROW(CIO_Exception, eInvalidArg,
580  "CConn_HttpStream::CConn_HttpStream(): "
581  " Path too long \"" + string(path) + '"');
582  }
583  if (args && !ConnNetInfo_SetArgs(x_net_info.get(), args)) {
584  NCBI_THROW(CIO_Exception, eInvalidArg,
585  "CConn_HttpStream::CConn_HttpStream(): "
586  " Args too long \"" + string(args) + '"');
587  }
588  if (user_header && *user_header
589  && !ConnNetInfo_OverrideUserHeader(x_net_info.get(), user_header)) {
590  int x_dynamic = 0;
591  const char* x_message = NcbiMessagePlusError(&x_dynamic,
592  "Cannot set user header",
593  errno, 0);
594  TTempCharPtr msg_ptr(const_cast<char*> (x_message),
595  x_dynamic ? eTakeOwnership : eNoOwnership);
597  "CConn_HttpStream::CConn_HttpStream(): "
598  " " + string(msg_ptr.get()));
599  }
600  if (timeout != kDefaultTimeout)
601  x_net_info->timeout = timeout;
602  // NB: Must init these two here just in case of early CONNECTOR->destroy()
603  *user_data_ptr = user_data;
604  *user_cleanup_ptr = user_cleanup;
605  CONNECTOR c = HTTP_CreateConnectorEx(x_net_info.get(),
606  flgs,
607  x_parse_header,
608  x_data,
609  x_adjust,
610  x_cleanup);
611  return CConn_IOStream::TConnector(c);
612 }
613 
614 
616  const string& path,
617  const string& args,
618  const string& user_header,
619  unsigned short port,
620  THTTP_Flags flgs,
621  const STimeout* timeout,
622  size_t buf_size)
625  0,
626  host.c_str(),
627  port,
628  path.c_str(),
629  args.c_str(),
630  user_header.c_str(),
631  this,
632  sx_Adjust,
633  0/*x_cleanup*/,
634  sx_ParseHeader,
635  flgs,
636  timeout,
637  &m_UserData,
638  &m_UserCleanup),
639  timeout, buf_size),
640  m_UserAdjust(0), m_UserParseHeader(0)
641 {
642  return;
643 }
644 
645 
647  THTTP_Flags flgs,
648  const STimeout* timeout,
649  size_t buf_size)
652  url.c_str(),
653  0,
654  0,
655  0,
656  0,
657  0,
658  this,
659  sx_Adjust,
660  0/*x_cleanup*/,
661  sx_ParseHeader,
662  flgs,
663  timeout,
664  &m_UserData,
665  &m_UserCleanup),
666  timeout, buf_size),
667  m_UserAdjust(0), m_UserParseHeader(0)
668 {
669  return;
670 }
671 
672 
674  EReqMethod method,
675  const string& user_header,
676  THTTP_Flags flgs,
677  const STimeout* timeout,
678  size_t buf_size)
680  method,
681  url.c_str(),
682  0,
683  0,
684  0,
685  0,
686  user_header.c_str(),
687  this,
688  sx_Adjust,
689  0/*x_cleanup*/,
690  sx_ParseHeader,
691  flgs,
692  timeout,
693  &m_UserData,
694  &m_UserCleanup),
695  timeout, buf_size),
696  m_UserAdjust(0), m_UserParseHeader(0)
697 {
698  return;
699 }
700 
701 
703  const SConnNetInfo* net_info,
704  const string& user_header,
705  FHTTP_ParseHeader parse_header,
706  void* user_data,
707  FHTTP_Adjust adjust,
709  THTTP_Flags flgs,
710  const STimeout* timeout,
711  size_t buf_size)
714  url.c_str(),
715  0,
716  0,
717  0,
718  0,
719  user_header.c_str(),
720  this,
721  sx_Adjust,
722  cleanup ? sx_Cleanup : 0,
723  sx_ParseHeader,
724  flgs,
725  timeout,
726  &m_UserData,
727  &m_UserCleanup,
728  user_data,
729  cleanup),
730  timeout, buf_size),
731  m_UserAdjust(adjust), m_UserParseHeader(parse_header)
732 {
733  return;
734 }
735 
736 
738  const string& user_header,
739  FHTTP_ParseHeader parse_header,
740  void* user_data,
741  FHTTP_Adjust adjust,
743  THTTP_Flags flgs,
744  const STimeout* timeout,
745  size_t buf_size)
748  0,
749  0,
750  0,
751  0,
752  0,
753  user_header.c_str(),
754  this,
755  sx_Adjust,
756  cleanup ? sx_Cleanup : 0,
757  sx_ParseHeader,
758  flgs,
759  timeout,
760  &m_UserData,
761  &m_UserCleanup,
762  user_data,
763  cleanup),
764  timeout, buf_size),
765  m_UserAdjust(adjust), m_UserParseHeader(parse_header)
766 {
767  return;
768 }
769 
770 
772 {
773  // Explicitly destroy so that the callbacks are not used out of context.
774  x_Destroy();
775 }
776 
777 
779  void* data,
780  int code)
781 {
782  CConn_HttpStream* http = reinterpret_cast<CConn_HttpStream*>(data);
783  _ASSERT(http->m_CSb); // make sure the stream is fully constructed
784  try {
785  EHTTP_HeaderParse rv = http->m_StatusData.Parse(header);
786  if (rv != eHTTP_HeaderSuccess)
787  return rv;
788  _ASSERT(!code || code == http->m_StatusData.m_Code);
789  return http->m_UserParseHeader
790  ? http->m_UserParseHeader(header, http->m_UserData, code)
792  }
793  NCBI_CATCH_ALL("CConn_HttpStream::sx_ParseHeader()");
794  if (http->exceptions())
795  THROW1_TRACE(IOS_BASE::failure, "CConn_HttpStream::sx_ParseHeader()");
796  return eHTTP_HeaderError;
797 }
798 
799 
801  void* data,
802  unsigned int failure_count)
803 {
804  CConn_HttpStream* http = reinterpret_cast<CConn_HttpStream*>(data);
805  _ASSERT(http->m_CSb); // make sure the stream is fully constructed
806  try {
807  int retval;
808  bool modified;
809  if (failure_count == (unsigned int)(-1) && !http->m_URL.empty()) {
810  http->m_StatusData.Clear();
811  if (!ConnNetInfo_ParseURL(net_info, http->m_URL.c_str()))
812  return 0/*failure*/;
813  http->m_URL.clear();
814  modified = true;
815  } else
816  modified = false;
817  if (http->m_UserAdjust) {
818  retval = http->m_UserAdjust(net_info,
819  http->m_UserData, failure_count);
820  if (retval < 0 && modified)
821  retval = 1;
822  } else
823  retval = modified ? 1 : -1;
824  return retval;
825  }
826  NCBI_CATCH_ALL("CConn_HttpStream::sx_Adjust()");
827  if (http->exceptions())
828  THROW1_TRACE(IOS_BASE::failure, "CConn_HttpStream::sx_Adjust()");
829  return 0/*error*/;
830 }
831 
832 
834 {
835  CConn_HttpStream* http = reinterpret_cast<CConn_HttpStream*>(data);
836  try {
837  http->m_UserCleanup(http->m_UserData);
838  }
839  NCBI_CATCH_ALL("CConn_HttpStream::sx_Cleanup()");
840 }
841 
842 
844 s_ServiceConnectorBuilder(const char* service,
846  const SConnNetInfo* net_info,
847  const char* user_header,
848  const SSERVICE_Extra* extra,
849  void* x_data,
850  SSERVICE_Extra* x_extra,
851  FSERVICE_Reset x_reset,
852  FHTTP_Adjust x_adjust,
853  FSERVICE_Cleanup x_cleanup,
854  FHTTP_ParseHeader x_parse_header,
855  FSERVICE_GetNextInfo x_get_next_info,
856  const STimeout* timeout)
857 {
858  AutoPtr<SConnNetInfo> x_net_info(net_info
859  ? ConnNetInfo_Clone(net_info)
860  : ConnNetInfo_Create(service));
861  if (!x_net_info) {
863  "CConn_ServiceStream::CConn_ServiceStream(): "
864  " Out of memory");
865  }
866  if (user_header && *user_header
867  && !ConnNetInfo_OverrideUserHeader(x_net_info.get(), user_header)) {
868  int x_dynamic = 0;
869  const char* x_message = NcbiMessagePlusError(&x_dynamic,
870  "Cannot set user header",
871  errno, 0);
872  TTempCharPtr msg_ptr(const_cast<char*> (x_message),
873  x_dynamic ? eTakeOwnership : eNoOwnership);
875  "CConn_ServiceStream::CConn_ServiceStream(): "
876  " " + string(msg_ptr.get()));
877  }
878  if (timeout != kDefaultTimeout)
879  x_net_info->timeout = timeout;
880 
881  if (extra)
882  memcpy(x_extra, extra, sizeof(*x_extra));
883  else
884  memset(x_extra, 0, sizeof(*x_extra));
885  _ASSERT(x_parse_header);
886  _ASSERT(!x_reset || (extra && extra->reset));
887  _ASSERT(!x_adjust || (extra && extra->adjust));
888  _ASSERT(!x_cleanup || (extra && extra->cleanup));
889  _ASSERT(!x_get_next_info || (extra && extra->get_next_info));
890  SSERVICE_Extra xx_extra;
891  memset(&xx_extra, 0, sizeof(xx_extra));
892  xx_extra.data = x_data;
893  xx_extra.reset = x_reset;
894  xx_extra.adjust = x_adjust;
895  xx_extra.cleanup = x_cleanup;
896  xx_extra.parse_header = x_parse_header;
897  xx_extra.get_next_info = x_get_next_info;
898  xx_extra.flags = extra ? extra->flags : 0;
900  types,
901  x_net_info.get(),
902  &xx_extra);
903  return CConn_IOStream::TConnector(c);
904 }
905 
906 
909  const SConnNetInfo* net_info,
910  const SSERVICE_Extra* extra,
911  const STimeout* timeout,
912  size_t buf_size)
914  types,
915  net_info,
916  0, // user_header
917  extra,
918  this,
919  &m_Extra,
920  extra && extra->reset
921  ? sx_Reset : 0,
922  extra && extra->adjust
923  ? sx_Adjust : 0,
924  extra && extra->cleanup
925  ? sx_Cleanup : 0,
926  sx_ParseHeader,
927  extra && extra->get_next_info
928  ? sx_GetNextInfo : 0,
929  timeout),
930  timeout, buf_size,
931  types & fSERV_DelayOpen ? fConn_DelayOpen : 0)
932 {
933  return;
934 }
935 
936 
938  const string& user_header,
940  const SSERVICE_Extra* extra,
941  const STimeout* timeout,
942  size_t buf_size)
944  types,
945  0, // net_info
946  user_header.c_str(),
947  extra,
948  this,
949  &m_Extra,
950  extra && extra->reset
951  ? sx_Reset : 0,
952  extra && extra->adjust
953  ? sx_Adjust : 0,
954  extra && extra->cleanup
955  ? sx_Cleanup : 0,
956  sx_ParseHeader,
957  extra && extra->get_next_info
958  ? sx_GetNextInfo : 0,
959  timeout),
960  timeout, buf_size,
961  types & fSERV_DelayOpen ? fConn_DelayOpen : 0)
962 {
963  return;
964 }
965 
966 
968 {
969  // Explicitly destroy so that the callbacks are not used out of context.
970  x_Destroy();
971 }
972 
973 
975  void* data,
976  int code)
977 {
978  CConn_ServiceStream* svc = reinterpret_cast<CConn_ServiceStream*>(data);
979  _ASSERT(svc->m_CSb); // make sure the stream is fully constructed
980  try {
981  EHTTP_HeaderParse rv = svc->m_StatusData.Parse(header);
982  if (rv != eHTTP_HeaderSuccess)
983  return rv;
984  _ASSERT(!code || code == svc->m_StatusData.m_Code);
985  return svc->m_Extra.parse_header
986  ? svc->m_Extra.parse_header(header, svc->m_Extra.data, code)
988  }
989  NCBI_CATCH_ALL("CConn_ServiceStream::sx_ParseHeader()");
990  if (svc->exceptions())
991  THROW1_TRACE(IOS_BASE::failure, "CConn_ServiceStream::sx_ParseHeader()");
992  return eHTTP_HeaderError;
993 }
994 
995 
997  void* data,
998  unsigned int failure_count)
999 {
1000  CConn_ServiceStream* svc = reinterpret_cast<CConn_ServiceStream*>(data);
1001  try {
1002  return svc->m_Extra.adjust(net_info, svc->m_Extra.data, failure_count);
1003  }
1004  NCBI_CATCH_ALL("CConn_ServiceStream::sx_Adjust()");
1005  if (svc->exceptions())
1006  THROW1_TRACE(IOS_BASE::failure, "CConn_ServiceStream::sx_Adjust()");
1007  return 0/*error*/;
1008 }
1009 
1010 
1012  SERV_ITER iter)
1013 {
1014  CConn_ServiceStream* svc = reinterpret_cast<CConn_ServiceStream*>(data);
1015  try {
1016  return svc->m_Extra.get_next_info(svc->m_Extra.data, iter);
1017  }
1018  NCBI_CATCH_ALL("CConn_ServiceStream::sx_GetNextInfo()");
1019  if (svc->exceptions())
1020  THROW1_TRACE(IOS_BASE::failure, "CConn_ServiceStream::sx_GetNextInfo()");
1021  return 0;
1022 }
1023 
1024 
1026 {
1027  CConn_ServiceStream* svc = reinterpret_cast<CConn_ServiceStream*>(data);
1028  try {
1029  return svc->m_Extra.reset(svc->m_Extra.data);
1030  }
1031  NCBI_CATCH_ALL("CConn_ServiceStream::sx_Reset()");
1032  if (svc->exceptions())
1033  THROW1_TRACE(IOS_BASE::failure, "CConn_ServiceStream::sx_Reset()");
1034 }
1035 
1036 
1038 {
1039  CConn_ServiceStream* svc = reinterpret_cast<CConn_ServiceStream*>(data);
1040  try {
1041  svc->m_Extra.cleanup(svc->m_Extra.data);
1042  }
1043  NCBI_CATCH_ALL("CConn_ServiceStream::sx_Cleanup()");
1044 }
1045 
1046 
1049  kInfiniteTimeout/*0*/, buf_size),
1050  m_Ptr(0)
1051 {
1052  return;
1053 }
1054 
1055 
1057  EOwnership owner,
1058  size_t buf_size)
1060  owner
1061  == eTakeOwnership
1062  ? 1/*true*/
1063  : 0/*false*/)),
1064  kInfiniteTimeout/*0*/, buf_size, 0/*flags*/,
1065  0, BUF_Size(buf)),
1066  m_Ptr(0)
1067 {
1068  return;
1069 }
1070 
1071 
1073  size_t size,
1074  EOwnership owner,
1075  size_t buf_size)
1077  kInfiniteTimeout/*0*/, buf_size, 0/*flags*/,
1078  (CT_CHAR_TYPE*) ptr, size),
1079  m_Ptr(owner == eTakeOwnership ? ptr : 0)
1080 {
1081  return;
1082 }
1083 
1084 
1086 {
1087  // Explicitly call x_Destroy() to avoid using deleted m_Ptr otherwise.
1088  x_Destroy();
1089  delete[] (CT_CHAR_TYPE*) m_Ptr;
1090 }
1091 
1092 
1094 {
1095  if (!str) {
1096  NCBI_THROW(CIO_Exception, eInvalidArg,
1097  "CConn_MemoryStream::ToString(NULL) is not allowed");
1098  }
1099  CConn_Streambuf* sb = dynamic_cast<CConn_Streambuf*>(rdbuf());
1100  size_t size = sb && good() ? (size_t)(tellp() - tellg()) : 0;
1101  str->resize(size);
1102  if (sb) {
1103  // Proceed with read even with size == 0
1104  size_t s = (size_t) sb->sgetn(&(*str)[0], size);
1105 #ifdef NCBI_COMPILER_WORKSHOP
1106  if (s < 0) {
1107  s = 0; // WS6 weirdness to sometimes return -1 from sgetn() :-/
1108  } else
1109 #endif //NCBI_COMPILER_WORKSHOP
1110  _ASSERT(s == size);
1111  str->resize(s); // NB: just in case, essentially NOOP when s == size
1112  }
1113 }
1114 
1115 
1116 void CConn_MemoryStream::ToVector(vector<char>* vec)
1117 {
1118  if (!vec) {
1119  NCBI_THROW(CIO_Exception, eInvalidArg,
1120  "CConn_MemoryStream::ToVector(NULL) is not allowed");
1121  }
1122  CConn_Streambuf* sb = dynamic_cast<CConn_Streambuf*>(rdbuf());
1123  size_t size = sb && good() ? (size_t)(tellp() - tellg()) : 0;
1124  vec->resize(size);
1125  if (sb) {
1126  // Proceed with read even with size == 0
1127  size_t s = (size_t) sb->sgetn(&(*vec)[0], size);
1128 #ifdef NCBI_COMPILER_WORKSHOP
1129  if (s < 0) {
1130  s = 0; // WS6 weirdness to sometimes return -1 from sgetn() :-/
1131  } else
1132 #endif //NCBI_COMPILER_WORKSHOP
1133  _ASSERT(s == size);
1134  vec->resize(s); // NB: just in case, essentially NOOP when s == size
1135  }
1136 }
1137 
1138 
1139 // HACK * HACK * HACK
1141 {
1142  SMetaConnector* meta = !flush() ? 0 : (SMetaConnector*) GetCONN();
1143  return meta ? *((BUF*) meta->list->handle) : 0;
1144 }
1145 
1146 
1149  const vector<string>& args,
1150  CPipe::TCreateFlags flgs,
1151  size_t pipe_size,
1152  CPipe*& pipe)
1153 {
1154  unique_ptr<CPipe> p(new CPipe(pipe_size));
1155  CONNECTOR c = PIPE_CreateConnector(cmd, args, flgs, p.get(), eNoOwnership);
1156  pipe = c ? p.release() : 0;
1157  return CConn_IOStream::TConnector(c);
1158 }
1159 
1160 
1162  const vector<string>& args,
1163  CPipe::TCreateFlags flgs,
1164  size_t pipe_size,
1165  const STimeout* timeout,
1166  size_t buf_size)
1167  : CConn_IOStream(s_PipeConnectorBuilder(cmd, args, flgs, pipe_size,
1168  m_Pipe),
1169  timeout, buf_size),
1170  m_ExitCode(-1)
1171 {
1172  return;
1173 }
1174 
1175 
1177 {
1178  // Explicitly x_Destroy() to avoid using dead m_Pipe in the base class dtor
1179  x_Destroy();
1180  delete m_Pipe;
1181 }
1182 
1183 
1185 {
1186  if (!flush())
1187  return Status(eIO_Write);
1188  // NB: This can lead to wrong order for a close callback, if any fired by
1189  // CConn_IOStream::Close(): the callback will be late and actually coming
1190  // _after_ the pipe gets closed here. There's no easy way to avoid this...
1191  EIO_Status status = m_Pipe->Close(&m_ExitCode);
1192  (void) CConn_IOStream::Close();
1193  return status;
1194 }
1195 
1196 
1198  size_t pipesize,
1199  const STimeout* timeout,
1200  size_t buf_size)
1201  : CConn_IOStream(TConnector(NAMEDPIPE_CreateConnector(pipename, pipesize)),
1202  timeout, buf_size)
1203 {
1204  return;
1205 }
1206 
1207 
1209 s_FtpConnectorBuilder(const char* host,
1210  unsigned short port,
1211  const char* user,
1212  const char* pass,
1213  const char* path,
1214  const SConnNetInfo* net_info,
1215  TFTP_Flags flgs,
1216  const SFTP_Callback* cmcb,
1217  void* x_data,
1218  SFTP_Callback* x_cmcb,
1219  FFTP_Callback x_func,
1220  const STimeout* timeout)
1221 {
1222  SFTP_Callback xx_cmcb;
1223  if (cmcb) {
1224  memcpy( x_cmcb, cmcb, sizeof(*x_cmcb));
1225  memset(&xx_cmcb, 0, sizeof(xx_cmcb));
1226  xx_cmcb.data = x_data;
1227  xx_cmcb.func = x_func;
1228  x_cmcb = &xx_cmcb;
1229  } else {
1230  memset( x_cmcb, 0, sizeof(*x_cmcb));
1231  x_cmcb = 0;
1232  }
1233 
1234  CONNECTOR c;
1235  if (net_info) {
1236  if (timeout == kDefaultTimeout)
1237  timeout = net_info->timeout;
1238  const SConnNetInfo* x_net_info;
1239  if (timeout != net_info->timeout) {
1240  SConnNetInfo* xx_net_info = ConnNetInfo_Clone(net_info);
1241  if (!xx_net_info) {
1243  "CConn_FtpStream::CConn_FtpStream(): "
1244  " Out of memory");
1245  }
1246  xx_net_info->timeout = timeout;
1247  x_net_info = xx_net_info;
1248  } else
1249  x_net_info = net_info;
1250  c = FTP_CreateConnector(x_net_info, flgs, x_cmcb);
1251  if (x_net_info != net_info)
1252  ConnNetInfo_Destroy((SConnNetInfo*) x_net_info);
1253  } else {
1254  c = FTP_CreateConnectorSimple(host,
1255  port,
1256  user,
1257  pass,
1258  path,
1259  flgs,
1260  x_cmcb);
1261  }
1262  return CConn_IOStream::TConnector(c);
1263 }
1264 
1265 
1266 /* For data integrity and unambigous interpretation, FTP streams are not
1267  * buffered at the level of the C++ STL streambuf because of the way they
1268  * execute read / write operations on the mix of FTP commands and data.
1269  * There should be a little impact on performance of byte-by-byte I/O (such as
1270  * formatted input, which is not expected very often for this kind of streams,
1271  * anyways), and almost none for block I/O (such as read / readsome / write).
1272  */
1274  const string& user,
1275  const string& pass,
1276  const string& path,
1277  unsigned short port,
1278  TFTP_Flags flgs,
1279  const SFTP_Callback* cmcb,
1280  const STimeout* timeout,
1281  size_t buf_size)
1282  : CConn_IOStream(s_FtpConnectorBuilder(host.c_str(),
1283  port,
1284  user.c_str(),
1285  pass.c_str(),
1286  path.c_str(),
1287  0/*net_info*/,
1288  flgs,
1289  cmcb,
1290  this,
1291  &m_Cmcb,
1292  sx_FtpCallback,
1293  timeout),
1294  timeout, buf_size,
1295  fConn_Untie | fConn_WriteUnbuffered)
1296 {
1297  return;
1298 }
1299 
1300 
1302  TFTP_Flags flgs,
1303  const SFTP_Callback* cmcb,
1304  const STimeout* timeout,
1305  size_t buf_size)
1307  0/*port*/,
1308  0/*user*/,
1309  0/*pass*/,
1310  0/*path*/,
1311  &net_info,
1312  flgs,
1313  cmcb,
1314  this,
1315  &m_Cmcb,
1316  sx_FtpCallback,
1317  timeout),
1318  timeout, buf_size,
1319  fConn_Untie | fConn_WriteUnbuffered)
1320 {
1321  return;
1322 }
1323 
1324 
1326 {
1327  // Explicitly destroy so that the callback is not used out of context.
1328  x_Destroy();
1329 }
1330 
1331 
1333  const char* cmd,
1334  const char* arg)
1335 {
1336  CConn_FtpStream* ftp = reinterpret_cast<CConn_FtpStream*>(data);
1337  try {
1338  return ftp->m_Cmcb.func(ftp->m_Cmcb.data, cmd, arg);
1339  }
1340  NCBI_CATCH_ALL("CConn_FtpStream::sx_FtpCallback()");
1341  if (ftp->exceptions())
1342  THROW1_TRACE(IOS_BASE::failure, "CConn_FtpStream::sx_FtpCallback()");
1343  return eIO_Unknown;
1344 }
1345 
1346 
1348 {
1349  const STimeout* r_timeout = kInfiniteTimeout/*0*/;
1350  const STimeout* w_timeout = kInfiniteTimeout/*0*/;
1351  static char sink[16384]; /*NB: shared sink*/
1352  CONN conn = GetCONN();
1353  size_t n;
1354  if (conn) {
1355  r_timeout = CONN_GetTimeout(conn, eIO_Read);
1356  w_timeout = CONN_GetTimeout(conn, eIO_Write);
1358  }
1359  clear();
1360  flush();
1361  if (conn) {
1362  // Cause any upload-in-progress to abort
1363  CONN_Read(conn, sink, sizeof(sink), &n, eIO_ReadPlain);
1364  // Cause any command-in-progress to abort
1365  CONN_Write(conn, "\n", 1, &n, eIO_WritePersist);
1366  }
1367  clear();
1368  while (read(sink, sizeof(sink)))
1369  continue;
1370  if (!conn)
1371  return eIO_Closed;
1372  EIO_Status status;
1373  do {
1374  status = CONN_Read(conn, sink, sizeof(sink), &n, eIO_ReadPersist);
1375  } while (status == eIO_Success);
1376  _VERIFY(CONN_SetTimeout(conn, eIO_Read, r_timeout) == eIO_Success);
1378  clear();
1379  return status == eIO_Closed ? eIO_Success : status;
1380 }
1381 
1382 
1384  const string& file,
1385  const string& user,
1386  const string& pass,
1387  const string& path,
1388  unsigned short port,
1389  TFTP_Flags flgs,
1390  const SFTP_Callback* cmcb,
1391  Uint8 offset,
1392  const STimeout* timeout,
1393  size_t buf_size)
1394  : CConn_FtpStream(host, user, pass, path, port, flgs, cmcb,
1395  timeout, buf_size)
1396 {
1397  if (!file.empty())
1399 }
1400 
1401 
1403  TFTP_Flags flgs,
1404  const SFTP_Callback* cmcb,
1405  Uint8 offset,
1406  const STimeout* timeout,
1407  size_t buf_size)
1408  : CConn_FtpStream(net_info, flgs | fFTP_IgnorePath, cmcb,
1409  timeout, buf_size)
1410 {
1411  if (net_info.path[0])
1412  x_InitDownload(net_info.path, offset);
1413 }
1414 
1415 
1417 {
1418  // Use '\n' here instead of NcbiFlush to avoid (and thus make silent)
1419  // flush errors on retrieval of nonexistent (or bad) files / directories...
1420  EIO_Status status;
1421  if (offset) {
1422  write("REST ", 5) << NStr::UInt8ToString(offset) << '\n';
1423  status = Status(eIO_Write);
1424  } else
1425  status = eIO_Success;
1426  if (good() && status == eIO_Success) {
1427  bool directory = NStr::EndsWith(file, '/');
1428  write(directory ? "NLST " : "RETR ", 5) << file << '\n';
1429  status = Status(eIO_Write);
1430  }
1431  if (status != eIO_Success)
1432  clear(NcbiBadbit);
1433 }
1434 
1435 
1437  const string& user,
1438  const string& pass,
1439  const string& file,
1440  const string& path,
1441  unsigned short port,
1442  TFTP_Flags flgs,
1443  Uint8 offset,
1444  const STimeout* timeout)
1445  : CConn_FtpStream(host, user, pass, path, port, flgs, 0/*cmcb*/,
1446  timeout)
1447 {
1448  if (!file.empty())
1450 }
1451 
1452 
1454  TFTP_Flags flgs,
1455  Uint8 offset,
1456  const STimeout* timeout)
1457  : CConn_FtpStream(net_info, flgs | fFTP_IgnorePath, 0/*cmcb*/,
1458  timeout)
1459 {
1460  if (net_info.path[0])
1461  x_InitUpload(net_info.path, offset);
1462 }
1463 
1464 
1466 {
1467  EIO_Status status;
1468  if (offset) {
1469  write("REST ", 5) << NStr::UInt8ToString(offset) << NcbiFlush;
1470  status = Status(eIO_Write);
1471  } else
1472  status = eIO_Success;
1473  if (good() && status == eIO_Success) {
1474  write("STOR ", 5) << file << NcbiFlush;
1475  status = Status(eIO_Write);
1476  }
1477  if (status != eIO_Success)
1478  clear(NcbiBadbit);
1479 }
1480 
1481 
1482 /* non-public class */
1484 {
1485 public:
1486  CConn_FileStream(const string& ifname,
1487  const string& ofname = kEmptyStr,
1488  SFILE_ConnAttr* attr = 0)
1490  ofname.c_str(),
1491  attr)),
1492  0/*timeout*/, 0/*unbuffered*/,
1493  fConn_Untie)
1494  {
1495  return;
1496  }
1497 };
1498 
1499 
1500 static bool x_IsIdentifier(const string& str)
1501 {
1502  const char* s = str.c_str();
1503  if (!isalpha((unsigned char)(*s)))
1504  return false;
1505  for (++s; *s; ++s) {
1506  if (!isalnum((unsigned char)(*s)) && *s != '_')
1507  return false;
1508  }
1509  return true;
1510 }
1511 
1512 
1513 extern CConn_IOStream* NcbiOpenURL(const string& url, size_t buf_size)
1514 {
1515  size_t len = url.size();
1516  if (!len)
1517  return 0;
1518  {
1519  class CInPlaceConnIniter : protected CConnIniter
1520  {
1521  } conn_initer; /*NCBI_FAKE_WARNING*/
1522  }
1523  bool svc = x_IsIdentifier(url);
1524 
1525  AutoPtr<SConnNetInfo> net_info
1527  (svc
1528  ? make_c_unique(SERV_ServiceName(url.c_str())).get()
1529  : NStr::StartsWith(url, "ftp://", NStr::eNocase)
1530  ? "_FTP" : 0));
1531  if (svc)
1532  return new CConn_ServiceStream(url, fSERV_Any, net_info.get());
1533 
1534  if (net_info && !NCBI_HasSpaces(url.c_str(), len)) {
1535  unsigned int host;
1536  unsigned short port;
1537  SIZE_TYPE pos = NStr::Find(url, ":");
1538  if (0 < pos && pos < len - 1
1539  && url[pos - 1] != '/' && (pos == 1 || url[pos - 2] != '/')
1540  && CSocketAPI::StringToHostPort(url, &host, &port) == len
1541  && host && port) {
1542  net_info->req_method = eReqMethod_Connect;
1543  }
1544  }
1545 
1546  if (ConnNetInfo_ParseURL(net_info.get(), url.c_str())) {
1547  _ASSERT(net_info); // otherwise ConnNetInfo_ParseURL() would've failed
1548  if (net_info->req_method == eReqMethod_Connect) {
1549  return new CConn_SocketStream(*net_info, 0, 0, fSOCK_LogDefault,
1550  net_info->timeout, buf_size);
1551  }
1552  switch (net_info->scheme) {
1553  case eURL_Https:
1554  case eURL_Http:
1555  return new CConn_HttpStream(net_info.get(), kEmptyStr, 0, 0, 0, 0,
1557  kDefaultTimeout, buf_size);
1558  case eURL_File:
1559  if (*net_info->host || net_info->port)
1560  break; // not supported
1561  if (net_info->debug_printout) {
1562  // manual cleanup of most fields req'd
1563  net_info->req_method = eReqMethod_Any;
1564  net_info->external = 0;
1565  net_info->firewall = 0;
1566  net_info->stateless = 0;
1567  net_info->lb_disable = 0;
1568  net_info->http_version = 0;
1569  net_info->http_push_auth = 0;
1570  net_info->http_proxy_leak = 0;
1571  net_info->http_proxy_skip = 0;
1572  net_info->http_proxy_only = 0;
1573  net_info->user[0] = '\0';
1574  net_info->pass[0] = '\0';
1575  net_info->http_proxy_host[0] = '\0';
1576  net_info->http_proxy_port = 0;
1577  net_info->http_proxy_user[0] = '\0';
1578  net_info->http_proxy_pass[0] = '\0';
1579  net_info->max_try = 0;
1580  net_info->timeout = kInfiniteTimeout/*0*/;
1581  ConnNetInfo_SetUserHeader(net_info.get(), 0);
1582  if (net_info->http_referer) {
1583  free((void*) net_info->http_referer);
1584  net_info->http_referer = 0;
1585  }
1587  ConnNetInfo_Log(net_info.get(), eLOG_Note, CORE_GetLOG());
1588  CORE_UNLOCK;
1589  }
1590  return new CConn_FileStream(net_info->path);
1591  case eURL_Ftp:
1592  if (!net_info->user[0]) {
1593  strcpy(net_info->user, "ftp");
1594  if (!net_info->pass[0])
1595  strcpy(net_info->pass, "-none@");
1596  }
1597  return new CConn_FTPDownloadStream(*net_info, 0, 0, 0,
1598  net_info->timeout, buf_size);
1599  default:
1600  break;
1601  }
1602  }
1603  return 0;
1604 }
1605 
1606 
AutoPtr –.
Definition: ncbimisc.hpp:401
Helper hook-up class that installs default logging/registry/locking (but only if they have not yet be...
CConn_FtpStream specialization (ctor) for download.
CConn_FileStream(const string &ifname, const string &ofname=kEmptyStr, SFILE_ConnAttr *attr=0)
CConn_FtpStream is an elaborate FTP client, can be used for data downloading and/or uploading to and ...
Helper base class for HTTP-like streams.
This stream exchanges data with an HTTP server located at the URL: http[s]://host[:port]/path[?...
Helper class to build streams on top of CONNECTOR (internal use only).
Base class, inherited from "std::iostream", does both input and output, using the specified CONNECTOR...
This stream exchanges data with a named service, in a constraint that the service is implemented as o...
This stream exchanges data in a TCP channel, using the SOCK socket API.
EIO_Status Close(void)
EIO_Status Status(EIO_Event direction) const
EIO_Status Fetch(const STimeout *timeout)
EIO_Status Pushback(const CT_CHAR_TYPE *data, streamsize size, bool push)
Push the specified data "data" of size "size" back into the underlying connection CONN.
I/O exception.
CPipe –.
Definition: ncbi_pipe.hpp:76
CSocket::
Interface for testing cancellation request in a long lasting operation.
Definition: icanceled.hpp:51
static CS_COMMAND * cmd
Definition: ct_dynamic.c:26
static void cleanup(void)
Definition: ct_dynamic.c:30
static CS_CONNECTION * conn
Definition: ct_dynamic.c:25
static uch flags
int close(int fd)
Definition: connection.cpp:45
static void DLIST_NAME() init(DLIST_LIST_TYPE *list)
Definition: dlist.tmpl.h:40
static DLIST_TYPE *DLIST_NAME() first(DLIST_LIST_TYPE *list)
Definition: dlist.tmpl.h:46
static int type
Definition: getdata.c:31
element_type * get(void) const
Get pointer.
Definition: ncbimisc.hpp:469
unique_ptr< T, TDeleter > make_c_unique(T *p, TDeleter d)
Eliminates the necessity for specifying types of both allocated resource and deallocating C function.
Definition: ncbimisc.hpp:1448
@ eTakeOwnership
An object can take ownership of another.
Definition: ncbi_types.h:136
@ eNoOwnership
No ownership is assumed.
Definition: ncbi_types.h:135
size_t BUF_Size(BUF buf)
Definition: ncbi_buffer.c:84
CConn_MemoryStream(size_t buf_size=kConn_DefaultBufSize)
EIO_Status Fetch(const STimeout *timeout=kDefaultTimeout)
Flush the stream and fetch the response (w/o extracting any user data)
void ToVector(vector< char > *)
fill in the data, NULL is not accepted
static int sx_Adjust(SConnNetInfo *net_info, void *data, unsigned int count)
static void sx_Cleanup(void *data)
CConn_IOStream(CONN conn, bool close=false, const STimeout *timeout=kDefaultTimeout, size_t buf_size=kConn_DefaultBufSize, TConn_Flags flags=0, CT_CHAR_TYPE *ptr=0, size_t size=0)
Create a stream based on CONN, which is to be closed upon stream dtor but only if "close" parameter i...
static void sx_Cleanup(void *data)
static const SSERV_Info * sx_GetNextInfo(void *data, SERV_ITER iter)
void x_InitDownload(const string &file, Uint8 offset)
EIO_Status Wait(EIO_Event event, const STimeout *timeout=&kZeroTimeout)
Equivalent to CONN_Wait(GetCONN(), event, timeout)
virtual EIO_Status Close(void)
Close CONNection, free all internal buffers and underlying structures, and render the stream unusable...
const STimeout * GetTimeout(EIO_Event direction) const
virtual EIO_Status Drain(const STimeout *timeout=kDefaultTimeout)
Abort any command in progress, read and discard all input data, and clear stream error state when suc...
CConn_ServiceStream(const string &service, TSERV_Type types=fSERV_Any, const SConnNetInfo *net_info=0, const SSERVICE_Extra *extra=0, const STimeout *timeout=kDefaultTimeout, size_t buf_size=kConn_DefaultBufSize)
SHTTP_StatusData m_StatusData
void ToString(string *)
The CConnMemoryStream::To* methods allow to obtain unread portion of the stream into a single contain...
CConn_NamedPipeStream(const string &pipename, size_t pipesize=0, const STimeout *timeout=kDefaultTimeout, size_t buf_size=kConn_DefaultBufSize)
SFTP_Callback m_Cmcb
static const STimeout kZeroTimeout
Polling timeout with the 0.0 time in it.
static EIO_Status sx_FtpCallback(void *data, const char *cmd, const char *arg)
CConn_SocketStream(const string &host, unsigned short port, unsigned short max_try, const STimeout *timeout=kDefaultTimeout, size_t buf_size=kConn_DefaultBufSize, TConn_Flags flags=0)
Create a direct connection with host:port.
CConn_Streambuf * m_CSb
EIO_Status SetCanceledCallback(const ICanceled *canceled)
Cancellation support.
FHTTP_Adjust m_UserAdjust
static void sx_Reset(void *data)
virtual ~CConn_IOStream()
CConn_PipeStream(const string &cmd, const vector< string > &args, CPipe::TCreateFlags flags=0, size_t pipe_size=0, const STimeout *timeout=kDefaultTimeout, size_t buf_size=kConn_DefaultBufSize)
EIO_Status SetTimeout(EIO_Event direction, const STimeout *timeout) const
Set connection timeout for "direction".
string GetType(void) const
CConn_FTPDownloadStream(const string &host, const string &file=kEmptyStr, const string &user="ftp", const string &pass="-none@", const string &path=kEmptyStr, unsigned short port=0, TFTP_Flags flag=0, const SFTP_Callback *cmcb=0, Uint8 offset=0, const STimeout *timeout=kDefaultTimeout, size_t buf_size=kConn_DefaultBufSize)
EIO_Status Status(EIO_Event direction=eIO_Close) const
void x_InitUpload(const string &file, Uint8 offset)
CConn_FTPUploadStream(const string &host, const string &user, const string &pass, const string &file=kEmptyStr, const string &path=kEmptyStr, unsigned short port=0, TFTP_Flags flag=0, Uint8 offset=0, const STimeout *timeout=kDefaultTimeout)
SCONN_Callback m_CB[4]
CConn_FtpStream(const string &host, const string &user, const string &pass, const string &path=kEmptyStr, unsigned short port=0, TFTP_Flags flag=0, const SFTP_Callback *cmcb=0, const STimeout *timeout=kDefaultTimeout, size_t buf_size=kConn_DefaultBufSize)
CConn_HttpStream(const string &host, const string &path, const string &args=kEmptyStr, const string &user_header=kEmptyStr, unsigned short port=0, THTTP_Flags flags=fHTTP_AutoReconnect, const STimeout *timeout=kDefaultTimeout, size_t buf_size=kConn_DefaultBufSize)
CONN GetCONN(void) const
SOCK GetSOCK(void)
Get underlying SOCK, if available (e.g. after Fetch())
EIO_Status x_Pushback(const CT_CHAR_TYPE *data, streamsize size, bool push=false)
CConn_IOStream * NcbiOpenURL(const string &url, size_t buf_size)
Given a URL, open the data source and make it available for _reading_.
static EHTTP_HeaderParse sx_ParseHeader(const char *header, void *data, int code)
const void * m_Ptr
pointer to read memory area (if owned)
FHTTP_Cleanup m_UserCleanup
EHTTP_HeaderParse Parse(const char *header)
FHTTP_ParseHeader m_UserParseHeader
string GetDescription(void) const
CPipe * m_Pipe
Underlying pipe.
unique_ptr< CConn_Streambuf > x_CSb
static int sx_Adjust(SConnNetInfo *net_info, void *data, unsigned int count)
static EHTTP_HeaderParse sx_ParseHeader(const char *header, void *data, int code)
unsigned int TConn_Flags
bitwise OR of EConn_Flag
int m_ExitCode
Process exit code.
CConstIRef< ICanceled > m_Canceled
virtual EIO_Status Close(void)
Close CONNection, free all internal buffers and underlying structures, and render the stream unusable...
BUF GetBUF(void)
Get the underlying BUF handle (it still remains managed by the stream)
static EIO_Status sx_IsCanceled(CONN conn, TCONN_Callback type, void *data)
@ fConn_Untie
do not flush before reading
CONNECTOR MEMORY_CreateConnector(void)
CONNECTOR SOCK_CreateConnectorEx(const char *host, unsigned short port, unsigned short max_try, const void *data, size_t size, TSOCK_Flags flags)
CONNECTOR NAMEDPIPE_CreateConnector(const string &pipename, size_t pipesize=0)
Create CNamedPipe-based CONNECTOR.
CONNECTOR SERVICE_CreateConnectorEx(const char *service, TSERV_Type types, const SConnNetInfo *net_info, const SSERVICE_Extra *extra)
EIO_Status HTTP_CreateTunnel(const SConnNetInfo *net_info, THTTP_Flags flags, SOCK *sock)
Same as HTTP_CreateTunnelEx(net_info, flags, 0, 0, 0, 0, sock)
CONNECTOR PIPE_CreateConnector(const string &cmd, const vector< string > &args, CPipe::TCreateFlags flags=0, CPipe *pipe=0, EOwnership own_pipe=eTakeOwnership, size_t pipe_size=0)
Create CPipe-based CONNECTOR.
CONNECTOR FTP_CreateConnectorSimple(const char *host, unsigned short port, const char *user, const char *pass, const char *path, TFTP_Flags flag, const SFTP_Callback *cmcb)
CONNECTOR FILE_CreateConnectorEx(const char *ifname, const char *ofname, const SFILE_ConnAttr *attr)
CONNECTOR MEMORY_CreateConnectorEx(BUF buf, unsigned int own_buf)
CONNECTOR HTTP_CreateConnectorEx(const SConnNetInfo *net_info, THTTP_Flags flags, FHTTP_ParseHeader parse_header, void *user_data, FHTTP_Adjust adjust, FHTTP_Cleanup cleanup)
Create new CONNECTOR structure to hit the specified URL using HTTP with either POST / GET (or ANY) me...
CONNECTOR SOCK_CreateConnectorOnTop(SOCK sock, unsigned short own_sock)
void(* FSERVICE_Reset)(void *data)
EIO_Status CONN_Read(CONN conn, void *buf, size_t size, size_t *n_read, EIO_ReadMethod how)
unsigned int THTTP_Flags
Bitwise OR of EHTTP_Flag.
EIO_Status CONN_SetCallback(CONN conn, ECONN_Callback type, const SCONN_Callback *new_cb, SCONN_Callback *old_cb)
int(* FHTTP_Adjust)(SConnNetInfo *net_info, void *user_data, unsigned int failure_count)
unsigned int TCONN_Callback
EIO_Status CONN_Write(CONN conn, const void *buf, size_t size, size_t *n_written, EIO_WriteMethod how)
void(* FHTTP_Cleanup)(void *user_data)
FHTTP_ParseHeader parse_header
const SSERV_Info *(* FSERVICE_GetNextInfo)(void *data, SERV_ITER iter)
EIO_Status(* FFTP_Callback)(void *data, const char *cmd, const char *arg)
void * data
data to pass to the callback as its last arg
EIO_Status CONN_SetTimeout(CONN conn, EIO_Event event, const STimeout *timeout)
Specify timeout for the connection I/O, including "Connect" (aka "Open") and "Close".
CONNECTOR FTP_CreateConnector(const SConnNetInfo *info, TFTP_Flags flag, const SFTP_Callback *cmcb)
char * CONN_Description(CONN conn)
Return a human-readable description of the connection as a character '\0'-terminated string.
FSERVICE_GetNextInfo get_next_info
CONNECTOR SOCK_CreateConnector(const char *host, unsigned short port, unsigned short max_try)
EIO_Status CONN_Wait(CONN conn, EIO_Event event, const STimeout *timeout)
Block on the connection until it becomes available for either reading or writing (depending on "event...
EHTTP_HeaderParse
The extended version HTTP_CreateConnectorEx() is able to track the HTTP response chain and also chang...
void * handle
data handle of the connector
FSERVICE_Cleanup cleanup
const char * CONN_GetType(CONN conn)
Get verbal representation of connection type as a character string.
EHTTP_HeaderParse(* FHTTP_ParseHeader)(const char *http_header, void *user_data, int server_error)
EIO_Status CONN_GetSOCK(CONN conn, SOCK *sock)
Get an underlying SOCK handle for connection that is implemented as a socket.
const STimeout * CONN_GetTimeout(CONN conn, EIO_Event event)
Retrieve current timeout, return NULL(kInfiniteTimeout) if it is infinite.
FFTP_Callback func
void(* FSERVICE_Cleanup)(void *data)
CONNECTOR SOCK_CreateConnectorOnTopEx(SOCK sock, unsigned short own_sock, const char *hostport)
FSERVICE_Reset reset
unsigned int TFTP_Flags
FCONN_Callback func
function address to call on the event
@ eCONN_OnFlush
About to be flushed (NB: == eIO_ReadWrite)
@ eCONN_OnWrite
Write to CONNECTOR is about to occur.
@ eCONN_OnRead
Read from CONNECTOR is about to occur.
@ eCONN_OnOpen
Call prior to open (NB: "conn" still closed)
@ fFTP_IgnorePath
@ fHTTP_NoAutoRetry
No auto-retries allowed.
@ fHTTP_AutoReconnect
See HTTP_CreateConnectorEx()
@ eHTTP_HeaderSuccess
Parse succeeded, retain server status.
@ eHTTP_HeaderError
Parse failed, treat as a server error.
#define _VERIFY(expr)
Definition: ncbidbg.hpp:161
#define NCBI_THROW(exception_class, err_code, message)
Generic macro to throw an exception, given the exception class, error code and message string.
Definition: ncbiexpt.hpp:704
#define THROW1_TRACE(exception_class, exception_arg)
Throw trace.
Definition: ncbiexpt.hpp:417
#define NCBI_CATCH_ALL(message)
This macro is deprecated - use *_X or *_XX variant instead of it.
Definition: ncbiexpt.hpp:587
@ eUnknown
Definition: app_popup.hpp:72
void Reset(void)
Reset reference object.
Definition: ncbiobj.hpp:1439
bool NotNull(void) const THROWS_NONE
Check if pointer is not null – same effect as NotEmpty().
Definition: ncbiobj.hpp:1410
unsigned int TCreateFlags
bitwise OR of "ECreateFlag"
Definition: ncbi_pipe.hpp:111
EIO_Status Close(int *exitcode=0)
Close pipe.
Definition: ncbi_pipe.cpp:1931
uint64_t Uint8
8-byte (64-bit) unsigned integer
Definition: ncbitype.h:105
#define END_NCBI_SCOPE
End previously defined NCBI scope.
Definition: ncbistl.hpp:103
#define BEGIN_NCBI_SCOPE
Define ncbi namespace.
Definition: ncbistl.hpp:100
unsigned int TSERV_Type
Bitwise OR of ESERV_Type[Special].
Definition: ncbi_service.h:94
@ fSERV_Any
Definition: ncbi_service.h:79
@ fSERV_DelayOpen
Don't open service until use.
Definition: ncbi_service.h:83
EOwnership SetOwnership(EOwnership if_to_own)
Specify if this "CSocket" is to own the underlying "SOCK".
static SIZE_TYPE StringToHostPort(const string &str, unsigned int *host, unsigned short *port)
Return position past the end of the parsed portion, NPOS on error.
#define SOCK_Destroy(s)
Definition: ncbi_socket.h:875
EIO_Status SOCK_Close(SOCK sock)
Close the SOCK handle, and destroy all relevant internal data.
Definition: ncbi_socket.c:6855
SOCK GetSOCK(void) const
Access to the underlying "SOCK".
void Reset(SOCK sock, EOwnership if_to_own, ECopyTimeout whence)
Close the current underlying "SOCK" (if any, and if owned), and from now on use "sock" as the underly...
EIO_Status SOCK_Abort(SOCK sock)
If there is outstanding connection or output data pending, cancel it.
Definition: ncbi_socket.c:7561
unsigned int TSOCK_Flags
bitwise "OR" of ESOCK_Flags
Definition: ncbi_socket.h:503
@ eCopyTimeoutsFromSOCK
Definition: ncbi_socket.hpp:52
@ fSOCK_LogDefault
Definition: ncbi_socket.h:491
@ fSOCK_LogOn
Definition: ncbi_socket.h:490
IO_PREFIX::iostream CNcbiIostream
Portable alias for iostream.
Definition: ncbistre.hpp:152
#define NcbiFlush
Definition: ncbistre.hpp:550
#define NcbiBadbit
Definition: ncbistre.hpp:571
#define CT_CHAR_TYPE
Definition: ncbistre.hpp:729
NCBI_NS_STD::string::size_type SIZE_TYPE
Definition: ncbistr.hpp:132
#define kEmptyStr
Definition: ncbistr.hpp:123
static bool EndsWith(const CTempString str, const CTempString end, ECase use_case=eCase)
Check if a string ends with a specified suffix value.
Definition: ncbistr.hpp:5429
CTempString & assign(const char *src_str, size_type len)
Assign new values to the content of the a string.
Definition: tempstr.hpp:733
static SIZE_TYPE Find(const CTempString str, const CTempString pattern, ECase use_case=eCase, EDirection direction=eForwardSearch, SIZE_TYPE occurrence=0)
Find the pattern in the string.
Definition: ncbistr.cpp:2887
static string UIntToString(unsigned int value, TNumToStringFlags flags=0, int base=10)
Convert UInt to string.
Definition: ncbistr.hpp:5108
static bool StartsWith(const CTempString str, const CTempString start, ECase use_case=eCase)
Check if a string starts with a specified prefix value.
Definition: ncbistr.hpp:5411
static bool SplitInTwo(const CTempString str, const CTempString delim, string &str1, string &str2, TSplitFlags flags=0)
Split a string into two pieces using the specified delimiters.
Definition: ncbistr.cpp:3550
static unsigned int StringToUInt(const CTempString str, TStringToNumFlags flags=0, int base=10)
Convert string to unsigned int.
Definition: ncbistr.cpp:642
static enable_if< is_arithmetic< TNumeric >::value||is_convertible< TNumeric, Int8 >::value, string >::type NumericToString(TNumeric value, TNumToStringFlags flags=0, int base=10)
Convert numeric value to string.
Definition: ncbistr.hpp:673
static string UInt8ToString(Uint8 value, TNumToStringFlags flags=0, int base=10)
Convert UInt8 to string.
Definition: ncbistr.hpp:5167
@ fConvErr_NoThrow
Do not throw an exception on error.
Definition: ncbistr.hpp:285
@ eNocase
Case insensitive compare.
Definition: ncbistr.hpp:1206
char http_proxy_host[255+1]
unsigned short http_proxy_port
#define kInfiniteTimeout
Definition: ncbi_types.h:82
int ConnNetInfo_OverrideUserHeader(SConnNetInfo *net_info, const char *header)
const STimeout * timeout
unsigned short port
int ConnNetInfo_ParseURL(SConnNetInfo *net_info, const char *url)
int ConnNetInfo_SetArgs(SConnNetInfo *net_info, const char *args)
SConnNetInfo * ConnNetInfo_Clone(const SConnNetInfo *net_info)
LOG CORE_GetLOG(void)
Get the log handle that is to be used by the core internals (CORE LOG).
Definition: ncbi_util.c:138
EIO_Status
I/O status.
Definition: ncbi_core.h:132
unsigned http_proxy_leak
EReqMethod
int ConnNetInfo_SetUserHeader(SConnNetInfo *net_info, const char *header)
enum ENcbiOwnership EOwnership
Ownership relations between objects.
void ConnNetInfo_Log(const SConnNetInfo *net_info, ELOG_Level sev, LOG log)
NCBI_CRED credentials
SConnNetInfo * ConnNetInfo_Create(const char *service)
const char * NcbiMessagePlusError(int *dynamic, const char *message, int error, const char *descr)
Add current "error" (and maybe its description) to the message: <message>[ {error=[[<error>][,...
Definition: ncbi_util.c:335
EIO_Event
I/O event (or direction).
Definition: ncbi_core.h:118
char host[255+1]
#define kDefaultTimeout
Definition: ncbi_types.h:81
char path[4095+1]
EBDebugPrintout debug_printout
int ConnNetInfo_SetPath(SConnNetInfo *net_info, const char *path)
void ConnNetInfo_Destroy(SConnNetInfo *net_info)
unsigned http_proxy_only
@ eLOG_Note
Definition: ncbi_core.h:294
@ eURL_Ftp
@ eURL_Unspec
@ eURL_Http
@ eURL_Https
@ eURL_File
@ eIO_Interrupt
signal arrival prevented any I/O to succeed
Definition: ncbi_core.h:136
@ eIO_NotSupported
operation is not supported or is not available
Definition: ncbi_core.h:138
@ eIO_Success
everything is fine, no error occurred
Definition: ncbi_core.h:133
@ eIO_Unknown
unknown I/O error (likely fatal but can retry)
Definition: ncbi_core.h:139
@ eReqMethod_Any
@ eReqMethod_v1
@ eReqMethod_Connect
@ eDebugPrintout_Data
@ eIO_ReadPlain
read readily available data only, wait if none
Definition: ncbi_core.h:90
@ eIO_ReadPersist
read exactly as much as requested, w/waits
Definition: ncbi_core.h:91
@ eIO_WritePersist
write exactly as much as specified, w/waits
Definition: ncbi_core.h:102
@ eIO_Write
write
Definition: ncbi_core.h:121
@ eIO_ReadWrite
eIO_Read | eIO_Write (also, eCONN_OnFlush)
Definition: ncbi_core.h:122
@ eIO_Close
also serves as an error indicator in SOCK_Poll
Definition: ncbi_core.h:123
@ eIO_Read
read
Definition: ncbi_core.h:120
unsigned int
A callback function used to compare two keys in a database.
Definition: types.hpp:1210
FILE * file
char * buf
yy_size_t n
int len
static void text(MDB_val *v)
Definition: mdb_dump.c:62
list< Ts... > push
const struct ncbi::grid::netcache::search::fields::SIZE size
int NCBI_HasSpaces(const char *s, size_t n)
Return non-zero(true) if a block of memory based at "s" and of size "n" has any space characters (as ...
#define GET_CONN(sb)
static CConn_IOStream::TConnector s_ServiceConnectorBuilder(const char *service, TSERV_Type types, const SConnNetInfo *net_info, const char *user_header, const SSERVICE_Extra *extra, void *x_data, SSERVICE_Extra *x_extra, FSERVICE_Reset x_reset, FHTTP_Adjust x_adjust, FSERVICE_Cleanup x_cleanup, FHTTP_ParseHeader x_parse_header, FSERVICE_GetNextInfo x_get_next_info, const STimeout *timeout)
AutoPtr< char, CDeleter< char > > TTempCharPtr
static CConn_IOStream::TConnector s_PipeConnectorBuilder(const string &cmd, const vector< string > &args, CPipe::TCreateFlags flgs, size_t pipe_size, CPipe *&pipe)
static CConn_IOStream::TConnector s_FtpConnectorBuilder(const char *host, unsigned short port, const char *user, const char *pass, const char *path, const SConnNetInfo *net_info, TFTP_Flags flgs, const SFTP_Callback *cmcb, void *x_data, SFTP_Callback *x_cmcb, FFTP_Callback x_func, const STimeout *timeout)
static CConn_IOStream::TConnector s_HttpConnectorBuilder(const SConnNetInfo *net_info, EReqMethod method, const char *url, const char *host, unsigned short port, const char *path, const char *args, const char *user_header, void *x_data, FHTTP_Adjust x_adjust, FHTTP_Cleanup x_cleanup, FHTTP_ParseHeader x_parse_header, THTTP_Flags flgs, const STimeout *timeout, void **user_data_ptr, FHTTP_Cleanup *user_cleanup_ptr, void *user_data=0, FHTTP_Cleanup user_cleanup=0)
static SOCK s_GrabSOCK(CSocket &socket)
static CConn_IOStream::TConnector s_SocketConnectorBuilder(const string &ahost, unsigned short aport, unsigned short max_try, const void *data, size_t size, TSOCK_Flags flgs)
static bool x_IsIdentifier(const string &str)
SConnNetInfo * ConnNetInfo_CreateInternal(const char *service)
#define CORE_UNLOCK
Definition: ncbi_priv.h:273
#define CORE_LOCK_READ
Definition: ncbi_priv.h:271
char * SERV_ServiceName(const char *service)
Definition: ncbi_service.c:186
EIO_Status SOCK_CreateOnTopInternal(const void *handle, size_t handle_size, SOCK *sock, const SSOCK_Init *init, TSOCK_Flags flags)
Definition: ncbi_socket.c:6703
EIO_Status SOCK_CreateInternal(const char *host, unsigned short port, const STimeout *timeout, SOCK *sock, const SSOCK_Init *init, TSOCK_Flags flags)
Definition: ncbi_socket.c:6634
int isalpha(Uchar c)
Definition: ncbictype.hpp:61
int isspace(Uchar c)
Definition: ncbictype.hpp:69
int isalnum(Uchar c)
Definition: ncbictype.hpp:62
int isdigit(Uchar c)
Definition: ncbictype.hpp:64
#define HTTP_EOL
Definition: ncbistre.hpp:120
int offset
Definition: replacements.h:160
static const char * str(char *buf, int n)
Definition: stats.c:84
static void Delete(SConnNetInfo *net_info)
Functor template for deleting object.
Definition: ncbimisc.hpp:349
Connector specification.
Standard set of connector methods to handle a connection (corresponding connectors are also in here),...
Timeout structure.
Definition: ncbi_types.h:76
Definition: inftrees.h:24
Definition: type.c:6
static int failure
Definition: t0019.c:11
#define _ASSERT
static const struct type types[]
Definition: type.c:22
void free(voidpf ptr)
Modified on Thu Nov 30 04:52:57 2023 by modify_doxy.py rev. 669887