httpclnt.h

Go to the documentation of this file.
00001 
00002  //
00003  // XMLStorage XML-RPC client extension
00004  //
00005  // Copyright (c) 2009, 2014 Martin Fuchs <martin-fuchs@gmx.net>
00006  //
00007 
00008 
00009 /*
00010 
00011   All rights reserved.
00012 
00013   Redistribution and use in source and binary forms, with or without
00014   modification, are permitted provided that the following conditions are met:
00015 
00016   * Redistributions of source code must retain the above copyright
00017     notice, this list of conditions and the following disclaimer.
00018   * Redistributions in binary form must reproduce the above copyright
00019     notice, this list of conditions and the following disclaimer in
00020     the documentation and/or other materials provided with the
00021     distribution.
00022 
00023   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00024   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00025   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00026   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
00027   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00028   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00029   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00030   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00031   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00032   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00033   POSSIBILITY OF SUCH DAMAGE.
00034 
00035 */
00036 
00037 #include "xmlrpc.h"
00038 
00039 
00040 //#ifdef _WIN32
00041 //#define USE_WININET
00042 //#endif
00043 
00044 
00045 namespace XMLRPC {
00046 
00047 
00048 #ifdef USE_WININET
00049 
00050 #include <wininet.h>
00051 
00052  // WININET exception
00053 typedef LWE LIE;
00054 
00055 struct INETLib
00056 {
00057     INETLib(LPCTSTR agent)
00058     {
00059         _hinet = InternetOpen(agent, INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
00060 
00061         if (!_hinet)
00062             throw LIE();
00063     }
00064 
00065     ~INETLib()
00066     {
00067         InternetCloseHandle(_hinet);
00068     }
00069 
00070     HINTERNET   _hinet;
00071 };
00072 
00073 struct URL
00074 {
00075     URL(LPCTSTR url)
00076     {
00077         TCHAR url_buffer[MAX_PATH];
00078         DWORD url_len = MAX_PATH;
00079 
00080         if (!InternetCanonicalizeUrl(url, url_buffer, &url_len, 0))
00081             throw LIE();
00082 
00083         memset(&_comps, 0, sizeof(URL_COMPONENTS));
00084         _comps.dwStructSize = sizeof(URL_COMPONENTS);
00085 
00086         *_hostname = '\0';
00087         _comps.lpszHostName = _hostname;
00088         _comps.dwHostNameLength = MAX_PATH;
00089 
00090         *_path = '\0';
00091         _comps.lpszUrlPath = _path;
00092         _comps.dwUrlPathLength = MAX_PATH;
00093 
00094         if (!InternetCrackUrl(url_buffer, 0, 0, &_comps))
00095             throw LIE();
00096     }
00097 
00098     LPCTSTR get_host() const
00099     {
00100         return _comps.lpszHostName;
00101     }
00102 
00103     LPCTSTR get_path() const
00104     {
00105         return _comps.lpszUrlPath;
00106     }
00107 
00108     INTERNET_PORT get_port() const
00109     {
00110         return _comps.nPort;
00111     }
00112 
00113     INTERNET_SCHEME get_scheme() const
00114     {
00115         return _comps.nScheme;
00116     }
00117 
00118 private:
00119     URL_COMPONENTS  _comps;
00120     TCHAR   _hostname[MAX_PATH];
00121     TCHAR   _path[MAX_PATH];
00122 };
00123 
00124 struct InternetConnection
00125 {
00126     InternetConnection(HINTERNET hinet, const URL& url)
00127     {
00128         _hConnect = InternetConnect(hinet, url.get_host(), url.get_port(), NULL, NULL, url.get_scheme(), 0, 0);
00129 
00130         if (!_hConnect)
00131             throw LIE();
00132     }
00133 
00134     ~InternetConnection()
00135     {
00136         InternetCloseHandle(_hConnect);
00137     }
00138 
00139     operator HINTERNET() {return _hConnect;}
00140 
00141 private:
00142     HINTERNET   _hConnect;
00143 };
00144 
00145 struct HTTPRequest
00146 {
00147     HTTPRequest(InternetConnection& conn, LPCTSTR url_path, LPCTSTR verb)
00148     {
00149         _hRequest = HttpOpenRequest(conn, verb, url_path, NULL, NULL, NULL, 0, 0);
00150 
00151         if (!_hRequest)
00152             throw LIE();
00153     }
00154 
00155     ~HTTPRequest()
00156     {
00157         InternetCloseHandle(_hRequest);
00158     }
00159 
00160     string  send(const void* data, size_t len);
00161 
00162 private:
00163     HINTERNET   _hRequest;
00164 };
00165 
00166 
00167 #else // USE_WININET
00168 
00169 
00170 #include "sockets.h"
00171 
00172 struct HTTPConnection
00173 {
00174     HTTPConnection(const char* agent, const URL& url);
00175 
00176     Socket& get_socket(const AddressList& addr);
00177     void    close();
00178 
00179     const char* _agent;
00180     URL     _url;
00181 
00182     string  send_request(const URL& url, const AddressList& addr, const char* verb, const char* data, size_t len, bool close_connection);
00183 
00184 private:
00185     INConnect*  _pConnect;
00186 };
00187 
00188 #endif // USE_WININET
00189 
00190 
00191 struct XMLRPCClient
00192 {
00193     XMLRPCClient(LPCTSTR url, LPCTSTR agent="HTTP Post Client");
00194 
00195     void enable_extensions(bool flag=true)
00196     {
00197         _extensions = flag;
00198     }
00199 
00200     string  request_post(const string& in);
00201 
00202     XMLRPCResult call(XMLRPCCall& call);
00203 
00204 protected:
00205     URL     _parsed_url;
00206     bool    _extensions;
00207 
00208 #ifdef USE_WININET
00209     INETLib _inet_lib;
00210     InternetConnection _connection;
00211 #else
00212 #ifdef _WIN32
00213     WinSockInit     _ws_init;
00214 #endif
00215     AddressList     _addr;
00216     HTTPConnection  _connection;
00217 #endif
00218 };
00219 
00220 
00221 } // namespace XMLRPC