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

Go to the SVN repository for this file.

1 #ifndef CONNECT___NCBI_CONN_STREAM__HPP
2 #define CONNECT___NCBI_CONN_STREAM__HPP
3 
4 /* $Id: ncbi_conn_stream.hpp 102308 2024-04-19 20:49:48Z lavr $
5  * ===========================================================================
6  *
7  * PUBLIC DOMAIN NOTICE
8  * National Center for Biotechnology Information
9  *
10  * This software/database is a "United States Government Work" under the
11  * terms of the United States Copyright Act. It was written as part of
12  * the author's official duties as a United States Government employee and
13  * thus cannot be copyrighted. This software/database is freely available
14  * to the public for use. The National Library of Medicine and the U.S.
15  * Government have not placed any restriction on its use or reproduction.
16  *
17  * Although all reasonable efforts have been taken to ensure the accuracy
18  * and reliability of the software and data, the NLM and the U.S.
19  * Government do not and cannot warrant the performance or results that
20  * may be obtained by using this software or data. The NLM and the U.S.
21  * Government disclaim all warranties, express or implied, including
22  * warranties of performance, merchantability or fitness for any particular
23  * purpose.
24  *
25  * Please cite the author in any work or product based on this material.
26  *
27  * ===========================================================================
28  *
29  * Authors: Denis Vakatov, Anton Lavrentiev
30  *
31  * File Description:
32  * @file ncbi_conn_stream.hpp
33  * CONN-based C++ streams
34  *
35  * Classes:
36  * CConn_IOStream
37  * Base class derived from "std::iostream" to perform I/O by means of the
38  * underlying CConn_Streambuf, which is implemented privately in
39  * ncbi_conn_streambuf.[ch]pp
40  *
41  * CConn_SocketStream
42  * I/O stream based on a socket connector.
43  *
44  * CConn_HttpStream
45  * I/O stream based on an HTTP connector (that is, a stream that can
46  * connect to an HTTP server and exchange information using the HTTP(S)
47  * protocol).
48  *
49  * CConn_ServiceStream
50  * I/O stream based on a service connector, which is able to exchange data
51  * to/from a named service that can be found via dispatcher/load-balancing
52  * daemon, and implemented as either HTTP GCI, standalone server, or NCBID
53  * service.
54  *
55  * CConn_MemoryStream
56  * In-memory stream of data (analogous to std::str[ing]stream).
57  *
58  * CConn_PipeStream
59  * I/O stream based on a PIPE connector, which is able to exchange data
60  * with a spawned child process, specified via a command.
61  *
62  * CConn_NamedPipeStream
63  * I/O stream based on a NAMEDPIPE connector, which is able to exchange
64  * data with another process (or self) via a pipe.
65  *
66  * CConn_FtpStream
67  * I/O stream based on an FTP connector, which is able to retrieve files
68  * and file lists from remote FTP servers, as well as to upload files.
69  *
70  * CConn_FTPDownloadStream
71  * Specialization of CConn_FtpStream for a (single) file download from an
72  * FTP server.
73  *
74  * CConn_FTPUploadStream
75  * Specialization of CConn_FtpStream for a (single) file upload to an FTP
76  * server
77  *
78  * API:
79  * NcbiOpenURL()
80  * Given a URL, return CConn_IOStream that is reading from the source.
81  * Supported schemes include: file://, http[s]://, ftp://, and finally, a
82  * named NCBI service (the null scheme).
83  *
84  */
85 
92 #include <connect/ncbi_socket.hpp>
93 #include <util/icanceled.hpp>
94 #include <utility>
95 
96 
97 /** @addtogroup ConnStreams
98  *
99  * @{
100  */
101 
102 
104 
105 
106 class CConn_Streambuf; // Forward declaration
107 
108 
109 const size_t kConn_DefaultBufSize = 16384; ///< I/O buffer size per direction
110 
111 
112 
113 /////////////////////////////////////////////////////////////////////////////
114 ///
115 /// Base class, inherited from "std::iostream", does both input and output,
116 /// using the specified CONNECTOR.
117 ///
118 /// The "buf_size" parameter designates the size of the internal I/O buffers,
119 /// which reside in between the stream and an underlying connector (which in
120 /// turn may do further buffering, if needed).
121 ///
122 /// By default, all input operations are tied to the output ones, which means
123 /// that any input attempt first flushes any pending output from the internal
124 /// buffers. The fConn_Untie flag can be used to untie the I/O directions.
125 ///
126 /// @note
127 /// CConn_IOStream implementation utilizes some connection callbacks on the
128 /// underlying CONN object. Care must be taken when intercepting the
129 /// callbacks using the native CONN API.
130 /// @sa
131 /// CONN_SetCallback
132 
134  virtual protected CConnIniter
135 {
136 public:
137  /// Polling timeout with the 0.0 time in it
138  static const STimeout kZeroTimeout;
139 
140  /// The values below must be compatible with TCONN_Flags
141  enum {
142  fConn_Untie = fCONN_Untie,///< do not flush before reading
143  fConn_DelayOpen = 2, ///< do not force CONN open in ctor
144  fConn_ReadUnbuffered = 4, ///< read buffer NOT to be alloc'd
145  fConn_WriteUnbuffered = 8 ///< write buffer NOT 2.b. alloc'd
146  } EConn_Flag;
147  typedef unsigned int TConn_Flags; ///< bitwise OR of EConn_Flag
148 
149  /// Create a stream based on CONN, which is to be closed upon stream dtor
150  /// but only if "close" parameter is passed as "true".
151  ///
152  /// @param conn
153  /// A C object of type CONN (ncbi_connection.h) on top of which the
154  /// stream is being constructed. May not be NULL.
155  /// @param close
156  /// True if to close CONN automatically (otherwise CONN remains open)
157  /// @param timeout
158  /// Default I/O timeout (including to open the stream)
159  /// @param buf_size
160  /// Default size of underlying stream buffer's I/O arena (per direction)
161  /// @param flags
162  /// Specifies whether to tie input and output (a tied stream flushes all
163  /// pending output prior to doing any input) and what to buffer
164  /// @param ptr
165  /// Specifies data which will be read from the stream prior to extracting
166  /// from the actual connection (must not be modified while I/O not done)
167  /// @param size
168  /// The size of the area pointed to by the "ptr" argument
169  /// @note
170  /// On MSVC, "size" may not be generally more than 2GB-1 (the signed
171  /// 32-bit int limit)
172  /// @sa
173  /// CONN, ncbi_connection.h
174  ///
176  (CONN conn,
177  bool close = false,
178  const STimeout* timeout = kDefaultTimeout,
179  size_t buf_size = kConn_DefaultBufSize,
180  TConn_Flags flags = 0,
181  CT_CHAR_TYPE* ptr = 0,
182  size_t size = 0);
183 
184  typedef pair<CONNECTOR, EIO_Status> TConnPair;
185  /// Helper class to build streams on top of CONNECTOR (internal use only).
186  class TConnector : public TConnPair
187  {
188  public:
189  /// @param connector
190  /// A C object of type CONNECTOR (ncbi_connector.h) on top of which a
191  /// stream will be constructed. NULL CONNECTOR indicates an error
192  /// (if none is passed in the second argument, eIO_Unknown results).
193  /// @param status
194  /// I/O status to use in the underlying streambuf (e.g. when
195  /// CONNECTOR is NULL), and if non-eIO_Success will also cause a
196  /// non-NULL CONNECTOR (if any passed in the first argument) to be
197  /// destroyed.
198  /// @sa
199  /// CONNECTOR, ncbi_connector.h
201  : TConnPair(connector, status != eIO_Success ? status :
202  connector ? eIO_Success : eIO_Unknown)
203  { }
204  };
205 protected:
206  /// Create a stream based on CONNECTOR -- only for internal use in derived
207  /// classes. The passed CONNECTOR always gets closed by stream dtor.
208  ///
209  /// @param connector
210  /// CONNECTOR coupled with an error code (if any)
211  /// @param timeout
212  /// Default I/O timeout (including to open the stream)
213  /// @param buf_size
214  /// Default size of underlying stream buffer's I/O arena (per direction)
215  /// @param flags
216  /// Specifies whether to tie input and output (a tied stream flushes all
217  /// pending output prior to doing any input), and what to buffer
218  /// @param ptr
219  /// Specifies data which will be read from the stream prior to extracting
220  /// from the actual connection (must not be modified while I/O not done)
221  /// @param size
222  /// The size of the area pointed to by the "ptr" argument
223  /// @note
224  /// On MSVC, "size" may not be generally more than 2GB-1 (the signed
225  /// 32-bit int limit)
227  (const TConnector& connector,
228  const STimeout* timeout = kDefaultTimeout,
229  size_t buf_size = kConn_DefaultBufSize,
230  TConn_Flags flags = 0,
231  CT_CHAR_TYPE* ptr = 0,
232  size_t size = 0);
233 
234 public:
235  virtual ~CConn_IOStream();
236 
237  /// @return
238  /// Verbal connection type (empty if unknown)
239  /// @sa
240  /// CONN_GetType
241  string GetType(void) const;
242 
243  /// @return
244  /// Verbal connection description (empty if unknown)
245  /// @sa
246  /// CONN_Description
247  string GetDescription(void) const;
248 
249  /// Set connection timeout for "direction"
250  /// @param
251  /// Can accept a pointer to a finite timeout, or either of the special
252  /// values: kInfiniteTimeout, kDefaultTimeout
253  /// @return
254  /// eIO_Success if succeeded; other error code if failed
255  /// @sa
256  /// CONN_SetTimeout, SetReadTimeout, SetWriteTimeout
257  EIO_Status SetTimeout(EIO_Event direction,
258  const STimeout* timeout) const;
259 
260  /// @return
261  /// Connection timeout for "direction"
262  /// @return
263  /// eIO_Success if succeeded; other error code if failed
264  /// @sa
265  /// CONN_GetTimeout
266  const STimeout* GetTimeout(EIO_Event direction) const;
267 
268  /// @return
269  /// Status of the last I/O performed by the underlying CONN in the
270  /// specified "direction" (either eIO_Open, IO_Read, or eIO_Write);
271  /// if "direction" is not specified (eIO_Close), return status of the
272  /// last CONN I/O performed by the stream -- the intended use for the
273  /// latter is to obtain more detailed information in cases what a stream
274  /// operation or I/O has just failed.
275  /// @warning
276  /// This method is not a status of iostream! Neither this is the last
277  /// EIO_Status value returned by the other stream methods.
278  /// @sa
279  /// CONN_Status
280  EIO_Status Status(EIO_Event direction = eIO_Close) const;
281 
282  /// Flush the stream and fetch the response (w/o extracting any user data)
283  /// @return
284  /// eIO_Success if the operation was successful, and some input
285  /// (including none in case of EOF) will be available upon read
286  EIO_Status Fetch(const STimeout* timeout = kDefaultTimeout);
287 
288  /// Push the specified data "data" of size "size" back into the underlying
289  /// connection CONN (making it look like received yet unread data).
290  /// If there is any non-empty pending input sequence (internal read buffer)
291  /// it will be attempted to return to CONN first. Note that it can include
292  /// any initial read area ("ptr"), which could have been specified in the
293  /// ctor yet still unread, so potentially unwanted data copying may result.
294  /// @return
295  /// Any status other than eIO_Success means that nothing from "data" has
296  /// been returned to the connection
297  /// @note
298  /// Can be used to push just the pending internal input alone back into
299  /// CONN if used with a "size" of 0 ("data" is ignored then).
300  /// @sa
301  /// CONN_Pushback
302  virtual EIO_Status Pushback(const CT_CHAR_TYPE* data, streamsize size)
303  { return x_Pushback(data, size); }
304 
305  /// Get underlying SOCK, if available (e.g. after Fetch())
306  SOCK GetSOCK(void);
307 
308  /// Get CSocket, if available (else empty). The returned CSocket doesn't
309  /// own the underlying SOCK, and is valid for as long as the stream exists.
310  /// @sa
311  /// CSocket, SOCK
312  CSocket& GetSocket(void);
313 
314  /// Close CONNection, free all internal buffers and underlying structures,
315  /// and render the stream unusable for further I/O
316  /// @return
317  /// eIO_Success when closed without errors; eIO_Closed if it was already
318  /// closed; other error code if failed to close in an orderly fashion
319  /// @warning
320  /// Regardless of the return code, this method makes the stream unable to
321  /// accept any further actions and / or I/O (they all would fail).
322  /// @note
323  /// Can be used at places where reaching end-of-scope for the stream.
324  /// would be impractical
325  /// @sa
326  /// CONN_Close
327  virtual EIO_Status Close(void);
328 
329  /// Cancellation support
330  /// @note
331  /// The ICanceled implementation must be derived from CObject as its
332  /// first superclass.
333  /// @sa
334  /// ICanceled
335  EIO_Status SetCanceledCallback(const ICanceled* canceled);
336 
337  /// @return
338  /// Internal CONNection handle, which is still owned and used by the
339  /// stream (or NULL if no such handle exists)
340  /// @note
341  /// Connection can have additional flags set for I/O processing
342  /// @sa
343  /// CONN, ncbi_connection.h, CONN_GetFlags
344  CONN GetCONN(void) const;
345 
346  /// Equivalent to CONN_Wait(GetCONN(), event, timeout)
347  /// @param event
348  /// eIO_Read or eIO_Write
349  /// @param timeout
350  /// Time to wait for the event (poll if zero time specified, and return
351  /// immediately)
352  /// @return
353  /// eIO_Success if the event is available; eIO_Timeout if the time has
354  /// expired; other code to signify some error condition
355  /// @sa
356  /// CONN_Wait
357  EIO_Status Wait(EIO_Event event,
358  const STimeout* timeout = &kZeroTimeout);
359 
360 protected:
361  EIO_Status x_Pushback(const CT_CHAR_TYPE* data, streamsize size,
362  bool push = false);
363  void x_Destroy(void);
364 
365 protected:
366  // Stream buffer
368 
369 private:
370  // Resource storage
371  unique_ptr<CConn_Streambuf> x_CSb;
373 
374  // Cancellation
375  SCONN_Callback m_CB[4];
377  static EIO_Status sx_IsCanceled(CONN conn,TCONN_Callback type,void* data);
378 
379 private:
380  // Disable copy constructor and assignment
382  CConn_IOStream& operator= (const CConn_IOStream&);
383 };
384 
385 
387 public:
388  const STimeout* GetTimeout(void) const { return m_Timeout; }
389 
390 protected:
392  : m_Timeout(timeout)
393  { }
394 
395 private:
397 };
398 
399 
401 {
402 public:
404 
405 protected:
407  : CConn_IOStreamSetTimeout(timeout)
408  { }
410 };
411 
412 
414 {
415  return CConn_IOStreamSetReadTimeout(timeout);
416 }
417 
418 
419 /// Stream manipulator "is >> SetReadTimeout(timeout)"
422 {
423  if (is.good() && is.SetTimeout(eIO_Read, s.GetTimeout()) != eIO_Success)
424  is.clear(NcbiBadbit);
425  return is;
426 }
427 
428 
430 {
431 public:
433 
434 protected:
436  : CConn_IOStreamSetTimeout(timeout)
437  { }
439 };
440 
441 
443 {
444  return CConn_IOStreamSetWriteTimeout(timeout);
445 }
446 
447 
448 /// Stream manipulator "os << SetWriteTimeout(timeout)"
451 {
452  if (os.good() && os.SetTimeout(eIO_Write, s.GetTimeout()) != eIO_Success)
453  os.clear(NcbiBadbit);
454  return os;
455 }
456 
457 
459 {
461  return m_Socket;
462 }
463 
464 
465 
466 /////////////////////////////////////////////////////////////////////////////
467 ///
468 /// This stream exchanges data in a TCP channel, using the SOCK socket API.
469 /// The endpoint is specified as a "host:port" pair. The maximal number of
470 /// connection attempts is given via "max_try".
471 /// More details on that: <connect/ncbi_socket_connector.h>.
472 ///
473 /// @sa
474 /// SOCK_CreateConnector, SOCK_Create
475 ///
476 
478 {
479 public:
480  /// Create a direct connection with host:port.
481  ///
482  /// @param host
483  /// Host to connect to
484  /// @param port
485  /// ... and port number
486  /// @param max_try
487  /// Number of attempts
488  /// @param timeout
489  /// Default I/O timeout
490  /// @param buf_size
491  /// Default buffer size
492  /// @param flags
493  /// Specifies whether to tie input and output (a tied stream flushes all
494  /// pending output prior to doing any input), and what to buffer
495  /// @sa
496  /// CConn_IOStream
498  (const string& host, ///< host to connect to
499  unsigned short port, ///< ... and port number
500  unsigned short max_try, ///< number of attempts
501  const STimeout* timeout = kDefaultTimeout,
502  size_t buf_size = kConn_DefaultBufSize,
503  TConn_Flags flags = 0);
504 
505  /// Create a direct connection with "host:port" and send an initial "data"
506  /// block of the specified "size" first; the remaining communication can
507  /// proceed as usual.
508  ///
509  /// @param host
510  /// Host to connect to
511  /// @param port
512  /// ... and port number (however, see a note below)
513  /// @param data
514  /// Pointer to block of data to send once connection is ready
515  /// @param size
516  /// Size of the data block to send (or 0 if to send nothing)
517  /// @param flgs
518  /// Socket flgs (see <connect/ncbi_socket.h>)
519  /// @param max_try
520  /// Number of attempts
521  /// @param timeout
522  /// Default I/O timeout
523  /// @param buf_size
524  /// Default buffer size
525  /// @param flags
526  /// Specifies whether to tie input and output (a tied stream flushes all
527  /// pending output prior to doing any input), and what to buffer
528  /// @note As a special case, if "port" is specified as 0, then the "host"
529  /// parameter is expected to have a "host:port" string as its value.
530  /// @sa
531  /// CConn_IOStream
533  (const string& host, ///< host[:port] to connect
534  unsigned short port = 0, ///< ... and port number
535  const void* data = 0, ///< initial data block
536  size_t size = 0, ///< size of the data block
537  TSOCK_Flags flgs = fSOCK_LogDefault, ///< see ncbi_socket.h
538  unsigned short max_try = DEF_CONN_MAX_TRY, ///< number of attempts
539  const STimeout* timeout = kDefaultTimeout,
540  size_t buf_size = kConn_DefaultBufSize,
541  TConn_Flags flags = 0);
542 
543  /// This variant uses an existing socket "sock" to build a stream upon it.
544  /// The caller may retain the ownership of "sock" by passing "if_to_own" as
545  /// "eNoOwnership" to the stream constructor -- in that case, the socket
546  /// "sock" will not be closed / destroyed upon stream destruction, and can
547  /// further be used (including proper closing when no longer needed).
548  /// Otherwise, "sock" becomes invalid once the stream is closed/destroyed.
549  /// NOTE: To maintain data integrity and consistency, "sock" should not
550  /// be used elsewhere while it is also being in use by the stream.
551  /// More details: <ncbi_socket_connector.h>::SOCK_CreateConnectorOnTop().
552  ///
553  /// @param sock
554  /// Socket to build the stream on
555  /// @param if_to_own
556  /// Whether the sock object is owned (managed) by the stream at dtor
557  /// @param timeout
558  /// Default I/O timeout
559  /// @param buf_size
560  /// Default buffer size
561  /// @param flags
562  /// Specifies whether to tie input and output (a tied stream flushes all
563  /// pending output prior to doing any input), and what to buffer
564  /// @sa
565  /// CConn_IOStream, ncbi_socket.h, SOCK_CreateConnectorOnTop
567  (SOCK sock, ///< socket
568  EOwnership if_to_own, ///< whether stream to own "sock" param
569  const STimeout* timeout = kDefaultTimeout,
570  size_t buf_size = kConn_DefaultBufSize,
571  TConn_Flags flags = 0);
572 
573  /// This variant uses an existing CSocket to build a stream up on it.
574  /// NOTE: this always revokes all ownership of the "socket"'s internals
575  /// (effectively leaving the CSocket empty); CIO_Exception(eInvalidArg)
576  /// is thrown if the internal SOCK is not owned by the passed CSocket.
577  /// More details: <ncbi_socket_connector.h>::SOCK_CreateConnectorOnTop().
578  ///
579  /// @param socket
580  /// Socket to build the stream up on
581  /// @param timeout
582  /// Default I/O timeout
583  /// @param buf_size
584  /// Default buffer size
585  /// @param flags
586  /// Specifies whether to tie input and output (a tied stream flushes all
587  /// pending output prior to doing any input), and what to buffer
588  /// @sa
589  /// CConn_IOStream, ncbi_socket.hpp, SOCK_CreateConnectorOnTop
591  (CSocket& socket, ///< socket, underlying SOCK always grabbed
592  const STimeout* timeout = kDefaultTimeout,
593  size_t buf_size = kConn_DefaultBufSize,
594  TConn_Flags flags = 0);
595 
596  /// Create a tunneled socket stream connection.
597  ///
598  /// The following fields of SConnNetInfo are used (other ignored):
599  ///
600  /// scheme -- must be http or unspecified, checked
601  /// host:port -- target server
602  /// http_proxy_host:http_proxy_port -- HTTP proxy server to tunnel thru
603  /// http_proxy_user:http_proxy_pass -- credentials for the proxy, if needed
604  /// http_proxy_leak -- ignore bad proxy and connect direct
605  /// timeout -- timeout to connect to HTTP proxy
606  /// firewall -- if true then look at proxy_server
607  /// proxy_server -- use as "host" if non-empty and FW
608  /// debug_printout -- how to log socket data by default
609  /// http_push_auth -- whether to push credentials at once
610  ///
611  /// @param net_info
612  /// Connection point and proxy tunnel location
613  /// @param data
614  /// Pointer to block of data to send once connection is ready
615  /// @param size
616  /// Size of the data block to send (or 0 if to send nothing)
617  /// @param flgs
618  /// Socket flags (see <connect/ncbi_socket.h>)
619  /// @param timeout
620  /// Default I/O timeout
621  /// @param buf_size
622  /// Default buffer size
623  /// @param flags
624  /// Specifies whether to tie input and output (a tied stream flushes all
625  /// pending output prior to doing any input), and what to buffer
626  /// @sa
627  /// CConn_IOStream, SConnNetInfo
629  (const SConnNetInfo& net_info,
630  const void* data = 0,
631  size_t size = 0,
633  const STimeout* timeout = kDefaultTimeout,
634  size_t buf_size = kConn_DefaultBufSize,
635  TConn_Flags flags = 0);
636 };
637 
638 
639 
640 /// Helper class to fetch HTTP status code and text
642  int m_Code;
644  string m_Header;
645 
647  : m_Code(0)
648  { }
649 
650  EHTTP_HeaderParse Parse(const char* header);
651 
652  void Clear(void)
653  { m_Code = 0; m_Text.clear(); m_Header.clear(); }
654 
655 private:
656  // Disable copy constructor and assignment
659 };
660 
661 
662 /// Helper base class for HTTP-like streams
664 {
665 public:
666  /// Get the last seen HTTP status code, if available
667  int GetStatusCode(void) const {return m_StatusData.m_Code; }
668 
669  /// Get the last seen HTTP status text, if available
670  const CTempString GetStatusText(void) const {return m_StatusData.m_Text; }
671 
672  /// Get the last seen HTTP header text, if available
673  const string& GetHTTPHeader(void) const {return m_StatusData.m_Header;}
674 
675 protected:
676  /// @sa
677  /// CConn_IOStream
679  (const TConnector& connector,
680  const STimeout* timeout,
681  size_t buf_size,
682  TConn_Flags flags = 0)
683  : CConn_IOStream(connector, timeout, buf_size, flags)
684  { }
685 
686 protected:
687  // HTTP status code & text seen last
689 };
690 
691 
692 /////////////////////////////////////////////////////////////////////////////
693 ///
694 /// This stream exchanges data with an HTTP server located at the URL:
695 /// http[s]://host[:port]/path[?args]
696 ///
697 /// Note that "path" must include the leading slash, "args" can be empty, in
698 /// which case the '?' does not get appended to the path.
699 ///
700 /// "User_header" (if not empty) should be a sequence of lines in the form
701 /// 'HTTP-tag: Tag value', with each line separated by a CR LF sequence, and
702 /// the last line optionally terminated with a CR LF sequence. For example:
703 /// "Content-Encoding: gzip\r\nContent-Type: application/octet-stream"
704 /// It is included in the HTTP-header of each transaction.
705 ///
706 /// More elaborate specification(s) of the server can be made via the
707 /// SConnNetInfo structure, which otherwise will be created with the use of a
708 /// standard registry section to obtain default values from (details:
709 /// <connect/ncbi_connutil.h>). To make sure the actual user header is empty,
710 /// remember to reset it with ConnNetInfo_SetUserHeader(net_info, 0).
711 ///
712 /// THTTP_Flags and other details: <connect/ncbi_http_connector.h>.
713 ///
714 /// Provided "timeout" is set at the connection level, and if different from
715 /// kDefaultTimeout, it overrides a value supplied by the HTTP connector (the
716 /// latter value is kept at SConnNetInfo::timeout).
717 ///
718 /// @sa
719 /// CConn_IOStream, HTTP_CreateConnector, ConnNetInfo_Create
720 ///
721 
723 {
724 public:
726  (const string& host,
727  const string& path,
728  const string& args = kEmptyStr,
729  const string& user_header = kEmptyStr,
730  unsigned short port = 0, ///< default(e.g. 80=HTTP/443=HTTPS)
732  const STimeout* timeout = kDefaultTimeout,
733  size_t buf_size = kConn_DefaultBufSize
734  );
735 
737  (const string& url,
739  const STimeout* timeout = kDefaultTimeout,
740  size_t buf_size = kConn_DefaultBufSize
741  );
742 
744  (const string& url,
745  EReqMethod method,
746  const string& user_header = kEmptyStr,
748  const STimeout* timeout = kDefaultTimeout,
749  size_t buf_size = kConn_DefaultBufSize
750  );
751 
753  (const string& url,
754  const SConnNetInfo* net_info,
755  const string& user_header = kEmptyStr,
756  FHTTP_ParseHeader parse_header = 0,
757  void* user_data = 0,
758  FHTTP_Adjust adjust = 0,
761  const STimeout* timeout = kDefaultTimeout,
762  size_t buf_size = kConn_DefaultBufSize
763  );
764 
766  (const SConnNetInfo* net_info = 0,
767  const string& user_header = kEmptyStr,
768  FHTTP_ParseHeader parse_header = 0,
769  void* user_data = 0,
770  FHTTP_Adjust adjust = 0,
773  const STimeout* timeout = kDefaultTimeout,
774  size_t buf_size = kConn_DefaultBufSize
775  );
776 
777  virtual ~CConn_HttpStream();
778 
779  /// Set new URL to hit next
780  void SetURL(const string& url) { m_URL = url; }
781 
782 protected:
783  // Chained callbacks and data
784  void* m_UserData;
788 
789  // URL to hit next
790  string m_URL;
791 
792 private:
793  // Callback interceptors
794  static int/*bool*/ sx_Adjust (SConnNetInfo* net_info,
795  void* data,
796  unsigned int count);
797  static void sx_Cleanup (void* data);
798  static EHTTP_HeaderParse sx_ParseHeader(const char* header,
799  void* data,
800  int code);
801 };
802 
803 
804 
805 /////////////////////////////////////////////////////////////////////////////
806 ///
807 /// This stream exchanges data with a named service, in a constraint that the
808 /// service is implemented as one of the specified server "types"
809 /// (details: <connect/ncbi_server_info.h>).
810 ///
811 /// Additional specifications can be passed in an SConnNetInfo structure,
812 /// otherwise created by using the service name as a registry section to obtain
813 /// the information from (details: <connect/ncbi_connutil.h>).
814 ///
815 /// In case when the service is implemented over underlying HTTP (which is NOT
816 /// generally guaranteed), the HTTP status data become available.
817 ///
818 /// Provided "timeout" is set at the connection level, and if different from
819 /// kDefaultTimeout, it overrides the value supplied by an underlying connector
820 /// (the latter value is kept in SConnNetInfo::timeout).
821 ///
822 /// @sa
823 /// SERVICE_CreateConnector
824 ///
825 
827 {
828 public:
830  (const string& service,
832  const SConnNetInfo* net_info = 0,
833  const SSERVICE_Extra* extra = 0,
834  const STimeout* timeout = kDefaultTimeout,
835  size_t buf_size = kConn_DefaultBufSize);
836 
838  (const string& service,
839  const string& user_header,
841  const SSERVICE_Extra* extra = 0,
842  const STimeout* timeout = kDefaultTimeout,
843  size_t buf_size = kConn_DefaultBufSize);
844 
845  virtual ~CConn_ServiceStream();
846 
847 protected:
848  // Chained callbacks and data
850 
851 private:
852  // Callback interceptors
853  static void sx_Reset (void* data);
854  static int/*bool*/ sx_Adjust (SConnNetInfo* net_info,
855  void* data,
856  unsigned int count);
857  static void sx_Cleanup (void* data);
858  static EHTTP_HeaderParse sx_ParseHeader(const char* header,
859  void* data,
860  int code);
861  static const SSERV_Info* sx_GetNextInfo(void* data,
862  SERV_ITER iter);
863 };
864 
865 
866 
867 /////////////////////////////////////////////////////////////////////////////
868 ///
869 /// In-memory stream (a la strstream or stringstream)
870 ///
871 /// @sa
872 /// MEMORY_CreateConnector
873 ///
874 
876 {
877 public:
878  CConn_MemoryStream(size_t buf_size = kConn_DefaultBufSize);
879 
880  /// Build a stream on top of an NCBI buffer (which in turn
881  /// could have been built over a memory area of a specified size).
882  /// BUF's ownership is assumed by the stream as specified in "owner".
884  EOwnership owner = eTakeOwnership,
885  size_t buf_size = kConn_DefaultBufSize);
886 
887  /// Build a stream on top of an existing data area of a specified size.
888  /// The contents of the area are what will be read first from the stream.
889  /// Writing to the stream will _not_ modify the contents of the area.
890  /// When read from the stream, the written data will appear following the
891  /// initial data block.
892  /// Ownership of the area pointed to by "ptr" is controlled by the "owner"
893  /// parameter, and if the ownership is passed to the stream the area will
894  /// be deleted by "delete[] (char*)" from the stream destructor. That is,
895  /// if there are any requirements to be considered for deleting the area
896  /// (like deleting an object or an array of objects), then the ownership
897  /// must not be passed to the stream.
898  /// Note that the area pointed to by "ptr" should not be changed while it
899  /// is still holding the data yet to be read from the stream.
900  /// @note
901  /// On MSVC, "size" may not be generally more than 2GB-1 (the signed
902  /// 32-bit int limit); so if a larger area needs to be converted to a
903  /// stream, then a BUF over the area needs to be built first, and then
904  /// passed to the first version of the stream constructor.
905  CConn_MemoryStream(const void* ptr,
906  size_t size,
907  EOwnership owner/**no default for safety*/,
908  size_t buf_size = kConn_DefaultBufSize);
909 
910  virtual ~CConn_MemoryStream();
911 
912  virtual EIO_Status Pushback(const CT_CHAR_TYPE* data, streamsize size)
913  { return x_Pushback(data, size, true); }
914 
915  /// The CConnMemoryStream::To* methods allow to obtain unread portion of
916  /// the stream into a single container (as a string or a vector) so that
917  /// all data is kept in sequential memory locations.
918  /// Note that the operation is considered an extraction, so it effectively
919  /// empties the stream, and both methods actually move the data from the
920  /// stream to the respective containers.
921  void ToString(string*); ///< fill in the data, NULL is not accepted
922  void ToVector(vector<char>*);///< fill in the data, NULL is not accepted
923 
924  /// Get the underlying BUF handle (it still remains managed by the stream)
925  /// @note
926  /// Causes the stream to flush().
927  BUF GetBUF(void);
928 
929 protected:
930  const void* m_Ptr; ///< pointer to read memory area (if owned)
931 };
932 
933 
934 
935 /////////////////////////////////////////////////////////////////////////////
936 ///
937 /// CConn_PipeStream for command piping
938 ///
939 /// @note
940 /// Exercise caution when operating on the underlying pipe while it's being
941 /// in use by the stream as that may cause some unpredictable behavior.
942 ///
943 /// Provided "timeout" is set at the connection level if different from
944 /// kDefaultTimeout (which is infinite for this class by default).
945 ///
946 /// @sa
947 /// PIPE_CreateConnector, CPipe::ECreateFlag, CPipe
948 ///
949 
951 {
952 public:
954  (const string& cmd,
955  const vector<string>& args,
957  size_t pipe_size = 0,
958  const STimeout* timeout = kDefaultTimeout,
959  size_t buf_size = kConn_DefaultBufSize
960  );
961  virtual ~CConn_PipeStream();
962 
963  virtual EIO_Status Close(void);
964 
965  /// A valid exit code is only made available after an explicit Close()
966  /// @sa
967  /// CProcess::CExitInfo
968  int GetExitCode(void) const { return m_ExitCode; }
969 
970  /// Return an underlying CPipe; it's valid for as long as the stream exists
971  /// @sa
972  /// CPipe
973  CPipe& GetPipe(void) { return *m_Pipe; }
974 
975 protected:
976  CPipe* m_Pipe; ///< Underlying pipe.
977  int m_ExitCode; ///< Process exit code.
978 };
979 
980 
981 
982 /////////////////////////////////////////////////////////////////////////////
983 ///
984 /// CConn_NamedPipeStream for inter-process communication
985 ///
986 /// Provided "timeout" is set at the connection level if different from
987 /// kDefaultTimeout (which is infinite for this class by default).
988 ///
989 /// @sa
990 /// NAMEDPIPE_CreateConnector, CNamedPipe
991 ///
992 
994 {
995 public:
997  (const string& pipename,
998  size_t pipesize = 0/*default*/,
999  const STimeout* timeout = kDefaultTimeout,
1000  size_t buf_size = kConn_DefaultBufSize
1001  );
1002 };
1003 
1004 
1005 
1006 /////////////////////////////////////////////////////////////////////////////
1007 ///
1008 /// CConn_FtpStream is an elaborate FTP client, can be used for data
1009 /// downloading and/or uploading to and from an FTP server.
1010 /// See <connect/ncbi_ftp_connector.h> for detailed explanations
1011 /// of supported features.
1012 ///
1013 /// Provided "timeout" is set at the connection level, and if different from
1014 /// kDefaultTimeout, it overrides a value supplied by the FTP connector
1015 /// (the latter value is kept at SConnNetInfo::timeout).
1016 ///
1017 /// @sa
1018 /// FTP_CreateConnector
1019 ///
1020 
1022 {
1023 public:
1025  (const string& host,
1026  const string& user,
1027  const string& pass,
1028  const string& path = kEmptyStr,
1029  unsigned short port = 0,
1030  TFTP_Flags flag = 0,
1031  const SFTP_Callback* cmcb = 0,
1032  const STimeout* timeout = kDefaultTimeout,
1033  size_t buf_size = kConn_DefaultBufSize
1034  );
1035 
1037  (const SConnNetInfo& net_info,
1038  TFTP_Flags flag = 0,
1039  const SFTP_Callback* cmcb = 0,
1040  const STimeout* timeout = kDefaultTimeout,
1041  size_t buf_size = kConn_DefaultBufSize
1042  );
1043 
1044  virtual ~CConn_FtpStream();
1045 
1046  /// Abort any command in progress, read and discard all input data, and
1047  /// clear stream error state when successful (eIO_Success returns)
1048  /// @note
1049  /// The call empties out both the stream and the underlying CONN.
1050  virtual EIO_Status Drain(const STimeout* timeout = kDefaultTimeout);
1051 
1052 protected:
1053  // Chained callback and data
1055 
1056 private:
1057  // Callback interceptor
1058  static EIO_Status sx_FtpCallback(void* data,
1059  const char* cmd,
1060  const char* arg);
1061 };
1062 
1063 
1064 /// CConn_FtpStream specialization (ctor) for download
1065 ///
1066 /// @warning
1067 /// Pay attention to the order of parameters vs generic CConn_FtpStream ctor.
1068 ///
1070 {
1071 public:
1073  (const string& host,
1074  const string& file = kEmptyStr,
1075  const string& user = "ftp",
1076  const string& pass = "-none@", // "-" helps make login quieter
1077  const string& path = kEmptyStr,
1078  unsigned short port = 0, ///< 0 means default (21 for FTP)
1079  TFTP_Flags flag = 0,
1080  const SFTP_Callback* cmcb = 0,
1081  Uint8 offset = 0, ///< file offset to begin download at
1082  const STimeout* timeout = kDefaultTimeout,
1083  size_t buf_size = kConn_DefaultBufSize
1084  );
1085 
1087  (const SConnNetInfo& net_info,
1088  TFTP_Flags flag = 0,
1089  const SFTP_Callback* cmcb = 0,
1090  Uint8 offset = 0, ///< file offset to begin download at
1091  const STimeout* timeout = kDefaultTimeout,
1092  size_t buf_size = kConn_DefaultBufSize
1093  );
1094 
1095 protected:
1096  void x_InitDownload(const string& file, Uint8 offset);
1097 };
1098 
1099 
1100 /// CConn_FtpStream specialization (ctor) for upload
1101 ///
1103 {
1104 public:
1106  (const string& host,
1107  const string& user,
1108  const string& pass,
1109  const string& file = kEmptyStr,
1110  const string& path = kEmptyStr,
1111  unsigned short port = 0, ///< 0 means default (21 for FTP)
1112  TFTP_Flags flag = 0,
1113  Uint8 offset = 0, ///< file offset to start upload at
1114  const STimeout* timeout = kDefaultTimeout
1115  );
1116 
1118  (const SConnNetInfo& net_info,
1119  TFTP_Flags flag = 0,
1120  Uint8 offset = 0, ///< file offset to start upload at
1121  const STimeout* timeout = kDefaultTimeout
1122  );
1123 
1124 protected:
1125  void x_InitUpload(const string& file, Uint8 offset);
1126 };
1127 
1128 
1129 
1130 /////////////////////////////////////////////////////////////////////////////
1131 ///
1132 /// Given a URL, open the data source and make it available for _reading_.
1133 /// See <connect/ncbi_connutil.h> for supported schemes.
1134 ///
1135 /// If "url" looks like an identifier (no scheme provided), then it will be
1136 /// opened as a named NCBI service (using CConn_ServiceStream); if the "url"
1137 /// looks like a string in the form "host:port", a socket to that host and port
1138 /// will be connected (using CConn_SocketStream); otherwise, a stream will be
1139 /// created according to the URL scheme (recognized are: "ftp://", "http://",
1140 /// "https://", and "file://").
1141 ///
1142 /// @warning
1143 /// Writing to the resultant stream is undefined, unless it's either a
1144 /// service or a socket stream.
1145 ///
1146 extern NCBI_XCONNECT_EXPORT
1147 CConn_IOStream* NcbiOpenURL(const string& url,
1148  size_t buf_size = kConn_DefaultBufSize);
1149 
1150 
1152 
1153 
1154 /* @} */
1155 
1156 #endif /* CONNECT___NCBI_CONN_STREAM__HPP */
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_FtpStream specialization (ctor) for upload.
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[?...
const STimeout * GetTimeout(void) const
const STimeout * GetTimeout(void) const
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...
In-memory stream (a la strstream or stringstream)
CConn_NamedPipeStream for inter-process communication.
CConn_PipeStream for command piping.
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.
CPipe –.
Definition: ncbi_pipe.hpp:76
CSocket::
CTempString implements a light-weight string on top of a storage buffer whose lifetime management is ...
Definition: tempstr.hpp:65
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 const struct type types[]
Definition: type.c:22
int offset
Definition: replacements.h:160
char data[12]
Definition: iconv.c:80
@ eTakeOwnership
An object can take ownership of another.
Definition: ncbi_types.h:136
@ eNoOwnership
No ownership is assumed.
Definition: ncbi_types.h:135
int GetStatusCode(void) const
Get the last seen HTTP status code, if available.
CConn_IOStream & operator<<(CConn_IOStream &os, const CConn_IOStreamSetWriteTimeout &s)
Stream manipulator "os << SetWriteTimeout(timeout)".
SHTTP_StatusData m_StatusData
CConn_IOStreamSetReadTimeout(const STimeout *timeout)
SFTP_Callback m_Cmcb
CConn_IOStreamSetWriteTimeout SetWriteTimeout(const STimeout *timeout)
static const STimeout kZeroTimeout
Polling timeout with the 0.0 time in it.
const CTempString GetStatusText(void) const
Get the last seen HTTP status text, if available.
TConnector(CONNECTOR connector, EIO_Status status=eIO_Success)
CConn_Streambuf * m_CSb
SHTTP_StatusData(const SHTTP_StatusData &)
FHTTP_Adjust m_UserAdjust
const STimeout * GetTimeout(void) const
CConn_IOStream(const CConn_IOStream &)
virtual EIO_Status Pushback(const CT_CHAR_TYPE *data, streamsize size)
Push the specified data "data" of size "size" back into the underlying connection CONN (making it loo...
EIO_Status SetTimeout(EIO_Event direction, const STimeout *timeout) const
Set connection timeout for "direction".
pair< CONNECTOR, EIO_Status > TConnPair
friend CConn_IOStreamSetReadTimeout SetReadTimeout(const STimeout *)
CConn_IOStreamSetTimeout(const STimeout *timeout)
CConn_IOStream & operator>>(CConn_IOStream &is, const CConn_IOStreamSetReadTimeout &s)
Stream manipulator "is >> SetReadTimeout(timeout)".
friend CConn_IOStreamSetWriteTimeout SetWriteTimeout(const STimeout *)
const string & GetHTTPHeader(void) const
Get the last seen HTTP header text, if available.
SHTTP_StatusData & operator=(const SHTTP_StatusData &)
CConn_IOStreamSetReadTimeout SetReadTimeout(const STimeout *timeout)
SOCK GetSOCK(void)
Get underlying SOCK, if available (e.g. after Fetch())
int GetExitCode(void) const
A valid exit code is only made available after an explicit Close()
CConn_IOStream * NcbiOpenURL(const string &url, size_t buf_size=kConn_DefaultBufSize)
Given a URL, open the data source and make it available for _reading_.
const void * m_Ptr
pointer to read memory area (if owned)
FHTTP_Cleanup m_UserCleanup
CPipe & GetPipe(void)
Return an underlying CPipe; it's valid for as long as the stream exists.
CConn_HttpStream_Base(const TConnector &connector, const STimeout *timeout, size_t buf_size, TConn_Flags flags=0)
virtual EIO_Status Pushback(const CT_CHAR_TYPE *data, streamsize size)
Push the specified data "data" of size "size" back into the underlying connection CONN (making it loo...
EHTTP_HeaderParse Parse(const char *header)
FHTTP_ParseHeader m_UserParseHeader
CPipe * m_Pipe
Underlying pipe.
CSocket & GetSocket(void)
Get CSocket, if available (else empty).
unique_ptr< CConn_Streambuf > x_CSb
unsigned int TConn_Flags
bitwise OR of EConn_Flag
int m_ExitCode
Process exit code.
const size_t kConn_DefaultBufSize
I/O buffer size per direction.
CConn_IOStreamSetWriteTimeout(const STimeout *timeout)
CConstIRef< ICanceled > m_Canceled
void SetURL(const string &url)
Set new URL to hit next.
unsigned int THTTP_Flags
Bitwise OR of EHTTP_Flag.
int(* FHTTP_Adjust)(SConnNetInfo *net_info, void *user_data, unsigned int failure_count)
unsigned int TCONN_Callback
void(* FHTTP_Cleanup)(void *user_data)
EHTTP_HeaderParse
The extended version HTTP_CreateConnectorEx() is able to track the HTTP response chain and also chang...
EHTTP_HeaderParse(* FHTTP_ParseHeader)(const char *http_header, void *user_data, int server_error)
unsigned int TFTP_Flags
@ fHTTP_AutoReconnect
See HTTP_CreateConnectorEx()
@ fCONN_Untie
do not call flush method prior to reading
unsigned int TCreateFlags
bitwise OR of "ECreateFlag"
Definition: ncbi_pipe.hpp:111
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
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...
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
IO_PREFIX::iostream CNcbiIostream
Portable alias for iostream.
Definition: ncbistre.hpp:152
#define NcbiBadbit
Definition: ncbistre.hpp:571
#define CT_CHAR_TYPE
Definition: ncbistre.hpp:729
#define kEmptyStr
Definition: ncbistr.hpp:123
void clear(void)
Clears the string.
Definition: tempstr.hpp:351
EIO_Status
I/O status.
Definition: ncbi_core.h:132
EReqMethod
enum ENcbiOwnership EOwnership
Ownership relations between objects.
EIO_Event
I/O event (or direction).
Definition: ncbi_core.h:118
#define kDefaultTimeout
Definition: ncbi_types.h:81
#define DEF_CONN_MAX_TRY
@ 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
@ eIO_Write
write
Definition: ncbi_core.h:121
@ eIO_Close
also serves as an error indicator in SOCK_Poll
Definition: ncbi_core.h:123
@ eIO_Read
read
Definition: ncbi_core.h:120
#define NCBI_XCONNECT_EXPORT
FILE * file
char * buf
list< Ts... > push
const struct ncbi::grid::netcache::search::fields::SIZE size
static const STimeout kZeroTimeout
static int x_Pushback(SOCK sock, BUF buf)
Implement CONNECTOR for a named pipe interprocess communication (based on the NCBI CNamedPipe).
Implement CONNECTOR for a pipe interprocess communication (based on the NCBI CPipe).
Connector specification.
Helper class to fetch HTTP status code and text.
Timeout structure.
Definition: ncbi_types.h:76
Definition: inftrees.h:24
Definition: type.c:6
string ToString(const wxRect &rc)
Definition: wx_utils.cpp:773
Modified on Mon Jun 24 05:22:36 2024 by modify_doxy.py rev. 669887