Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
TS3HTTPRequest.cxx
Go to the documentation of this file.
1// @(#)root/net:$Id$
2// Author: Fabio Hernandez 30/01/2013
3// based on an initial version by Marcelo Sousa (class THTTPMessage)
4
5/*************************************************************************
6 * Copyright (C) 1995-2011, Rene Brun and Fons Rademakers. *
7 * All rights reserved. *
8 * *
9 * For the licensing terms see $ROOTSYS/LICENSE. *
10 * For the list of contributors see $ROOTSYS/README/CREDITS. *
11 *************************************************************************/
12
13//////////////////////////////////////////////////////////////////////////
14// //
15// TS3HTTPRequest //
16// //
17// An object of this class represents an HTTP request extended to be //
18// compatible with Amazon's S3 protocol. //
19// Specifically, such a request contains an 'Authorization' header with //
20// information used by the S3 server for authenticating this request. //
21// The authentication information is computed based on a pair of access //
22// key and secret key which are both provided to the user by the S3 //
23// service provider (e.g. Amazon, Google, etc.). //
24// The secret key is used to compute a signature of selected fields in //
25// the request. The algorithm for computing the signature is documented //
26// in: //
27// //
28// Google storage: //
29// http://code.google.com/apis/storage/docs/reference/v1/developer-guidev1.html#authentication
30// //
31// Amazon: //
32// http://docs.aws.amazon.com/AmazonS3/latest/dev/S3_Authentication2.html
33// //
34//////////////////////////////////////////////////////////////////////////
35
36#include "TS3HTTPRequest.h"
37#include "TBase64.h"
38#if defined(MAC_OS_X_VERSION_10_7)
39#include <CommonCrypto/CommonHMAC.h>
40#define SHA_DIGEST_LENGTH 20
41#else
42#include <openssl/sha.h>
43#include <openssl/hmac.h>
44#include <openssl/evp.h>
45#include <openssl/bio.h>
46#include <openssl/buffer.h>
47#endif
48
49#include <cstdio>
50#include <ctime>
51#include <cstring>
52
53
54////////////////////////////////////////////////////////////////////////////////
55
57 : fAuthType(kNoAuth), fHost("NoHost")
58{
59}
60
61////////////////////////////////////////////////////////////////////////////////
62/// Default constructor
63
76
77////////////////////////////////////////////////////////////////////////////////
78/// Copy constructor
79
81 : TObject(r)
82{
83 fVerb = r.fVerb;
84 fHost = r.fHost;
85 fBucket = r.fBucket;
86 fObjectKey = r.fObjectKey;
87 fAuthType = r.fAuthType;
88 fAccessKey = r.fAccessKey;
89 fSecretKey = r.fSecretKey;
90 fTimeStamp = r.fTimeStamp;
91}
92
93////////////////////////////////////////////////////////////////////////////////
94/// Returns this request's signature
95
97{
98 // Please note, the order of the fields used for computing
99 // the signature is important. Make sure that the changes you
100 // make are compatible with the reference documentation.
101 //
102 // Refs:
103 // AMAZON http://awsdocs.s3.amazonaws.com/S3/latest/s3-qrc.pdf
104 // GOOGLE: http://code.google.com/apis/storage/docs/reference/v1/developer-guidev1.html#authentication
105
106 TString toSign = TString::Format("%s\n\n\n%s\n", // empty Content-MD5 and Content-Type
107 (const char*)HTTPVerbToTString(httpVerb),
108 (const char*)fTimeStamp);
109 if (fAuthType == kGoogle) {
110 // Must use API version 1. Google Storage API v2 only
111 // accepts OAuth authentication.
112 // This header is not strictly needed but if used for computing
113 // the signature, the request must contain it as a header
114 // (see method MakeAuthHeader)
115 // Ref: https://developers.google.com/storage/docs/reference/v1/apiversion1
116 toSign += "x-goog-api-version:1\n"; // Lowercase, no spaces around ':'
117 }
118
119 if (fAuthType == kAmazon) {
120 if (!fSessionToken.IsNull()) {
121 toSign += "x-amz-security-token:" + fSessionToken + "\n";
122 }
123 }
124
125 toSign += "/" + fBucket + fObjectKey;
126
127 unsigned char digest[SHA_DIGEST_LENGTH] = {0};
128#if defined(MAC_OS_X_VERSION_10_7)
129 CCHmac(kCCHmacAlgSHA1, fSecretKey.Data(), fSecretKey.Length() , (unsigned char *)toSign.Data(), toSign.Length(), digest);
130#else
131 unsigned int *sd = NULL;
132 HMAC(EVP_sha1(), fSecretKey.Data(), fSecretKey.Length() , (unsigned char *)toSign.Data(), toSign.Length(), digest, sd);
133#endif
134
135 return TBase64::Encode((const char *)digest, SHA_DIGEST_LENGTH);
136}
137
138////////////////////////////////////////////////////////////////////////////////
139
141{
142 switch (httpVerb) {
143 case kGET: return TString("GET");
144 case kPOST: return TString("POST");
145 case kPUT: return TString("PUT");
146 case kDELETE: return TString("DELETE");
147 case kHEAD: return TString("HEAD");
148 case kCOPY: return TString("COPY");
149 default: return TString("");
150 }
151}
152
153////////////////////////////////////////////////////////////////////////////////
154/// Sets this request's time stamp according to:
155/// http://code.google.com/apis/storage/docs/reference-headers.html#date
156
158{
159 time_t now = time(NULL);
160 char result[128];
161 struct tm dateFormat;
162#ifdef R__WIN32
164 strftime(result, sizeof(result), "%a, %d %b %Y %H:%M:%S GMT", &dateFormat);
165#else
166 strftime(result, sizeof(result), "%a, %d %b %Y %H:%M:%S GMT",
168#endif
170 return *this;
171}
172
173////////////////////////////////////////////////////////////////////////////////
174/// Returns the first line of a HTTP request for this object. Note that since
175/// we don't use the virtual host syntax which is supported by Amazon, we
176/// must include the bucket name in thr resource. For example, we don't use
177/// http://mybucket.s3.amazonaws.com/path/to/my/file but instead
178/// http://s3.amazonaws.com/mybucket/path/to/my/file so the HTTP request
179/// will be of the form "GET /mybucket/path/to/my/file HTTP/1.1"
180/// Also note that the path must include the leading '/'.
181
183{
184 return TString::Format("%s /%s%s HTTP/1.1",
185 (const char*)HTTPVerbToTString(httpVerb),
186 (const char*)fBucket,
187 (const char*)fObjectKey);
188}
189
190////////////////////////////////////////////////////////////////////////////////
191/// Returns the 'Host' header to include in the HTTP request.
192
194{
195 return "Host: " + fHost;
196}
197
198////////////////////////////////////////////////////////////////////////////////
199/// Returns the date header for this HTTP request
200
202{
203 return "Date: " + fTimeStamp;
204}
205
206////////////////////////////////////////////////////////////////////////////////
207/// Returns the session security token header for this HTTP request
208
210{
211 if (fAuthType != kAmazon)
212 return "";
213
214 if (fSessionToken.IsNull())
215 return "";
216
217 return TString::Format("x-amz-security-token: %s",
218 (const char*) fSessionToken.Data());
219}
220
221////////////////////////////////////////////////////////////////////////////////
222/// Returns the authentication prefix
223
225{
226 switch (fAuthType) {
227 case kNoAuth: return "";
228 case kGoogle: return "GOOG1";
229 case kAmazon:
230 default: return "AWS";
231 }
232}
233
234////////////////////////////////////////////////////////////////////////////////
235/// Returns the authentication header for this HTTP request
236
238{
239 if (fAuthType == kNoAuth)
240 return "";
241
242 return TString::Format("Authorization: %s %s:%s%s",
243 (const char*)MakeAuthPrefix(),
244 (const char*)fAccessKey,
245 (const char*)ComputeSignature(httpVerb),
246 (fAuthType == kGoogle) ? "\r\nx-goog-api-version: 1" : "");
247}
248
249////////////////////////////////////////////////////////////////////////////////
250/// Returns the HTTP request ready to be sent to the server
251
253{
254 // Set time stamp before computing this request's signature. The signature
255 // includes the date.
256 SetTimeStamp();
257 TString request = TString::Format("%s\r\n%s\r\n%s\r\n",
258 (const char*)MakeRequestLine(httpVerb),
259 (const char*)MakeHostHeader(),
260 (const char*)MakeDateHeader());
262 if (!tokenHeader.IsNull())
263 request += tokenHeader + "\r\n";
265 if (!authHeader.IsNull())
266 request += authHeader + "\r\n";
267 if (appendCRLF)
268 request += "\r\n";
269 return request;
270}
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t r
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t result
static TString Encode(const char *data)
Transform data into a null terminated base64 string.
Definition TBase64.cxx:106
Mother of all ROOT objects.
Definition TObject.h:41
TString fSessionToken
TString GetRequest(TS3HTTPRequest::EHTTPVerb httpVerb, Bool_t appendCRLF=kTRUE)
Returns the HTTP request ready to be sent to the server.
TString HTTPVerbToTString(EHTTPVerb httpVerb) const
TString MakeAuthPrefix() const
Returns the authentication prefix.
EAuthType fAuthType
TString MakeTokenHeader() const
Returns the session security token header for this HTTP request.
TS3HTTPRequest & SetTimeStamp()
Sets this request's time stamp according to: http://code.google.com/apis/storage/docs/reference-heade...
TString ComputeSignature(TS3HTTPRequest::EHTTPVerb httpVerb) const
Returns this request's signature.
TString MakeRequestLine(TS3HTTPRequest::EHTTPVerb httpVerb) const
Returns the first line of a HTTP request for this object.
TString MakeAuthHeader(TS3HTTPRequest::EHTTPVerb httpVerb) const
Returns the authentication header for this HTTP request.
TString MakeHostHeader() const
Returns the 'Host' header to include in the HTTP request.
TString MakeDateHeader() const
Returns the date header for this HTTP request.
Basic string class.
Definition TString.h:138
Ssiz_t Length() const
Definition TString.h:425
const char * Data() const
Definition TString.h:384
Bool_t IsNull() const
Definition TString.h:422
static TString Format(const char *fmt,...)
Static method which formats a string using a printf style format descriptor and return a TString.
Definition TString.cxx:2384