OW_HTTPClient.hpp

Go to the documentation of this file.
00001 /*******************************************************************************
00002 * Copyright (C) 2001-2004 Vintela, Inc. All rights reserved.
00003 *
00004 * Redistribution and use in source and binary forms, with or without
00005 * modification, are permitted provided that the following conditions are met:
00006 *
00007 *  - Redistributions of source code must retain the above copyright notice,
00008 *    this list of conditions and the following disclaimer.
00009 *
00010 *  - Redistributions in binary form must reproduce the above copyright notice,
00011 *    this list of conditions and the following disclaimer in the documentation
00012 *    and/or other materials provided with the distribution.
00013 *
00014 *  - Neither the name of Vintela, Inc. nor the names of its
00015 *    contributors may be used to endorse or promote products derived from this
00016 *    software without specific prior written permission.
00017 *
00018 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
00019 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00020 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00021 * ARE DISCLAIMED. IN NO EVENT SHALL Vintela, Inc. OR THE CONTRIBUTORS
00022 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00023 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00024 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00025 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00026 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00027 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00028 * POSSIBILITY OF SUCH DAMAGE.
00029 *******************************************************************************/
00030 
00036 #ifndef OW_HTTPCLIENT_HPP_
00037 #define OW_HTTPCLIENT_HPP_
00038 #include "OW_config.h"
00039 #include "OW_Socket.hpp"
00040 #include "OW_AutoPtr.hpp"
00041 #include "OW_Map.hpp"
00042 #include "OW_HTTPUtils.hpp"
00043 #include "OW_CIMProtocolIFC.hpp"
00044 #include "OW_URL.hpp"
00045 #include "OW_CommonFwd.hpp"
00046 
00047 #if defined(GOOD)
00048 #undef GOOD
00049 #endif
00050 
00051 namespace OW_NAMESPACE
00052 {
00053 
00054 // TODO: Rewrite this class. It's way too big and convoluted. 
00055 // Take a look at Apache's HttpClient library: http://jakarta.apache.org/commons/httpclient/index.html
00056 
00066 class OW_HTTP_API HTTPClient : public CIMProtocolIFC
00067 {
00068 public:
00090    HTTPClient(const String& url, const SSLClientCtxRef& sslCtx = SSLClientCtxRef());
00091    virtual ~HTTPClient();
00092    virtual Reference<std::iostream> beginRequest(
00093          const String& methodName, const String& cimObject);
00094 
00114    virtual CIMProtocolIStreamIFCRef endRequest(
00115       const Reference<std::iostream>& request,
00116       const String& methodName,
00117       const String& cimObject,
00118       ERequestType requestType,
00119       const String& cimProtocolVersion);
00120 
00126    virtual CIMFeatures getFeatures();
00131    SocketAddress getLocalAddress() const;
00136    SocketAddress getPeerAddress()  const;
00146    void setHTTPPath(const String& newPath);
00147 
00155    void assumeBasicAuth();
00156 
00161    virtual void close();
00162 
00169    void addCustomHeader(const String& name, const String& value);
00170 
00178    bool getResponseHeader(const String& hdrName, String& valueOut) const;
00179 
00180    static const int INFINITE_TIMEOUT = -1;
00185    virtual void setReceiveTimeout(int seconds);
00190    virtual int getReceiveTimeout() const;
00195    virtual void setSendTimeout(int seconds);
00200    virtual int getSendTimeout() const;
00205    virtual void setConnectTimeout(int seconds);
00210    virtual int getConnectTimeout() const;
00215    virtual void setTimeouts(int seconds);
00216 
00217 private:
00218    /*
00219     * @throws SocketException If an SSL connection was requested, but support for SSL is not available.
00220     */
00221    void setUrl();
00222 
00223    void cleanUpIStreams();
00224    void receiveAuthentication();
00225    void sendAuthorization();
00226    bool receiveOptions( void );
00227 
00228 #ifdef OW_WIN32
00229 #pragma warning (push)
00230 #pragma warning (disable: 4251)
00231 #endif
00232    
00233    String m_sAuthorization;
00234    String m_sRealm;
00235    
00236 #ifndef OW_DISABLE_DIGEST
00237    String m_sDigestNonce;
00238    String m_sDigestCNonce;
00239    UInt8 m_iDigestNonceCount;
00240    String m_sDigestSessionKey;
00241    String m_sDigestResponse;
00242 #endif
00243    enum Resp_t
00244    {
00245       FATAL,
00246       RETRY,
00247       GOOD,
00248       CONTINUE
00249    };
00250    SocketAddress m_serverAddress;
00251    URL m_url;
00252    HTTPHeaderMap m_responseHeaders;
00253    // Persistant headers remain for the life of the
00254    // HTTPClient.  They are included in each request
00255    Array<String> m_requestHeadersPersistent;
00256    // Common headers are used for only a single request,
00257    // but are reused if the request must be repeated (with
00258    // new authentication credentials, for instance).
00259    Array<String> m_requestHeadersCommon;
00260    // New headers are replaced each time the client repeats
00261    // a request (with new auth credentials, for instance).
00262    Array<String> m_requestHeadersNew;
00263    CIMProtocolIStreamIFCRef m_pIstrReturn;
00264    SSLClientCtxRef m_sslCtx;
00265    mutable Socket m_socket;
00266    String m_requestMethod;
00267    bool m_authRequired;
00268    std::istream& m_istr;
00269    std::ostream& m_ostr;
00270    bool m_doDeflateOut;
00271    int m_retryCount;
00272    String m_httpPath;
00273    bool m_uselocalAuthentication;
00274    String m_localNonce;
00275    String m_localCookieFile;
00276    String m_statusLine;
00277 
00278 #ifdef OW_WIN32
00279 #pragma warning (pop)
00280 #endif
00281 
00282    bool headerHasKey(const String& key)
00283    {
00284       return HTTPUtils::headerHasKey(m_responseHeaders, key);
00285    }
00286    String getHeaderValue(const String& key)
00287    {
00288       return HTTPUtils::getHeaderValue(m_responseHeaders, key);
00289    }
00290    void addHeaderCommon(const String& key, const String& value)
00291    {
00292       HTTPUtils::addHeader(m_requestHeadersCommon, key, value);
00293    }
00294    void addHeaderPersistent(const String& key, const String& value)
00295    {
00296       HTTPUtils::addHeader(m_requestHeadersPersistent, key, value);
00297    }
00298    void addHeaderNew(const String& key, const String& value)
00299    {
00300       HTTPUtils::addHeader(m_requestHeadersNew, key, value);
00301    }
00302    void sendHeaders(const String& method,
00303       const String& prot);
00308    Resp_t processHeaders(String& reasonPhrase);
00309    CIMProtocolIStreamIFCRef convertToFiniteStream();
00310    void prepareForRetry();
00311    void handleAuth(); // process authorization
00312    void checkConnection();
00316    String checkResponse(Resp_t& rt);
00317    void prepareHeaders();
00318    void sendDataToServer( const Reference<TempFileStream>& tfs, const String& methodName, const String& cimObject, ERequestType requestType );
00324    void getCredentialsIfNecessary();
00325    void copyStreams(std::ostream& ostr, std::istream& istr);
00329    void getStatusLine();
00330 
00341    enum EStatusLineSummary
00342    {
00343       E_STATUS_GOOD,
00344       E_STATUS_ERROR
00345    };
00346    EStatusLineSummary checkAndExamineStatusLine();
00347 
00348 
00349 
00350    // unimplemented
00351    HTTPClient(const HTTPClient&);
00352    HTTPClient& operator=(const HTTPClient&);
00353 };
00354 
00355 typedef IntrusiveReference<HTTPClient> HTTPClientRef;
00356 
00357 } // end namespace OW_NAMESPACE
00358 
00359 #endif

Generated on Thu Feb 9 08:47:59 2006 for openwbem by  doxygen 1.4.6