summaryrefslogtreecommitdiff
path: root/inc
diff options
context:
space:
mode:
authorBryan Ischo <bryan@ischo.com>2008-07-01 12:08:57 +0000
committerBryan Ischo <bryan@ischo.com>2008-07-01 12:08:57 +0000
commitea132819c17f169c68b4c2ac5993c857a53bded7 (patch)
treec01a327012cdecf51276c530c0083546c7432872 /inc
parentfb76cb2d8fe580babd63c4b45826faa9fe9c8a19 (diff)
downloadceph-libs3-ea132819c17f169c68b4c2ac5993c857a53bded7.tar.gz
* Checkpoint work in progress
Diffstat (limited to 'inc')
-rw-r--r--inc/libs3.h37
-rw-r--r--inc/private.h180
2 files changed, 141 insertions, 76 deletions
diff --git a/inc/libs3.h b/inc/libs3.h
index 41db7ee..d27bcf5 100644
--- a/inc/libs3.h
+++ b/inc/libs3.h
@@ -55,13 +55,13 @@
************************************************************************** **/
/**
- * S3_MAX_KEY_LENGTH is the maximum length of keys that Amazon S3 supports.
+ * S3_MAX_KEY_SIZE is the maximum size of keys that Amazon S3 supports.
**/
-#define S3_MAX_KEY_LENGTH 1024
+#define S3_MAX_KEY_SIZE 1024
/**
- * S3_MAX_META_HEADERS_SIZE is the maximum number of bytes that all
- * x-amz-meta headers passed to Amazon S3 is allowed to contain
+ * S3_MAX_META_HEADERS_SIZE is the maximum number of bytes allowed for
+ * x-amz-meta header names and values in any request passed to Amazon S3
**/
#define S3_MAX_META_HEADER_SIZE 2048
@@ -226,7 +226,7 @@ typedef enum
* updated. Each canned ACL has a predefined value when expanded to a full
* set of S3 ACL Grants.
**/
-typedef enum S3CannedAcl
+typedef enum
{
S3CannedAclNone = 0, /* private */
S3CannedAclRead = 1, /* public-read */
@@ -235,6 +235,17 @@ typedef enum S3CannedAcl
} S3CannedAcl;
+/**
+ * S3MetaDataDirective identifies what the S3 service should do with an
+ * object's metadata when the object is copied.
+ **/
+typedef enum
+{
+ S3MetaDataDirectiveCopy = 0,
+ S3MetaDataDirectiveReplace = 1
+} S3MetaDataDirective;
+
+
/** **************************************************************************
* Data Types
************************************************************************** **/
@@ -479,10 +490,24 @@ typedef struct S3RequestHeaders
/**
* This identifies the "canned ACL" that should be used for this object.
* The default (0) gives only the owner of the object access to it.
+ * This value is ignored for all operations except put_object and
+ * copy_object.
**/
S3CannedAcl cannedAcl;
/**
- * This is the number of headers in the metaHeaders field
+ * For copy operations, this identifies the source object; must be
+ * of the form /source_bucket/source_key. This value is ignored for all
+ * operations except copy_object.
+ **/
+ const char *sourceObject;
+ /**
+ * For copy operations, this gives the metadata directive. This value is
+ * ignored for all operations except copy_object.
+ **/
+ S3MetaDataDirective metaDataDirective;
+ /**
+ * This is the number of headers in the metaHeaders field. Ignored and
+ * assumed to be 0, for all except put_object and copy_object operations.
**/
int metaHeadersCount;
/**
diff --git a/inc/private.h b/inc/private.h
index 6514043..5640313 100644
--- a/inc/private.h
+++ b/inc/private.h
@@ -36,26 +36,112 @@
// Derived from S3 documentation
-// The maximum number of x-amz-meta headers that the user can supply is
-// limited by the fact that every x-amz-meta header must be of the form:
-// x-amz-meta-${NAME}: ${VALUE}
-// where NAME and VALUE must be at least 1 character long, so the shortest
-// x-amz-meta header would be:
-// x-amz-meta-n: v
-// So we take the S3's total limit of 2K and divide it by the length of that
+
+// This is the maximum number of x-amz-meta- headers that could be included in
+// a request to S3. The smallest meta header is" x-amz-meta-n: v". Since S3
+// doesn't count the ": " against the total, the smallest amount of data to
+// count for a header would be the length of "x-amz-meta-nv".
#define MAX_META_HEADER_COUNT \
- (S3_MAX_META_HEADER_SIZE / (sizeof(META_HEADER_NAME_PREFIX "n: v")))
-// Now the total that we allow for all x-amz- headers includes the ones that
-// we additionally add, which is x-amz-acl and x-amz-date
-// 256 bytes will be more than enough to cover those
-#define MAX_AMZ_HEADER_SIZE (S3_MAX_META_HEADER_SIZE + 256)
+ (S3_MAX_META_HEADER_SIZE / (sizeof(META_HEADER_NAME_PREFIX "nv") - 1))
+
+// This is the maximum number of bytes needed in a "compacted meta header"
+// buffer, which is a buffer storing all of the compacted meta headers.
+#define COMPACTED_META_HEADER_BUFFER_SIZE \
+ (MAX_META_HEADER_COUNT * sizeof(META_HEADER_NAME_PREFIX "n: v"))
+
+// Maximum url encoded key size; since every single character could require
+// URL encoding, it's 3 times the size of a key (since each url encoded
+// character takes 3 characters: %NN)
+#define MAX_URLENCODED_KEY_SIZE (3 * S3_MAX_KEY_SIZE)
-#define MAX_CANONICALIZED_RESOURCE_SIZE (S3_MAX_KEY_LENGTH + 1024)
+// This is the maximum size of a URI that could be passed to S3:
+// https://s3.amazonaws.com/${BUCKET}/${KEY}?acl
+// 255 is the maximum bucket length
+#define MAX_URI_SIZE \
+ ((sizeof("https://" HOSTNAME "/") - 1) + 255 + 1 + \
+ MAX_URLENCODED_KEY_SIZE + (sizeof("?torrent" - 1)) + 1)
-#define MAX_URLENCODED_KEY_SIZE (3 * S3_MAX_KEY_LENGTH)
+// Maximum size of a canonicalized resource
+#define MAX_CANONICALIZED_RESOURCE_SIZE \
+ (1 + 255 + 1 + MAX_URLENCODED_KEY_SIZE + (sizeof("?torrent") - 1) + 1)
-// This is the data associated with a request, and is set in the private data
-// of the curl request
+
+// Describes a type of HTTP request (these are our supported HTTP "verbs")
+typedef enum
+{
+ HttpRequestTypeGET,
+ HttpRequestTypeHEAD,
+ HttpRequestTypePUT,
+ HttpRequestTypeCOPY,
+ HttpRequestTypeDELETE
+} HttpRequestType;
+
+
+// This completely describes a request. A RequestParams is not required to be
+// allocated from the heap and its lifetime is not assumed to extend beyond
+// the lifetime of the function to which it has been passed.
+typedef struct RequestParams
+{
+ // The following are supplied ---------------------------------------------
+
+ // Request type, affects the HTTP verb used
+ HttpRequestType httpRequestType;
+ // Protocol to use for request
+ S3Protocol protocol;
+ // URI style to use for request
+ S3UriStyle uriStyle;
+ // Bucket name, if any
+ const char *bucketName;
+ // Key, if any
+ const char *key;
+ // Query params - ready to append to URI (i.e. ?p1=v1?p2=v2)
+ const char *queryParams;
+ // sub resource, like ?acl, ?location, ?torrent
+ const char *subResource;
+ // AWS Access Key ID
+ const char *accessKeyId;
+ // AWS Secret Access Key
+ const char *secretAccessKey;
+ // Request headers
+ const S3RequestHeaders *requestHeaders;
+ // Response handler callback
+ S3ResponseHandler *handler;
+ // Response handler callback data
+ void *callbackData;
+
+ // The following are computed ---------------------------------------------
+
+ // All x-amz- headers, in normalized form (i.e. NAME: VALUE, no other ws)
+ char *amzHeaders[MAX_META_HEADER_COUNT + 2]; // + 2 for acl and date
+ // The number of x-amz- headers
+ int amzHeadersCount;
+ // Storage for amzHeaders (the +256 is for x-amz-acl and x-amz-date)
+ char *amzHeadersRaw[COMPACTED_META_HEADER_BUFFER_SIZE + 256 + 1];
+ // Canonicalized x-amz- headers
+ char canonicalizedAmzHeaders[COMPACTED_META_HEADER_BUFFER_SIZE + 256 + 1];
+ // URL-Encoded key
+ char urlEncodedKey[MAX_URLENCODED_KEY_SIZE + 1];
+ // Canonicalized resource
+ char canonicalizedResource[MAX_CANONICALIZED_RESOURCE_SIZE + 1];
+ // Content-Type header (or empty)
+ char contentTypeHeader[128];
+ // Content-MD5 header (or empty)
+ char md5Header[128];
+ // Content-Disposition header (or empty)
+ char contentDispositionHeader[128];
+ // Content-Encoding header (or empty)
+ char contentEncodingHeader[128];
+ // Expires header (or empty)
+ char expiresHeader[128];
+ // Authorization header
+ char authorizationHeader[128];
+ // Uri
+ char uri[MAX_URI_SIZE + 1];
+} RequestParams;
+
+
+// This is the stuff associated with a request that needs to be on the heap
+// (and thus live while a curl_multi is in use).
typedef struct Request
{
// True if this request has already been used
@@ -64,22 +150,19 @@ typedef struct Request
// The CURL structure driving the request
CURL *curl;
- // The headers that will be sent to S3
- struct curl_slist *headers;
+ // libcurl requires that the uri be stored outside of the curl handle
+ char uri[MAX_URI_SIZE + 1];
// The callback data to pass to all of the callbacks
void *callbackData;
- // responseHeaders.metaHeaders strings get copied into here. Since S3
- // supports a max of 2K for all values and keys, limiting to 2K here is
- // sufficient
- char responseMetaHeaderStrings[S3_MAX_META_HEADER_SIZE];
+ // responseHeaders.metaHeaders strings get copied into here
+ char responseMetaHeaderStrings[COMPACTED_META_HEADER_BUFFER_SIZE];
// The length thus far of metaHeaderStrings
int responseMetaHeaderStringsLen;
- // The maximum number of meta headers possible is:
- // 2K / strlen("x-amz-meta-a:\0\0")
+ // Response meta headers
S3MetaHeader responseMetaHeaders[MAX_META_HEADER_COUNT];
// Callback stuff ---------------------------------------------------------
@@ -148,9 +231,9 @@ S3Status request_api_initialize(const char *userAgentInfo);
void request_api_deinitialize();
// Get a Request that has been initialized, except for the data payload
-// callback pointer
-S3Status request_get(S3ResponseHandler *handler, void *callbackData,
- Request **requestReturn);
+// callback pointer, and is ready to execute via request_multi_add or
+// request_easy_perform
+S3Status request_get(RequestParams *params, Request **requestReturn);
// Release a Request that is no longer needed
void request_release(Request *request);
@@ -166,48 +249,5 @@ void request_easy_perform(Request *request);
// releases the request
void request_finish(Request *request, S3Status status);
-typedef struct XAmzHeaders
-{
- int count;
- char *headers[MAX_META_HEADER_COUNT];
- char headers_raw[MAX_AMZ_HEADER_SIZE];
-} XAmzHeaders;
-
-// Composes the entire list of x-amz- headers, which includes all x-amz-meta-
-// headers and any other headers. Each one is guaranteed to be of the form:
-// [HEADER]: [VALUE]
-// Where HEADER and VALUE have no whitespace in them, and they are separated
-// by exactly ": "
-// There may be duplicate x-amz-meta- headers returned
-// All header names will be lower cased
-S3Status request_compose_x_amz_headers(XAmzHeaders *xAmzHeaders,
- const S3RequestHeaders *requestHeaders);
-
-// buffer must be at least MAX_URLENCODED_KEY_SIZE bytes
-void request_encode_key(char *buffer, const char *key);
-
-
-// Authorization functions
-// ------------------------------------------------------------
-
-// Canonicalizes the given x-amz- headers into the given buffer with the
-// given bufferSize. buffer must be at least S3_MAX_AMZ_HEADER_SIZE bytes.
-void canonicalize_amz_headers(char *buffer, const XAmzHeaders *xAmzHeaders);
-
-// Canonicalizes a resource into buffer; buffer must be at least
-// MAX_CANONICALIZED_RESOURCE_SIZE bytes long. subResource is one of:
-// "acl", "location", "logging", and "torrent"
-void canonicalize_resource(char *buffer, S3UriStyle uriStyle,
- const char *bucketName,
- const char *encodedKey, const char *subResource);
-
-S3Status auth_header_snprintf(char *buffer, int bufferSize,
- const char *accessKeyId,
- const char *secretAccessKey,
- const char *httpVerb, const char *md5,
- const char *contentType,
- const char *canonicalizedAmzHeaders,
- const char *canonicalizedResource);
-
#endif /* PRIVATE_H */