<commit_before>/*
 * Copyright(c) Sophist Solutions, Inc. 1990-2014.  All rights reserved
 */
#ifndef _Stroika_Foundation_IO_Network_Transfer_Client_h_
#define _Stroika_Foundation_IO_Network_Transfer_Client_h_   1

#include    "../../../StroikaPreComp.h"

#include    <string>

#include    "../../../Characters/String.h"
#include    "../../../Configuration/Common.h"
#include    "../../../Containers/Mapping.h"
#include    "../../../DataExchange/InternetMediaType.h"
#include    "../../../Memory/BLOB.h"
#include    "../../../Memory/Optional.h"
#include    "../../../Streams/BinaryInputStream.h"
#include    "../../../Streams/TextInputStream.h"
#include    "../../../Time/Realtime.h"

#include    "../URL.h"
#include    "../HTTP/Status.h"


/**
 *
 *  \version    <a href="code_status.html#Late-Alpha">Late-Alpha</a>
 *
 *
 * TODO:
 *
 *      @todo   Probably should redo Request so it can optionally use a BLOB or
 *              Stream (like Response). DO NOW the header / class changes - making
 *              CTOR/accessors, so easiser to change funcitonality later!!!
 *
 *      @todo   Add thread safety (locks/semaphores)
 *
 *                  Decide on and DOCUMENT threading policy. For example - do we need
 *                  locks internally in the connection object or DEFINE that its
 *                  the callers resposabiltiy. PROBABLY best to do in the Connection object itself?
 *
 *                  ADD CRITICAL SECTIONS!!! - or DOCUMENT CALLERS REPSONABILTY
 *
 *      @todo   Add (optionally callable) Connect() method. Send etc connect on-demand as needed
 *              but sometimes its useful to pre-create connections (to reduce latnecy).
 *
 *      @todo   Add factory for 'CreateConnection'  - so you can do 'dependnecy injection' or other
 *              way to configure http client support library (winhttp versus libcurl or other).
 *
 *      @todo   Redo Response to fully/properly support incremental read through streams. Must do
 *              CTOR on response object taking a stream, and hten reasonably (tbd) how to handle
 *              calls to getResponseBLOB? (probably assert or except?)
 *
 *      @todo   Progress Callbacks?
 *
 *      @todo   Add Client side certs
 *
 *      @todo   Refine server-side-cert checking mechanism (review LIBCURL to see what makes sense)
 *              PROBABLY just a callback mechanism - with a few default callabcks you can plugin (like reject bad certs)
 *              MAYBE just add FLAG saying whether to VALIDATE_HOST? Maybe callback API"?
 *
 *                        //  This COULD be expanded to include either a BOOL to CHECK remote SSL info, or a callback (which can throw)
 *                        //  if invalid SSL INFO from server side. Thats probably best. callback whcih throws, and set it to such a callback by default!
 *                        //      -- LGP 2012-06-26
 *
 */



namespace   Stroika {
    namespace   Foundation {
        namespace   IO {
            namespace   Network {
                namespace   Transfer {


//avoid windows header clash...
#undef DELETE


                    using   Characters::String;
                    using   Containers::Mapping;
                    using   DataExchange::InternetMediaType;
                    using   Memory::BLOB;
                    using   Memory::Byte;
                    using   Memory::Optional;
                    using   Streams::BinaryInputStream;
                    using   Streams::TextInputStream;
                    using   Time::DurationSecondsType;


                    /**
                     *  \note  DESIGN-NOTE:
                     *      Chose not move request/repsonse stuff to HTTP module- so re-usable in framework
                     *      code which does webserver, because though the abstract API is identical, we
                     *      have very differnt needs about to what to specify/retrieve in one case or the other.
                     *
                     *      @todo maybe reconsider?
                     */
                    struct  Request {
                        String                  fMethod;
                        Mapping<String, String> fOverrideHeaders;
                        BLOB                    fData;  // usually empty, but provided for some methods like POST

                        /**
                         *  Scans fOverrideHeaders
                         */
                        nonvirtual  InternetMediaType   GetContentType () const;

                        /**
                         * updates fOverrideHeaders
                         */
                        nonvirtual  void                SetContentType (const InternetMediaType& ct);
                    };


                    /**
                     *  DESIGN NOTES:
                     *      The Response can be constructed with a BLOB of data, or a binary stream. If constructed
                     *      with a blob of data, the binary stream returned will be a reference to this data, and can be used
                     *      to page out the data.
                     *
                     *      If constructed with a BinaryStream (NYI) - then the caller (Client::Send) can return before all the data
                     *      is available. Any future calls on teh Client may block (TBD???) or fail???
                     *
                     *      But then the data can be paged out without ever being accumulated into a single large buffer.
                     *
                     *      Note - if the use of a Response calls GetBLOB () - even if constructed with a stream - this will
                     *      block reading in the stream.
                     *
                     *      If the caller gets GetResponseStream() - then calls to GetBLOB() will fail. Note - we COULD have
                     *      kept the bytes around from the response stream as it came in, but that could in principle be large,
                     *      and your probably using the Stream API to avoid having the entire thing in emmroy so we dont want
                     *      to needlessly thwart that.
                     *
                     *      NOTE - as of 2014-10-08 - the only case thats implemented is the case of construction with a prefetched
                     *      BLOB, and then repsenting THAT as a binary stream if requested.
                     */
                    class  Response {
                    public:
                        struct  SSLResultInfo;
<commit_msg>docs about IO/Network/Transfer/Client response (blob versus stream)<commit_after>/*
 * Copyright(c) Sophist Solutions, Inc. 1990-2014.  All rights reserved
 */
#ifndef _Stroika_Foundation_IO_Network_Transfer_Client_h_
#define _Stroika_Foundation_IO_Network_Transfer_Client_h_   1

#include    "../../../StroikaPreComp.h"

#include    <string>

#include    "../../../Characters/String.h"
#include    "../../../Configuration/Common.h"
#include    "../../../Containers/Mapping.h"
#include    "../../../DataExchange/InternetMediaType.h"
#include    "../../../Memory/BLOB.h"
#include    "../../../Memory/Optional.h"
#include    "../../../Streams/BinaryInputStream.h"
#include    "../../../Streams/TextInputStream.h"
#include    "../../../Time/Realtime.h"

#include    "../URL.h"
#include    "../HTTP/Status.h"


/**
 *
 *  \version    <a href="code_status.html#Late-Alpha">Late-Alpha</a>
 *
 *
 * TODO:
 *
 *      @todo   Probably should redo Request so it can optionally use a BLOB or
 *              Stream (like Response). DO NOW the header / class changes - making
 *              CTOR/accessors, so easiser to change funcitonality later!!!
 *
 *      @todo   Add thread safety (locks/semaphores)
 *
 *                  Decide on and DOCUMENT threading policy. For example - do we need
 *                  locks internally in the connection object or DEFINE that its
 *                  the callers resposabiltiy. PROBABLY best to do in the Connection object itself?
 *
 *                  ADD CRITICAL SECTIONS!!! - or DOCUMENT CALLERS REPSONABILTY
 *
 *      @todo   Add (optionally callable) Connect() method. Send etc connect on-demand as needed
 *              but sometimes its useful to pre-create connections (to reduce latnecy).
 *
 *      @todo   Add factory for 'CreateConnection'  - so you can do 'dependnecy injection' or other
 *              way to configure http client support library (winhttp versus libcurl or other).
 *
 *      @todo   Redo Response to fully/properly support incremental read through streams. Must do
 *              CTOR on response object taking a stream, and hten reasonably (tbd) how to handle
 *              calls to getResponseBLOB? (probably assert or except?)
 *
 *      @todo   Progress Callbacks?
 *
 *      @todo   Add Client side certs
 *
 *      @todo   Refine server-side-cert checking mechanism (review LIBCURL to see what makes sense)
 *              PROBABLY just a callback mechanism - with a few default callabcks you can plugin (like reject bad certs)
 *              MAYBE just add FLAG saying whether to VALIDATE_HOST? Maybe callback API"?
 *
 *                        //  This COULD be expanded to include either a BOOL to CHECK remote SSL info, or a callback (which can throw)
 *                        //  if invalid SSL INFO from server side. Thats probably best. callback whcih throws, and set it to such a callback by default!
 *                        //      -- LGP 2012-06-26
 *
 */



namespace   Stroika {
    namespace   Foundation {
        namespace   IO {
            namespace   Network {
                namespace   Transfer {


//avoid windows header clash...
#undef DELETE


                    using   Characters::String;
                    using   Containers::Mapping;
                    using   DataExchange::InternetMediaType;
                    using   Memory::BLOB;
                    using   Memory::Byte;
                    using   Memory::Optional;
                    using   Streams::BinaryInputStream;
                    using   Streams::TextInputStream;
                    using   Time::DurationSecondsType;


                    /**
                     *  \note  DESIGN-NOTE:
                     *      Chose not move request/repsonse stuff to HTTP module- so re-usable in framework
                     *      code which does webserver, because though the abstract API is identical, we
                     *      have very differnt needs about to what to specify/retrieve in one case or the other.
                     *
                     *      @todo maybe reconsider?
                     */
                    struct  Request {
                        String                  fMethod;
                        Mapping<String, String> fOverrideHeaders;
                        BLOB                    fData;  // usually empty, but provided for some methods like POST

                        /**
                         *  Scans fOverrideHeaders
                         */
                        nonvirtual  InternetMediaType   GetContentType () const;

                        /**
                         * updates fOverrideHeaders
                         */
                        nonvirtual  void                SetContentType (const InternetMediaType& ct);
                    };


                    /**
                     *  DESIGN NOTES:
                     *      The Response can be constructed with a BLOB of data, or a binary stream. If constructed
                     *      with a blob of data, the binary stream returned will be a reference to this data, and can be used
                     *      to page out the data.
                     *
                     *      If constructed with a BinaryStream (NYI) - then the caller (Client::Send) can return before all the data
                     *      is available. Any future calls on teh Client may block (TBD???) or fail???
                     *
                     *      But then the data can be paged out without ever being accumulated into a single large buffer.
                     *
                     *      Note - if the use of a Response calls GetBLOB () - even if constructed with a stream - this will
                     *      block reading in the stream.
                     *
                     *      If the caller gets GetResponseStream() - then calls to GetBLOB() will fail. Note - we COULD have
                     *      kept the bytes around from the response stream as it came in, but that could in principle be large,
                     *      and your probably using the Stream API to avoid having the entire thing in emmroy so we dont want
                     *      to needlessly thwart that.
                     *
                     *      NOTE - as of 2014-10-08 - the only case thats implemented is the case of construction with a prefetched
                     *      BLOB, and then repsenting THAT as a binary stream if requested.
                     *
                     *  @todo    NOTE IMPLICATIONS ABOUT COIPYING.
                     *          HAVE FLAG CALLED "STREAMED_RESPONSE".
                     *
                     *          CTOR specifies this value and it cannot change and generally comes from request options.
                     *          if streamed response, ILLEGAL to call GETBLOB() (throws IsStreamedResponse).
                     *          If streamed response, copy of Response object copies Stream itself, whcih is (cuz all streams are
                     *          logcially smart poitners to data) - so multiple readers interfere with one another. threadsafe byt
                     *          possibly not the expected behavior).
                     */
                    class  Response {
                    public:
                        struct  SSLResultInfo;

{'fraction_non_alphanumeric': 0.07167014463553285, 'fraction_numerical': 0.0035978988270849825, 'mean_word_length': 1.398274374460742, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 10, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2013839', 'n_tokens_mistral': 3421, 'n_tokens_neox': 3153, 'n_words': 1278}