summaryrefslogtreecommitdiffstats
path: root/src/libcmis/http-session.hxx
blob: 34223b23df8b946a373bf25e0b7b6039e8162971 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
/* libcmis
 * Version: MPL 1.1 / GPLv2+ / LGPLv2+
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (the "License"); you may not use this file except in compliance with
 * the License or as specified alternatively below. You may obtain a copy of
 * the License at http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * Major Contributor(s):
 * Copyright (C) 2011 SUSE <cbosdonnat@suse.com>
 *
 *
 * All Rights Reserved.
 *
 * For minor contributions see the git repository.
 *
 * Alternatively, the contents of this file may be used under the terms of
 * either the GNU General Public License Version 2 or later (the "GPLv2+"), or
 * the GNU Lesser General Public License Version 2 or later (the "LGPLv2+"),
 * in which case the provisions of the GPLv2+ or the LGPLv2+ are applicable
 * instead of those above.
 */
#ifndef _HTTP_SESSION_HXX_
#define _HTTP_SESSION_HXX_

#include <istream>
#include <sstream>
#include <vector>
#include <string>

#include <curl/curl.h>
#include <libxml/xmlstring.h>
#include <libxml/xpath.h>

#include <libcmis/exception.hxx>
#include <libcmis/oauth2-data.hxx>
#include <libcmis/xml-utils.hxx>

class OAuth2Handler;

namespace libcmis {
    typedef void(*CurlInitProtocolsFunction)(CURL *);
}

class CurlException : public std::exception
{
    private:
        std::string m_message;
        CURLcode    m_code;
        std::string m_url;
        long        m_httpStatus;

        bool        m_cancelled;

        mutable std::string m_errorMessage;

    public:
        CurlException( std::string message, CURLcode code, std::string url, long httpStatus ) :
            exception( ),
            m_message( message ),
            m_code( code ),
            m_url( url ),
            m_httpStatus( httpStatus ),
            m_cancelled( false ),
            m_errorMessage( )
        {
        }

        CurlException( std::string message ) :
            exception( ),
            m_message( message ),
            m_code( CURLE_OK ),
            m_url( ),
            m_httpStatus( 0 ),
            m_cancelled( true ),
            m_errorMessage( )
        {
        }

        ~CurlException( ) noexcept { }
        virtual const char* what( ) const noexcept;

        CURLcode getErrorCode( ) const { return m_code; }
        std::string getErrorMessage( ) const { return m_message; }
        bool isCancelled( ) const { return m_cancelled; }
        long getHttpStatus( ) const { return m_httpStatus; }

        libcmis::Exception getCmisException ( ) const;
};

class HttpSession
{
    protected:
        CURL* m_curlHandle;
        libcmis::CurlInitProtocolsFunction m_CurlInitProtocolsFunction = nullptr;
    private:
        bool  m_no100Continue;
    protected:
        OAuth2Handler* m_oauth2Handler;
        std::string m_username;
        std::string m_password;
        bool m_authProvided;

        bool m_verbose;
        bool m_noHttpErrors;
        bool m_noSSLCheck;
        bool m_refreshedToken;
        bool m_inOAuth2Authentication;
        unsigned long m_authMethod;
    public:
        HttpSession( std::string username, std::string password,
                     bool noSslCheck = false,
                     libcmis::OAuth2DataPtr oauth2 = libcmis::OAuth2DataPtr(),
                     bool verbose = false,
                     libcmis::CurlInitProtocolsFunction = nullptr);

        HttpSession( const HttpSession& copy );
        virtual ~HttpSession( );

        HttpSession& operator=( const HttpSession& copy );

        std::string& getUsername( );

        std::string& getPassword( );

        /** Don't throw the HTTP errors as CurlExceptions.
          */
        void setNoHttpErrors( bool noHttpErrors ) { m_noHttpErrors = noHttpErrors; }


        /** Set the OAuth2 data and get the access / refresh tokens.
          */
        virtual void setOAuth2Data( libcmis::OAuth2DataPtr oauth2 );

        libcmis::HttpResponsePtr httpGetRequest( std::string url );
        libcmis::HttpResponsePtr httpPatchRequest( std::string url,
                                                 std::istream& is,
                                                 std::vector< std::string > headers );
        libcmis::HttpResponsePtr httpPutRequest( std::string url,
                                                 std::istream& is,
                                                 std::vector< std::string > headers );
        libcmis::HttpResponsePtr httpPostRequest( const std::string& url,
                                                  std::istream& is,
                                                  const std::string& contentType,
                                                  bool redirect = true );
        void httpDeleteRequest( std::string url );

        long getHttpStatus( );

        void setNoSSLCertificateCheck( bool noCheck );

        virtual std::string getRefreshToken( );

    protected:
        HttpSession( );

        /** Helper function actually handling the oauth2 process.
            This function is provided for BaseSession to customize
            the OAuth2 login parser.
          */
        void oauth2Authenticate( );
        void setAuthMethod( unsigned long authMethod ) { m_authMethod = authMethod; }
        virtual void httpRunRequest( std::string url,
                                    std::vector< std::string > headers = std::vector< std::string > ( ),
                                    bool redirect = true );

    private:
        void checkCredentials( );
        void checkOAuth2( std::string url );
        void oauth2Refresh( );
        void initProtocols( );
};

#endif