// @(#)root/net:$Id$
// Author: Fabio Hernandez 30/01/2013
//         based on an initial version by Marcelo Sousa (class THTTPMessage)

/*************************************************************************
 * Copyright (C) 1995-2011, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

#ifndef ROOT_TS3HTTPRequest
#define ROOT_TS3HTTPRequest

//////////////////////////////////////////////////////////////////////////
//                                                                      //
// TS3HTTPRequest                                                       //
//                                                                      //
// An object of this class represents an HTTP request extended to be    //
// compatible with Amazon's S3 protocol.                                //
// Specifically, such a request contains an 'Authorization' header with //
// information used by the S3 server for authenticating this request.   //
// The authentication information is computed based on a pair of access //
// key and secret key which are both provided to the user by the S3     //
// service provider (e.g. Amazon, Google, etc.).                        //
// The secret key is used to compute a signature of selected fields in  //
// the request. The algorithm for computing the signature is documented //
// in:                                                                  //
//                                                                      //
// Google storage:                                                      //
// http://code.google.com/apis/storage/docs/reference/v1/developer-guidev1.html#authentication
//                                                                      //
// Amazon:                                                              //
// http://docs.aws.amazon.com/AmazonS3/latest/dev/S3_Authentication2.html 
//                                                                      //
//////////////////////////////////////////////////////////////////////////

#ifndef ROOT_TObject
#include "TObject.h"
#endif

#ifndef ROOT_TString
#include "TString.h"
#endif



class TS3HTTPRequest : public TObject {

public:

   enum EHTTPVerb { kGET, kPOST, kPUT, kDELETE, kHEAD, kCOPY };
   enum EAuthType { kNoAuth, kAmazon, kGoogle };

private:
   EHTTPVerb fVerb;        // HTTP Verb
   EAuthType fAuthType;    // Authentication type
   TString   fHost;        // Host name
   TString   fBucket;      // Bucket name
   TString   fObjectKey;   // Object key
   TString   fTimeStamp;   // Request time stamp
   TString   fAccessKey;   // Access key (for authentication)
   TString   fSecretKey;   // Secret key (for authentication)


protected:
   TString HTTPVerbToTString(EHTTPVerb httpVerb) const;
   TString MakeRequestLine(TS3HTTPRequest::EHTTPVerb httpVerb) const;
   TString MakeAuthHeader(TS3HTTPRequest::EHTTPVerb httpVerb) const;
   TString ComputeSignature(TS3HTTPRequest::EHTTPVerb httpVerb) const;
   TString MakeAuthPrefix() const;
   TString MakeHostHeader() const;
   TString MakeDateHeader() const;
   TS3HTTPRequest& SetTimeStamp();

public:

   TS3HTTPRequest();
   TS3HTTPRequest(EHTTPVerb httpVerb, const TString& host,
                const TString& bucket, const TString& objectKey,
                EAuthType authType, const TString& accessKey,
                const TString& secretKey);
   TS3HTTPRequest(const TS3HTTPRequest& m);
   virtual ~TS3HTTPRequest() { }

   EHTTPVerb       GetHTTPVerb() const { return fVerb; }
   const TString&  GetHost() const { return fHost; }
   const TString&  GetBucket() const { return fBucket; }
   const TString&  GetObjectKey() const { return fObjectKey; }
   const TString&  GetTimeStamp() const { return fTimeStamp; }
   const TString&  GetAccessKey() const { return fAccessKey; }
   const TString&  GetSecretKey() const { return fSecretKey; }
   TString         GetAuthType() const { return fAuthType; }
   TString         GetRequest(TS3HTTPRequest::EHTTPVerb httpVerb, Bool_t appendCRLF=kTRUE);

   TS3HTTPRequest& SetHost(const TString& host);
   TS3HTTPRequest& SetBucket(const TString& bucket);
   TS3HTTPRequest& SetObjectKey(const TString& objectKey);
   TS3HTTPRequest& SetAccessKey(const TString& accessKey);
   TS3HTTPRequest& SetSecretKey(const TString& secretKey);
   TS3HTTPRequest& SetAuthKeys(const TString& accessKey, const TString& secretKey);
   TS3HTTPRequest& SetAuthType(TS3HTTPRequest::EAuthType authType);

   ClassDef(TS3HTTPRequest, 0)  // Create generic HTTP request for Amazon S3 and Google Storage services
};


//////////////////////////////////////////////////////////////////////////
//                                                                      //
//  Inlines                                                             //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

inline TS3HTTPRequest& TS3HTTPRequest::SetHost(const TString& host)
{
   fHost = host;
   return *this;
}

inline TS3HTTPRequest& TS3HTTPRequest::SetBucket(const TString& bucket)
{
   fBucket = bucket;
   return *this;
}

inline TS3HTTPRequest& TS3HTTPRequest::SetObjectKey(const TString& objectKey)
{
   fObjectKey = objectKey;
   return *this;
}

inline TS3HTTPRequest& TS3HTTPRequest::SetAuthKeys(const TString& accessKey, const TString& secretKey)
{
   fAccessKey = accessKey;
   fSecretKey = secretKey;
   return *this;
}

inline TS3HTTPRequest& TS3HTTPRequest::SetAuthType(TS3HTTPRequest::EAuthType authType)
{
   fAuthType = authType;
   return *this;
}

inline TS3HTTPRequest& TS3HTTPRequest::SetAccessKey(const TString& accessKey)
{
   fAccessKey = accessKey;
   return *this;
}

inline TS3HTTPRequest& TS3HTTPRequest::SetSecretKey(const TString& secretKey)
{
   fSecretKey = secretKey;
   return *this;
}

#endif
 TS3HTTPRequest.h:1
 TS3HTTPRequest.h:2
 TS3HTTPRequest.h:3
 TS3HTTPRequest.h:4
 TS3HTTPRequest.h:5
 TS3HTTPRequest.h:6
 TS3HTTPRequest.h:7
 TS3HTTPRequest.h:8
 TS3HTTPRequest.h:9
 TS3HTTPRequest.h:10
 TS3HTTPRequest.h:11
 TS3HTTPRequest.h:12
 TS3HTTPRequest.h:13
 TS3HTTPRequest.h:14
 TS3HTTPRequest.h:15
 TS3HTTPRequest.h:16
 TS3HTTPRequest.h:17
 TS3HTTPRequest.h:18
 TS3HTTPRequest.h:19
 TS3HTTPRequest.h:20
 TS3HTTPRequest.h:21
 TS3HTTPRequest.h:22
 TS3HTTPRequest.h:23
 TS3HTTPRequest.h:24
 TS3HTTPRequest.h:25
 TS3HTTPRequest.h:26
 TS3HTTPRequest.h:27
 TS3HTTPRequest.h:28
 TS3HTTPRequest.h:29
 TS3HTTPRequest.h:30
 TS3HTTPRequest.h:31
 TS3HTTPRequest.h:32
 TS3HTTPRequest.h:33
 TS3HTTPRequest.h:34
 TS3HTTPRequest.h:35
 TS3HTTPRequest.h:36
 TS3HTTPRequest.h:37
 TS3HTTPRequest.h:38
 TS3HTTPRequest.h:39
 TS3HTTPRequest.h:40
 TS3HTTPRequest.h:41
 TS3HTTPRequest.h:42
 TS3HTTPRequest.h:43
 TS3HTTPRequest.h:44
 TS3HTTPRequest.h:45
 TS3HTTPRequest.h:46
 TS3HTTPRequest.h:47
 TS3HTTPRequest.h:48
 TS3HTTPRequest.h:49
 TS3HTTPRequest.h:50
 TS3HTTPRequest.h:51
 TS3HTTPRequest.h:52
 TS3HTTPRequest.h:53
 TS3HTTPRequest.h:54
 TS3HTTPRequest.h:55
 TS3HTTPRequest.h:56
 TS3HTTPRequest.h:57
 TS3HTTPRequest.h:58
 TS3HTTPRequest.h:59
 TS3HTTPRequest.h:60
 TS3HTTPRequest.h:61
 TS3HTTPRequest.h:62
 TS3HTTPRequest.h:63
 TS3HTTPRequest.h:64
 TS3HTTPRequest.h:65
 TS3HTTPRequest.h:66
 TS3HTTPRequest.h:67
 TS3HTTPRequest.h:68
 TS3HTTPRequest.h:69
 TS3HTTPRequest.h:70
 TS3HTTPRequest.h:71
 TS3HTTPRequest.h:72
 TS3HTTPRequest.h:73
 TS3HTTPRequest.h:74
 TS3HTTPRequest.h:75
 TS3HTTPRequest.h:76
 TS3HTTPRequest.h:77
 TS3HTTPRequest.h:78
 TS3HTTPRequest.h:79
 TS3HTTPRequest.h:80
 TS3HTTPRequest.h:81
 TS3HTTPRequest.h:82
 TS3HTTPRequest.h:83
 TS3HTTPRequest.h:84
 TS3HTTPRequest.h:85
 TS3HTTPRequest.h:86
 TS3HTTPRequest.h:87
 TS3HTTPRequest.h:88
 TS3HTTPRequest.h:89
 TS3HTTPRequest.h:90
 TS3HTTPRequest.h:91
 TS3HTTPRequest.h:92
 TS3HTTPRequest.h:93
 TS3HTTPRequest.h:94
 TS3HTTPRequest.h:95
 TS3HTTPRequest.h:96
 TS3HTTPRequest.h:97
 TS3HTTPRequest.h:98
 TS3HTTPRequest.h:99
 TS3HTTPRequest.h:100
 TS3HTTPRequest.h:101
 TS3HTTPRequest.h:102
 TS3HTTPRequest.h:103
 TS3HTTPRequest.h:104
 TS3HTTPRequest.h:105
 TS3HTTPRequest.h:106
 TS3HTTPRequest.h:107
 TS3HTTPRequest.h:108
 TS3HTTPRequest.h:109
 TS3HTTPRequest.h:110
 TS3HTTPRequest.h:111
 TS3HTTPRequest.h:112
 TS3HTTPRequest.h:113
 TS3HTTPRequest.h:114
 TS3HTTPRequest.h:115
 TS3HTTPRequest.h:116
 TS3HTTPRequest.h:117
 TS3HTTPRequest.h:118
 TS3HTTPRequest.h:119
 TS3HTTPRequest.h:120
 TS3HTTPRequest.h:121
 TS3HTTPRequest.h:122
 TS3HTTPRequest.h:123
 TS3HTTPRequest.h:124
 TS3HTTPRequest.h:125
 TS3HTTPRequest.h:126
 TS3HTTPRequest.h:127
 TS3HTTPRequest.h:128
 TS3HTTPRequest.h:129
 TS3HTTPRequest.h:130
 TS3HTTPRequest.h:131
 TS3HTTPRequest.h:132
 TS3HTTPRequest.h:133
 TS3HTTPRequest.h:134
 TS3HTTPRequest.h:135
 TS3HTTPRequest.h:136
 TS3HTTPRequest.h:137
 TS3HTTPRequest.h:138
 TS3HTTPRequest.h:139
 TS3HTTPRequest.h:140
 TS3HTTPRequest.h:141
 TS3HTTPRequest.h:142
 TS3HTTPRequest.h:143
 TS3HTTPRequest.h:144
 TS3HTTPRequest.h:145
 TS3HTTPRequest.h:146
 TS3HTTPRequest.h:147
 TS3HTTPRequest.h:148
 TS3HTTPRequest.h:149
 TS3HTTPRequest.h:150
 TS3HTTPRequest.h:151
 TS3HTTPRequest.h:152
 TS3HTTPRequest.h:153
 TS3HTTPRequest.h:154
 TS3HTTPRequest.h:155
 TS3HTTPRequest.h:156
 TS3HTTPRequest.h:157
 TS3HTTPRequest.h:158