00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
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 
00055 
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 
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    
00254    
00255    Array<String> m_requestHeadersPersistent;
00256    
00257    
00258    
00259    Array<String> m_requestHeadersCommon;
00260    
00261    
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(); 
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    
00351    HTTPClient(const HTTPClient&);
00352    HTTPClient& operator=(const HTTPClient&);
00353 };
00354 
00355 typedef IntrusiveReference<HTTPClient> HTTPClientRef;
00356 
00357 } 
00358 
00359 #endif