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 101458 2023-12-15 16:57:33Z 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
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_mask != fProxy_Http) {
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_mask = 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  string("CConn_HttpStream::CConn_HttpStream(): ")
550  + (net_info ? " Out of memory"
551  : " Unable to build connection parameters"));
552  }
553  x_req_method = (EReqMethod)(method & ~eReqMethod_v1);
554  if (x_req_method == eReqMethod_Connect) {
555  NCBI_THROW(CIO_Exception, eInvalidArg,
556  "CConn_HttpStream::CConn_HttpStream(): "
557  " Bad request method (CONNECT)");
558  }
559  if (x_req_method)
560  x_net_info->req_method = method;
561  else if (method/*ANY/1.1*/)
562  x_net_info->http_version = 1;
563  if (url && !ConnNetInfo_ParseURL(x_net_info.get(), url)) {
564  NCBI_THROW(CIO_Exception, eInvalidArg,
565  "CConn_HttpStream::CConn_HttpStream(): "
566  " Bad URL \"" + string(url) + '"');
567  }
568  if (host) {
569  size_t len;
570  if ((len = *host ? strlen(host) : 0) >= sizeof(x_net_info->host)) {
571  NCBI_THROW(CIO_Exception, eInvalidArg,
572  "CConn_HttpStream::CConn_HttpStream(): "
573  " Host too long \"" + string(host) + '"');
574  }
575  memcpy(x_net_info->host, host, ++len);
576  }
577  if (port)
578  x_net_info->port = port;
579  if (path && !ConnNetInfo_SetPath(x_net_info.get(), path)) {
580  NCBI_THROW(CIO_Exception, eInvalidArg,
581  "CConn_HttpStream::CConn_HttpStream(): "
582  " Path too long \"" + string(path) + '"');
583  }
584  if (args && !ConnNetInfo_SetArgs(x_net_info.get(), args)) {
585  NCBI_THROW(CIO_Exception, eInvalidArg,
586  "CConn_HttpStream::CConn_HttpStream(): "
587  " Args too long \"" + string(args) + '"');
588  }
589  if (user_header && *user_header
590  && !ConnNetInfo_OverrideUserHeader(x_net_info.get(), user_header)) {
591  int x_dynamic = 0;
592  const char* x_message = NcbiMessagePlusError(&x_dynamic,
593  "Cannot set user header",
594  errno, 0);
595  TTempCharPtr msg_ptr(const_cast<char*> (x_message),
596  x_dynamic ? eTakeOwnership : eNoOwnership);
598  "CConn_HttpStream::CConn_HttpStream(): "
599  " " + string(msg_ptr.get()));
600  }
601  if (timeout != kDefaultTimeout)
602  x_net_info->timeout = timeout;
603  // NB: Must init these two here just in case of early CONNECTOR->destroy()
604  *user_data_ptr = user_data;
605  *user_cleanup_ptr = user_cleanup;
606  CONNECTOR c = HTTP_CreateConnectorEx(x_net_info.get(),
607  flgs,
608  x_parse_header,
609  x_data,
610  x_adjust,
611  x_cleanup);
612  return CConn_IOStream::TConnector(c);
613 }
614 
615 
617  const string& path,
618  const string& args,
619  const string& user_header,
620  unsigned short port,
621  THTTP_Flags flgs,
622  const STimeout* timeout,
623  size_t buf_size)
626  0,
627  host.c_str(),
628  port,
629  path.c_str(),
630  args.c_str(),
631  user_header.c_str(),
632  this,
633  sx_Adjust,
634  0/*x_cleanup*/,
635  sx_ParseHeader,
636  flgs,
637  timeout,
638  &m_UserData,
639  &m_UserCleanup),
640  timeout, buf_size),
641  m_UserAdjust(0), m_UserParseHeader(0)
642 {
643  return;
644 }
645 
646 
648  THTTP_Flags flgs,
649  const STimeout* timeout,
650  size_t buf_size)
653  url.c_str(),
654  0,
655  0,
656  0,
657  0,
658  0,
659  this,
660  sx_Adjust,
661  0/*x_cleanup*/,
662  sx_ParseHeader,
663  flgs,
664  timeout,
665  &m_UserData,
666  &m_UserCleanup),
667  timeout, buf_size),
668  m_UserAdjust(0), m_UserParseHeader(0)
669 {
670  return;
671 }
672 
673 
675  EReqMethod method,
676  const string& user_header,
677  THTTP_Flags flgs,
678  const STimeout* timeout,
679  size_t buf_size)
681  method,
682  url.c_str(),
683  0,
684  0,
685  0,
686  0,
687  user_header.c_str(),
688  this,
689  sx_Adjust,
690  0/*x_cleanup*/,
691  sx_ParseHeader,
692  flgs,
693  timeout,
694  &m_UserData,
695  &m_UserCleanup),
696  timeout, buf_size),
697  m_UserAdjust(0), m_UserParseHeader(0)
698 {
699  return;
700 }
701 
702 
704  const SConnNetInfo* net_info,
705  const string& user_header,
706  FHTTP_ParseHeader parse_header,
707  void* user_data,
708  FHTTP_Adjust adjust,
710  THTTP_Flags flgs,
711  const STimeout* timeout,
712  size_t buf_size)
715  url.c_str(),
716  0,
717  0,
718  0,
719  0,
720  user_header.c_str(),
721  this,
722  sx_Adjust,
723  cleanup ? sx_Cleanup : 0,
724  sx_ParseHeader,
725  flgs,
726  timeout,
727  &m_UserData,
728  &m_UserCleanup,
729  user_data,
730  cleanup),
731  timeout, buf_size),
732  m_UserAdjust(adjust), m_UserParseHeader(parse_header)
733 {
734  return;
735 }
736 
737 
739  const string& user_header,
740  FHTTP_ParseHeader parse_header,
741  void* user_data,
742  FHTTP_Adjust adjust,
744  THTTP_Flags flgs,
745  const STimeout* timeout,
746  size_t buf_size)
749  0,
750  0,
751  0,
752  0,
753  0,
754  user_header.c_str(),
755  this,
756  sx_Adjust,
757  cleanup ? sx_Cleanup : 0,
758  sx_ParseHeader,
759  flgs,
760  timeout,
761  &m_UserData,
762  &m_UserCleanup,
763  user_data,
764  cleanup),
765  timeout, buf_size),
766  m_UserAdjust(adjust), m_UserParseHeader(parse_header)
767 {
768  return;
769 }
770 
771 
773 {
774  // Explicitly destroy so that the callbacks are not used out of context.
775  x_Destroy();
776 }
777 
778 
780  void* data,
781  int code)
782 {
783  CConn_HttpStream* http = reinterpret_cast<CConn_HttpStream*>(data);
784  _ASSERT(http->m_CSb); // make sure the stream is fully constructed
785  try {
786  EHTTP_HeaderParse rv = http->m_StatusData.Parse(header);
787  if (rv != eHTTP_HeaderSuccess)
788  return rv;
789  _ASSERT(!code || code == http->m_StatusData.m_Code);
790  return http->m_UserParseHeader
791  ? http->m_UserParseHeader(header, http->m_UserData, code)
793  }
794  NCBI_CATCH_ALL("CConn_HttpStream::sx_ParseHeader()");
795  if (http->exceptions())
796  THROW1_TRACE(IOS_BASE::failure, "CConn_HttpStream::sx_ParseHeader()");
797  return eHTTP_HeaderError;
798 }
799 
800 
802  void* data,
803  unsigned int failure_count)
804 {
805  CConn_HttpStream* http = reinterpret_cast<CConn_HttpStream*>(data);
806  _ASSERT(http->m_CSb); // make sure the stream is fully constructed
807  try {
808  int retval;
809  bool modified;
810  if (failure_count == (unsigned int)(-1) && !http->m_URL.empty()) {
811  http->m_StatusData.Clear();
812  if (!ConnNetInfo_ParseURL(net_info, http->m_URL.c_str()))
813  return 0/*failure*/;
814  http->m_URL.clear();
815  modified = true;
816  } else
817  modified = false;
818  if (http->m_UserAdjust) {
819  retval = http->m_UserAdjust(net_info,
820  http->m_UserData, failure_count);
821  if (retval < 0 && modified)
822  retval = 1;
823  } else
824  retval = modified ? 1 : -1;
825  return retval;
826  }
827  NCBI_CATCH_ALL("CConn_HttpStream::sx_Adjust()");
828  if (http->exceptions())
829  THROW1_TRACE(IOS_BASE::failure, "CConn_HttpStream::sx_Adjust()");
830  return 0/*error*/;
831 }
832 
833 
835 {
836  CConn_HttpStream* http = reinterpret_cast<CConn_HttpStream*>(data);
837  try {
838  http->m_UserCleanup(http->m_UserData);
839  }
840  NCBI_CATCH_ALL("CConn_HttpStream::sx_Cleanup()");
841 }
842 
843 
845 s_ServiceConnectorBuilder(const char* service,
847  const SConnNetInfo* net_info,
848  const char* user_header,
849  const SSERVICE_Extra* extra,
850  void* x_data,
851  SSERVICE_Extra* x_extra,
852  FSERVICE_Reset x_reset,
853  FHTTP_Adjust x_adjust,
854  FSERVICE_Cleanup x_cleanup,
855  FHTTP_ParseHeader x_parse_header,
856  FSERVICE_GetNextInfo x_get_next_info,
857  const STimeout* timeout)
858 {
859  AutoPtr<SConnNetInfo> x_net_info(net_info
860  ? ConnNetInfo_Clone(net_info)
861  : ConnNetInfo_Create(service));
862  if (!x_net_info) {
864  string("CConn_ServiceStream::CConn_ServiceStream(): ")
865  + (net_info ? " Out of memory"
866  : " Unable to build connection parameters"));
867  }
868  if (user_header && *user_header
869  && !ConnNetInfo_OverrideUserHeader(x_net_info.get(), user_header)) {
870  int x_dynamic = 0;
871  const char* x_message = NcbiMessagePlusError(&x_dynamic,
872  "Cannot set user header",
873  errno, 0);
874  TTempCharPtr msg_ptr(const_cast<char*> (x_message),
875  x_dynamic ? eTakeOwnership : eNoOwnership);
877  "CConn_ServiceStream::CConn_ServiceStream(): "
878  " " + string(msg_ptr.get()));
879  }
880  if (timeout != kDefaultTimeout)
881  x_net_info->timeout = timeout;
882 
883  if (extra)
884  memcpy(x_extra, extra, sizeof(*x_extra));
885  else
886  memset(x_extra, 0, sizeof(*x_extra));
887  _ASSERT(x_parse_header);
888  _ASSERT(!x_reset || (extra && extra->reset));
889  _ASSERT(!x_adjust || (extra && extra->adjust));
890  _ASSERT(!x_cleanup || (extra && extra->cleanup));
891  _ASSERT(!x_get_next_info || (extra && extra->get_next_info));
892  SSERVICE_Extra xx_extra;
893  memset(&xx_extra, 0, sizeof(xx_extra));
894  xx_extra.data = x_data;
895  xx_extra.reset = x_reset;
896  xx_extra.adjust = x_adjust;
897  xx_extra.cleanup = x_cleanup;
898  xx_extra.parse_header = x_parse_header;
899  xx_extra.get_next_info = x_get_next_info;
900  xx_extra.flags = extra ? extra->flags : 0;
902  types,
903  x_net_info.get(),
904  &xx_extra);
905  return CConn_IOStream::TConnector(c);
906 }
907 
908 
911  const SConnNetInfo* net_info,
912  const SSERVICE_Extra* extra,
913  const STimeout* timeout,
914  size_t buf_size)
916  types,
917  net_info,
918  0, // user_header
919  extra,
920  this,
921  &m_Extra,
922  extra && extra->reset
923  ? sx_Reset : 0,
924  extra && extra->adjust
925  ? sx_Adjust : 0,
926  extra && extra->cleanup
927  ? sx_Cleanup : 0,
928  sx_ParseHeader,
929  extra && extra->get_next_info
930  ? sx_GetNextInfo : 0,
931  timeout),
932  timeout, buf_size,
933  types & fSERV_DelayOpen ? fConn_DelayOpen : 0)
934 {
935  return;
936 }
937 
938 
940  const string& user_header,
942  const SSERVICE_Extra* extra,
943  const STimeout* timeout,
944  size_t buf_size)
946  types,
947  0, // net_info
948  user_header.c_str(),
949  extra,
950  this,
951  &m_Extra,
952  extra && extra->reset
953  ? sx_Reset : 0,
954  extra && extra->adjust
955  ? sx_Adjust : 0,
956  extra && extra->cleanup
957  ? sx_Cleanup : 0,
958  sx_ParseHeader,
959  extra && extra->get_next_info
960  ? sx_GetNextInfo : 0,
961  timeout),
962  timeout, buf_size,
963  types & fSERV_DelayOpen ? fConn_DelayOpen : 0)
964 {
965  return;
966 }
967 
968 
970 {
971  // Explicitly destroy so that the callbacks are not used out of context.
972  x_Destroy();
973 }
974 
975 
977  void* data,
978  int code)
979 {
980  CConn_ServiceStream* svc = reinterpret_cast<CConn_ServiceStream*>(data);
981  _ASSERT(svc->m_CSb); // make sure the stream is fully constructed
982  try {
983  EHTTP_HeaderParse rv = svc->m_StatusData.Parse(header);
984  if (rv != eHTTP_HeaderSuccess)
985  return rv;
986  _ASSERT(!code || code == svc->m_StatusData.m_Code);
987  return svc->m_Extra.parse_header
988  ? svc->m_Extra.parse_header(header, svc->m_Extra.data, code)
990  }
991  NCBI_CATCH_ALL("CConn_ServiceStream::sx_ParseHeader()");
992  if (svc->exceptions())
993  THROW1_TRACE(IOS_BASE::failure, "CConn_ServiceStream::sx_ParseHeader()");
994  return eHTTP_HeaderError;
995 }
996 
997 
999  void* data,
1000  unsigned int failure_count)
1001 {
1002  CConn_ServiceStream* svc = reinterpret_cast<CConn_ServiceStream*>(data);
1003  try {
1004  return svc->m_Extra.adjust(net_info, svc->m_Extra.data, failure_count);
1005  }
1006  NCBI_CATCH_ALL("CConn_ServiceStream::sx_Adjust()");
1007  if (svc->exceptions())
1008  THROW1_TRACE(IOS_BASE::failure, "CConn_ServiceStream::sx_Adjust()");
1009  return 0/*error*/;
1010 }
1011 
1012 
1014  SERV_ITER iter)
1015 {
1016  CConn_ServiceStream* svc = reinterpret_cast<CConn_ServiceStream*>(data);
1017  try {
1018  return svc->m_Extra.get_next_info(svc->m_Extra.data, iter);
1019  }
1020  NCBI_CATCH_ALL("CConn_ServiceStream::sx_GetNextInfo()");
1021  if (svc->exceptions())
1022  THROW1_TRACE(IOS_BASE::failure, "CConn_ServiceStream::sx_GetNextInfo()");
1023  return 0;
1024 }
1025 
1026 
1028 {
1029  CConn_ServiceStream* svc = reinterpret_cast<CConn_ServiceStream*>(data);
1030  try {
1031  return svc->m_Extra.reset(svc->m_Extra.data);
1032  }
1033  NCBI_CATCH_ALL("CConn_ServiceStream::sx_Reset()");
1034  if (svc->exceptions())
1035  THROW1_TRACE(IOS_BASE::failure, "CConn_ServiceStream::sx_Reset()");
1036 }
1037 
1038 
1040 {
1041  CConn_ServiceStream* svc = reinterpret_cast<CConn_ServiceStream*>(data);
1042  try {
1043  svc->m_Extra.cleanup(svc->m_Extra.data);
1044  }
1045  NCBI_CATCH_ALL("CConn_ServiceStream::sx_Cleanup()");
1046 }
1047 
1048 
1051  kInfiniteTimeout/*0*/, buf_size),
1052  m_Ptr(0)
1053 {
1054  return;
1055 }
1056 
1057 
1059  EOwnership owner,
1060  size_t buf_size)
1062  owner
1063  == eTakeOwnership
1064  ? 1/*true*/
1065  : 0/*false*/)),
1066  kInfiniteTimeout/*0*/, buf_size, 0/*flags*/,
1067  0, BUF_Size(buf)),
1068  m_Ptr(0)
1069 {
1070  return;
1071 }
1072 
1073 
1075  size_t size,
1076  EOwnership owner,
1077  size_t buf_size)
1079  kInfiniteTimeout/*0*/, buf_size, 0/*flags*/,
1080  (CT_CHAR_TYPE*) ptr, size),
1081  m_Ptr(owner == eTakeOwnership ? ptr : 0)
1082 {
1083  return;
1084 }
1085 
1086 
1088 {
1089  // Explicitly call x_Destroy() to avoid using deleted m_Ptr otherwise.
1090  x_Destroy();
1091  delete[] (CT_CHAR_TYPE*) m_Ptr;
1092 }
1093 
1094 
1096 {
1097  if (!str) {
1098  NCBI_THROW(CIO_Exception, eInvalidArg,
1099  "CConn_MemoryStream::ToString(NULL) is not allowed");
1100  }
1101  CConn_Streambuf* sb = dynamic_cast<CConn_Streambuf*>(rdbuf());
1102  size_t size = sb && good() ? (size_t)(tellp() - tellg()) : 0;
1103  str->resize(size);
1104  if (sb) {
1105  // Proceed with read even with size == 0
1106  size_t s = (size_t) sb->sgetn(&(*str)[0], size);
1107 #ifdef NCBI_COMPILER_WORKSHOP
1108  if (s < 0) {
1109  s = 0; // WS6 weirdness to sometimes return -1 from sgetn() :-/
1110  } else
1111 #endif //NCBI_COMPILER_WORKSHOP
1112  _ASSERT(s == size);
1113  str->resize(s); // NB: just in case, essentially NOOP when s == size
1114  }
1115 }
1116 
1117 
1118 void CConn_MemoryStream::ToVector(vector<char>* vec)
1119 {
1120  if (!vec) {
1121  NCBI_THROW(CIO_Exception, eInvalidArg,
1122  "CConn_MemoryStream::ToVector(NULL) is not allowed");
1123  }
1124  CConn_Streambuf* sb = dynamic_cast<CConn_Streambuf*>(rdbuf());
1125  size_t size = sb && good() ? (size_t)(tellp() - tellg()) : 0;
1126  vec->resize(size);
1127  if (sb) {
1128  // Proceed with read even with size == 0
1129  size_t s = (size_t) sb->sgetn(&(*vec)[0], size);
1130 #ifdef NCBI_COMPILER_WORKSHOP
1131  if (s < 0) {
1132  s = 0; // WS6 weirdness to sometimes return -1 from sgetn() :-/
1133  } else
1134 #endif //NCBI_COMPILER_WORKSHOP
1135  _ASSERT(s == size);
1136  vec->resize(s); // NB: just in case, essentially NOOP when s == size
1137  }
1138 }
1139 
1140 
1141 // HACK * HACK * HACK
1143 {
1144  SMetaConnector* meta = !flush() ? 0 : (SMetaConnector*) GetCONN();
1145  return meta ? *((BUF*) meta->list->handle) : 0;
1146 }
1147 
1148 
1151  const vector<string>& args,
1152  CPipe::TCreateFlags flgs,
1153  size_t pipe_size,
1154  CPipe*& pipe)
1155 {
1156  unique_ptr<CPipe> p(new CPipe(pipe_size));
1157  CONNECTOR c = PIPE_CreateConnector(cmd, args, flgs, p.get(), eNoOwnership);
1158  pipe = c ? p.release() : 0;
1159  return CConn_IOStream::TConnector(c);
1160 }
1161 
1162 
1164  const vector<string>& args,
1165  CPipe::TCreateFlags flgs,
1166  size_t pipe_size,
1167  const STimeout* timeout,
1168  size_t buf_size)
1169  : CConn_IOStream(s_PipeConnectorBuilder(cmd, args, flgs, pipe_size,
1170  m_Pipe),
1171  timeout, buf_size),
1172  m_ExitCode(-1)
1173 {
1174  return;
1175 }
1176 
1177 
1179 {
1180  // Explicitly x_Destroy() to avoid using dead m_Pipe in the base class dtor
1181  x_Destroy();
1182  delete m_Pipe;
1183 }
1184 
1185 
1187 {
1188  if (!flush())
1189  return Status(eIO_Write);
1190  // NB: This can lead to wrong order for a close callback, if any fired by
1191  // CConn_IOStream::Close(): the callback will be late and actually coming
1192  // _after_ the pipe gets closed here. There's no easy way to avoid this...
1193  EIO_Status status = m_Pipe->Close(&m_ExitCode);
1194  (void) CConn_IOStream::Close();
1195  return status;
1196 }
1197 
1198 
1200  size_t pipesize,
1201  const STimeout* timeout,
1202  size_t buf_size)
1203  : CConn_IOStream(TConnector(NAMEDPIPE_CreateConnector(pipename, pipesize)),
1204  timeout, buf_size)
1205 {
1206  return;
1207 }
1208 
1209 
1211 s_FtpConnectorBuilder(const char* host,
1212  unsigned short port,
1213  const char* user,
1214  const char* pass,
1215  const char* path,
1216  const SConnNetInfo* net_info,
1217  TFTP_Flags flgs,
1218  const SFTP_Callback* cmcb,
1219  void* x_data,
1220  SFTP_Callback* x_cmcb,
1221  FFTP_Callback x_func,
1222  const STimeout* timeout)
1223 {
1224  SFTP_Callback xx_cmcb;
1225  if (cmcb) {
1226  memcpy( x_cmcb, cmcb, sizeof(*x_cmcb));
1227  memset(&xx_cmcb, 0, sizeof(xx_cmcb));
1228  xx_cmcb.data = x_data;
1229  xx_cmcb.func = x_func;
1230  x_cmcb = &xx_cmcb;
1231  } else {
1232  memset( x_cmcb, 0, sizeof(*x_cmcb));
1233  x_cmcb = 0;
1234  }
1235 
1236  CONNECTOR c;
1237  if (net_info) {
1238  if (timeout == kDefaultTimeout)
1239  timeout = net_info->timeout;
1240  const SConnNetInfo* x_net_info;
1241  if (timeout != net_info->timeout) {
1242  SConnNetInfo* xx_net_info = ConnNetInfo_Clone(net_info);
1243  if (!xx_net_info) {
1245  "CConn_FtpStream::CConn_FtpStream(): "
1246  " Out of memory");
1247  }
1248  xx_net_info->timeout = timeout;
1249  x_net_info = xx_net_info;
1250  } else
1251  x_net_info = net_info;
1252  c = FTP_CreateConnector(x_net_info, flgs, x_cmcb);
1253  if (x_net_info != net_info)
1254  ConnNetInfo_Destroy((SConnNetInfo*) x_net_info);
1255  } else {
1256  c = FTP_CreateConnectorSimple(host,
1257  port,
1258  user,
1259  pass,
1260  path,
1261  flgs,
1262  x_cmcb);
1263  }
1264  return CConn_IOStream::TConnector(c);
1265 }
1266 
1267 
1268 /* For data integrity and unambigous interpretation, FTP streams are not
1269  * buffered at the level of the C++ STL streambuf because of the way they
1270  * execute read / write operations on the mix of FTP commands and data.
1271  * There should be a little impact on performance of byte-by-byte I/O (such as
1272  * formatted input, which is not expected very often for this kind of streams,
1273  * anyways), and almost none for block I/O (such as read / readsome / write).
1274  */
1276  const string& user,
1277  const string& pass,
1278  const string& path,
1279  unsigned short port,
1280  TFTP_Flags flgs,
1281  const SFTP_Callback* cmcb,
1282  const STimeout* timeout,
1283  size_t buf_size)
1284  : CConn_IOStream(s_FtpConnectorBuilder(host.c_str(),
1285  port,
1286  user.c_str(),
1287  pass.c_str(),
1288  path.c_str(),
1289  0/*net_info*/,
1290  flgs,
1291  cmcb,
1292  this,
1293  &m_Cmcb,
1294  sx_FtpCallback,
1295  timeout),
1296  timeout, buf_size,
1297  fConn_Untie | fConn_WriteUnbuffered)
1298 {
1299  return;
1300 }
1301 
1302 
1304  TFTP_Flags flgs,
1305  const SFTP_Callback* cmcb,
1306  const STimeout* timeout,
1307  size_t buf_size)
1309  0/*port*/,
1310  0/*user*/,
1311  0/*pass*/,
1312  0/*path*/,
1313  &net_info,
1314  flgs,
1315  cmcb,
1316  this,
1317  &m_Cmcb,
1318  sx_FtpCallback,
1319  timeout),
1320  timeout, buf_size,
1321  fConn_Untie | fConn_WriteUnbuffered)
1322 {
1323  return;
1324 }
1325 
1326 
1328 {
1329  // Explicitly destroy so that the callback is not used out of context.
1330  x_Destroy();
1331 }
1332 
1333 
1335  const char* cmd,
1336  const char* arg)
1337 {
1338  CConn_FtpStream* ftp = reinterpret_cast<CConn_FtpStream*>(data);
1339  try {
1340  return ftp->m_Cmcb.func(ftp->m_Cmcb.data, cmd, arg);
1341  }
1342  NCBI_CATCH_ALL("CConn_FtpStream::sx_FtpCallback()");
1343  if (ftp->exceptions())
1344  THROW1_TRACE(IOS_BASE::failure, "CConn_FtpStream::sx_FtpCallback()");
1345  return eIO_Unknown;
1346 }
1347 
1348 
1350 {
1351  const STimeout* r_timeout = kInfiniteTimeout/*0*/;
1352  const STimeout* w_timeout = kInfiniteTimeout/*0*/;
1353  static char sink[16384]; /*NB: shared sink*/
1354  CONN conn = GetCONN();
1355  size_t n;
1356  if (conn) {
1357  r_timeout = CONN_GetTimeout(conn, eIO_Read);
1358  w_timeout = CONN_GetTimeout(conn, eIO_Write);
1360  }
1361  clear();
1362  flush();
1363  if (conn) {
1364  // Cause any upload-in-progress to abort
1365  CONN_Read(conn, sink, sizeof(sink), &n, eIO_ReadPlain);
1366  // Cause any command-in-progress to abort
1367  CONN_Write(conn, "\n", 1, &n, eIO_WritePersist);
1368  }
1369  clear();
1370  while (read(sink, sizeof(sink)))
1371  continue;
1372  if (!conn)
1373  return eIO_Closed;
1374  EIO_Status status;
1375  do {
1376  status = CONN_Read(conn, sink, sizeof(sink), &n, eIO_ReadPersist);
1377  } while (status == eIO_Success);
1378  _VERIFY(CONN_SetTimeout(conn, eIO_Read, r_timeout) == eIO_Success);
1380  clear();
1381  return status == eIO_Closed ? eIO_Success : status;
1382 }
1383 
1384 
1386  const string& file,
1387  const string& user,
1388  const string& pass,
1389  const string& path,
1390  unsigned short port,
1391  TFTP_Flags flgs,
1392  const SFTP_Callback* cmcb,
1393  Uint8 offset,
1394  const STimeout* timeout,
1395  size_t buf_size)
1396  : CConn_FtpStream(host, user, pass, path, port, flgs, cmcb,
1397  timeout, buf_size)
1398 {
1399  if (!file.empty())
1401 }
1402 
1403 
1405  TFTP_Flags flgs,
1406  const SFTP_Callback* cmcb,
1407  Uint8 offset,
1408  const STimeout* timeout,
1409  size_t buf_size)
1410  : CConn_FtpStream(net_info, flgs | fFTP_IgnorePath, cmcb,
1411  timeout, buf_size)
1412 {
1413  if (net_info.path[0])
1414  x_InitDownload(net_info.path, offset);
1415 }
1416 
1417 
1419 {
1420  // Use '\n' here instead of NcbiFlush to avoid (and thus make silent)
1421  // flush errors on retrieval of nonexistent (or bad) files / directories...
1422  EIO_Status status;
1423  if (offset) {
1424  write("REST ", 5) << NStr::UInt8ToString(offset) << '\n';
1425  status = Status(eIO_Write);
1426  } else
1427  status = eIO_Success;
1428  if (good() && status == eIO_Success) {
1429  bool directory = NStr::EndsWith(file, '/');
1430  write(directory ? "NLST " : "RETR ", 5) << file << '\n';
1431  status = Status(eIO_Write);
1432  }
1433  if (status != eIO_Success)
1434  clear(NcbiBadbit);
1435 }
1436 
1437 
1439  const string& user,
1440  const string& pass,
1441  const string& file,
1442  const string& path,
1443  unsigned short port,
1444  TFTP_Flags flgs,
1445  Uint8 offset,
1446  const STimeout* timeout)
1447  : CConn_FtpStream(host, user, pass, path, port, flgs, 0/*cmcb*/,
1448  timeout)
1449 {
1450  if (!file.empty())
1452 }
1453 
1454 
1456  TFTP_Flags flgs,
1457  Uint8 offset,
1458  const STimeout* timeout)
1459  : CConn_FtpStream(net_info, flgs | fFTP_IgnorePath, 0/*cmcb*/,
1460  timeout)
1461 {
1462  if (net_info.path[0])
1463  x_InitUpload(net_info.path, offset);
1464 }
1465 
1466 
1468 {
1469  EIO_Status status;
1470  if (offset) {
1471  write("REST ", 5) << NStr::UInt8ToString(offset) << NcbiFlush;
1472  status = Status(eIO_Write);
1473  } else
1474  status = eIO_Success;
1475  if (good() && status == eIO_Success) {
1476  write("STOR ", 5) << file << NcbiFlush;
1477  status = Status(eIO_Write);
1478  }
1479  if (status != eIO_Success)
1480  clear(NcbiBadbit);
1481 }
1482 
1483 
1484 /* non-public class */
1486 {
1487 public:
1488  CConn_FileStream(const string& ifname,
1489  const string& ofname = kEmptyStr,
1490  SFILE_ConnAttr* attr = 0)
1492  ofname.c_str(),
1493  attr)),
1494  0/*timeout*/, 0/*unbuffered*/,
1495  fConn_Untie)
1496  {
1497  return;
1498  }
1499 };
1500 
1501 
1502 static bool x_IsIdentifier(const string& str)
1503 {
1504  const char* s = str.c_str();
1505  if (!isalpha((unsigned char)(*s)))
1506  return false;
1507  for (++s; *s; ++s) {
1508  if (!isalnum((unsigned char)(*s)) && *s != '_')
1509  return false;
1510  }
1511  return true;
1512 }
1513 
1514 
1515 extern CConn_IOStream* NcbiOpenURL(const string& url, size_t buf_size)
1516 {
1517  size_t len = url.size();
1518  if (!len)
1519  return 0;
1520  {
1521  class CInPlaceConnIniter : protected CConnIniter
1522  {
1523  } conn_initer; /*NCBI_FAKE_WARNING*/
1524  }
1525  bool svc = x_IsIdentifier(url);
1526 
1527  AutoPtr<SConnNetInfo> net_info
1529  (svc
1530  ? make_c_unique(SERV_ServiceName(url.c_str())).get()
1531  : NStr::StartsWith(url, "ftp://", NStr::eNocase)
1532  ? "_FTP" : 0));
1533  if (svc)
1534  return new CConn_ServiceStream(url, fSERV_Any, net_info.get());
1535 
1536  if (net_info && !NCBI_HasSpaces(url.c_str(), len)) {
1537  unsigned int host;
1538  unsigned short port;
1539  SIZE_TYPE pos = NStr::Find(url, ":");
1540  if (0 < pos && pos < len - 1
1541  && url[pos - 1] != '/' && (pos == 1 || url[pos - 2] != '/')
1542  && CSocketAPI::StringToHostPort(url, &host, &port) == len
1543  && host && port) {
1544  net_info->req_method = eReqMethod_Connect;
1545  }
1546  }
1547 
1548  if (ConnNetInfo_ParseURL(net_info.get(), url.c_str())) {
1549  _ASSERT(net_info); // otherwise ConnNetInfo_ParseURL() would've failed
1550  if (net_info->req_method == eReqMethod_Connect) {
1551  return new CConn_SocketStream(*net_info, 0, 0, fSOCK_LogDefault,
1552  net_info->timeout, buf_size);
1553  }
1554  switch (net_info->scheme) {
1555  case eURL_Https:
1556  case eURL_Http:
1557  return new CConn_HttpStream(net_info.get(), kEmptyStr, 0, 0, 0, 0,
1559  kDefaultTimeout, buf_size);
1560  case eURL_File:
1561  if (*net_info->host || net_info->port)
1562  break; // not supported
1563  if (net_info->debug_printout) {
1564  // manual cleanup of most fields req'd
1565  net_info->req_method = eReqMethod_Any;
1566  net_info->external = 0;
1567  net_info->firewall = 0;
1568  net_info->stateless = 0;
1569  net_info->lb_disable = 0;
1570  net_info->http_version = 0;
1571  net_info->http_push_auth = 0;
1572  net_info->http_proxy_leak = 0;
1573  net_info->http_proxy_skip = 0;
1574  net_info->http_proxy_mask = 0;
1575  net_info->user[0] = '\0';
1576  net_info->pass[0] = '\0';
1577  net_info->http_proxy_host[0] = '\0';
1578  net_info->http_proxy_port = 0;
1579  net_info->http_proxy_user[0] = '\0';
1580  net_info->http_proxy_pass[0] = '\0';
1581  net_info->max_try = 0;
1582  net_info->timeout = kInfiniteTimeout/*0*/;
1583  ConnNetInfo_SetUserHeader(net_info.get(), 0);
1584  if (net_info->http_referer) {
1585  free((void*) net_info->http_referer);
1586  net_info->http_referer = 0;
1587  }
1589  ConnNetInfo_Log(net_info.get(), eLOG_Note, CORE_GetLOG());
1590  CORE_UNLOCK;
1591  }
1592  return new CConn_FileStream(net_info->path);
1593  case eURL_Ftp:
1594  if (!net_info->user[0]) {
1595  strcpy(net_info->user, "ftp");
1596  if (!net_info->pass[0])
1597  strcpy(net_info->pass, "-none@");
1598  }
1599  return new CConn_FTPDownloadStream(*net_info, 0, 0, 0,
1600  net_info->timeout, buf_size);
1601  default:
1602  break;
1603  }
1604  }
1605  return 0;
1606 }
1607 
1608 
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 uch flags
int close(int fd)
Definition: connection.cpp:45
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 int failure
Definition: t0019.c:11
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
static const char * str(char *buf, int n)
Definition: stats.c:84
static const struct type types[]
Definition: type.c:22
int offset
Definition: replacements.h:160
char data[12]
Definition: iconv.c:80
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:1964
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:6851
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:7557
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:5430
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:2891
static string UIntToString(unsigned int value, TNumToStringFlags flags=0, int base=10)
Convert UInt to string.
Definition: ncbistr.hpp:5109
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:5412
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:3554
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:5168
@ 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)
EBProxyType http_proxy_mask
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)
@ 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
@ fProxy_Http
$http_proxy used
@ 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:6700
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:6631
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
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
#define _ASSERT
void free(voidpf ptr)
Modified on Sun Apr 21 03:38:45 2024 by modify_doxy.py rev. 669887