summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBryan Ischo <bryan@ischo.com>2008-09-28 05:08:56 +0000
committerBryan Ischo <bryan@ischo.com>2008-09-28 05:08:56 +0000
commit8cc18cbb67d459076d6d3df08b02c531d5ccc08f (patch)
tree8a93d3224e820b96d010fbf0f59dedca81069923 /src
parent1dc8c62abe2e638eb6220ff420662fb11f611cd5 (diff)
downloadceph-libs3-8cc18cbb67d459076d6d3df08b02c531d5ccc08f.tar.gz
* Remove time_t from API, replace with int64_t, which is of known size and
avoids problems with structure sizes of precompiled libraries differing from that of compiled programs using libs3 * Fixed S3RequestContext functionality; it was untested and nonworking before this change * Added S3_get_request_context_timeout function for allowing callers to assist libs3 to support curl internal timeouts
Diffstat (limited to 'src')
-rw-r--r--src/object.c4
-rw-r--r--src/request.c12
-rw-r--r--src/request_context.c35
-rw-r--r--src/s3.c23
-rw-r--r--src/util.c4
5 files changed, 53 insertions, 25 deletions
diff --git a/src/object.c b/src/object.c
index dd77c61..0f33655 100644
--- a/src/object.c
+++ b/src/object.c
@@ -80,7 +80,7 @@ typedef struct CopyObjectData
S3ResponseCompleteCallback *responseCompleteCallback;
void *callbackData;
- time_t *lastModifiedReturn;
+ int64_t *lastModifiedReturn;
int eTagReturnSize;
char *eTagReturn;
int eTagReturnLen;
@@ -165,7 +165,7 @@ static void copyObjectCompleteCallback(S3Status requestStatus,
void S3_copy_object(const S3BucketContext *bucketContext, const char *key,
const char *destinationBucket, const char *destinationKey,
const S3PutProperties *putProperties,
- time_t *lastModifiedReturn, int eTagReturnSize,
+ int64_t *lastModifiedReturn, int eTagReturnSize,
char *eTagReturn, S3RequestContext *requestContext,
const S3ResponseHandler *handler, void *callbackData)
{
diff --git a/src/request.c b/src/request.c
index d5b455e..79837fa 100644
--- a/src/request.c
+++ b/src/request.c
@@ -431,9 +431,9 @@ static S3Status compose_standard_headers(const RequestParams *params,
// Expires
if (params->putProperties && (params->putProperties->expires >= 0)) {
+ time_t t = (time_t) params->putProperties->expires;
strftime(values->expiresHeader, sizeof(values->expiresHeader),
- "Expires: %a, %d %b %Y %H:%M:%S UTC",
- gmtime(&(params->putProperties->expires)));
+ "Expires: %a, %d %b %Y %H:%M:%S UTC", gmtime(&t));
}
else {
values->expiresHeader[0] = 0;
@@ -442,10 +442,10 @@ static S3Status compose_standard_headers(const RequestParams *params,
// If-Modified-Since
if (params->getConditions &&
(params->getConditions->ifModifiedSince >= 0)) {
+ time_t t = (time_t) params->getConditions->ifModifiedSince;
strftime(values->ifModifiedSinceHeader,
sizeof(values->ifModifiedSinceHeader),
- "If-Modified-Since: %a, %d %b %Y %H:%M:%S UTC",
- gmtime(&(params->getConditions->ifModifiedSince)));
+ "If-Modified-Since: %a, %d %b %Y %H:%M:%S UTC", gmtime(&t));
}
else {
values->ifModifiedSinceHeader[0] = 0;
@@ -454,10 +454,10 @@ static S3Status compose_standard_headers(const RequestParams *params,
// If-Unmodified-Since header
if (params->getConditions &&
(params->getConditions->ifNotModifiedSince >= 0)) {
+ time_t t = (time_t) params->getConditions->ifNotModifiedSince;
strftime(values->ifUnmodifiedSinceHeader,
sizeof(values->ifUnmodifiedSinceHeader),
- "If-Unmodified-Since: %a, %d %b %Y %H:%M:%S UTC",
- gmtime(&(params->getConditions->ifNotModifiedSince)));
+ "If-Unmodified-Since: %a, %d %b %Y %H:%M:%S UTC", gmtime(&t));
}
else {
values->ifUnmodifiedSinceHeader[0] = 0;
diff --git a/src/request_context.c b/src/request_context.c
index 567f51a..d049778 100644
--- a/src/request_context.c
+++ b/src/request_context.c
@@ -75,13 +75,25 @@ S3Status S3_runall_request_context(S3RequestContext *requestContext)
int requestsRemaining;
do {
fd_set readfds, writefds, exceptfds;
+ FD_ZERO(&readfds);
+ FD_ZERO(&writefds);
+ FD_ZERO(&exceptfds);
int maxfd;
S3Status status = S3_get_request_context_fdsets
(requestContext, &readfds, &writefds, &exceptfds, &maxfd);
if (status != S3StatusOK) {
return status;
}
- select(maxfd + 1, &readfds, &writefds, &exceptfds, 0);
+ // curl will return -1 if it hasn't even created any fds yet because
+ // none of the connections have started yet. In this case, don't
+ // do the select at all, because it will wait forever; instead, just
+ // skip it and go straight to running the underlying CURL handles
+ if (maxfd != -1) {
+ int64_t timeout = S3_get_request_context_timeout(requestContext);
+ struct timeval tv = { timeout / 1000, (timeout % 1000) * 1000 };
+ select(maxfd + 1, &readfds, &writefds, &exceptfds,
+ (timeout == -1) ? 0 : &tv);
+ }
status = S3_runonce_request_context(requestContext,
&requestsRemaining);
if (status != S3StatusOK) {
@@ -115,13 +127,11 @@ S3Status S3_runonce_request_context(S3RequestContext *requestContext,
CURLMsg *msg;
int junk;
while ((msg = curl_multi_info_read(requestContext->curlm, &junk))) {
- if ((msg->msg != CURLMSG_DONE) ||
- (curl_multi_remove_handle(requestContext->curlm,
- msg->easy_handle) != CURLM_OK)) {
+ if (msg->msg != CURLMSG_DONE) {
return S3StatusInternalError;
}
Request *request;
- if (curl_easy_getinfo(msg->easy_handle, CURLOPT_PRIVATE,
+ if (curl_easy_getinfo(msg->easy_handle, CURLINFO_PRIVATE,
(char *) &request) != CURLE_OK) {
return S3StatusInternalError;
}
@@ -143,6 +153,10 @@ S3Status S3_runonce_request_context(S3RequestContext *requestContext,
request->status = request_curl_code_to_status
(msg->data.result);
}
+ if (curl_multi_remove_handle(requestContext->curlm,
+ msg->easy_handle) != CURLM_OK) {
+ return S3StatusInternalError;
+ }
// Finish the request, ensuring that all callbacks have been made,
// and also releases the request
request_finish(request);
@@ -160,3 +174,14 @@ S3Status S3_get_request_context_fdsets(S3RequestContext *requestContext,
exceptFdSet, maxFd) == CURLM_OK) ?
S3StatusOK : S3StatusInternalError);
}
+
+int64_t S3_get_request_context_timeout(S3RequestContext *requestContext)
+{
+ long timeout;
+
+ if (curl_multi_timeout(requestContext->curlm, &timeout) != CURLM_OK) {
+ timeout = 0;
+ }
+
+ return timeout;
+}
diff --git a/src/s3.c b/src/s3.c
index 895c0c7..55ee2ac 100644
--- a/src/s3.c
+++ b/src/s3.c
@@ -696,9 +696,9 @@ static S3Status responsePropertiesCallback
print_nonnull("ETag", eTag);
if (properties->lastModified > 0) {
char timebuf[256];
+ time_t t = (time_t) properties->lastModified;
// gmtime is not thread-safe but we don't care here.
- strftime(timebuf, sizeof(timebuf), "%Y-%m-%dT%H:%M:%SZ",
- gmtime(&(properties->lastModified)));
+ strftime(timebuf, sizeof(timebuf), "%Y-%m-%dT%H:%M:%SZ", gmtime(&t));
printf("Last-Modified: %s\n", timebuf);
}
int i;
@@ -782,7 +782,7 @@ static void printListServiceHeader(int allDetails)
static S3Status listServiceCallback(const char *ownerId,
const char *ownerDisplayName,
const char *bucketName,
- time_t creationDate, void *callbackData)
+ int64_t creationDate, void *callbackData)
{
list_service_data *data = (list_service_data *) callbackData;
@@ -793,8 +793,8 @@ static S3Status listServiceCallback(const char *ownerId,
char timebuf[256];
if (creationDate >= 0) {
- strftime(timebuf, sizeof(timebuf), "%Y-%m-%dT%H:%M:%SZ",
- gmtime(&creationDate));
+ time_t t = (time_t) creationDate;
+ strftime(timebuf, sizeof(timebuf), "%Y-%m-%dT%H:%M:%SZ", gmtime(&t));
}
else {
timebuf[0] = 0;
@@ -1090,8 +1090,9 @@ static S3Status listBucketCallback(int isTruncated, const char *nextMarker,
const S3ListBucketContent *content = &(contents[i]);
char timebuf[256];
if (0) {
+ time_t t = (time_t) content->lastModified;
strftime(timebuf, sizeof(timebuf), "%Y-%m-%dT%H:%M:%SZ",
- gmtime(&(content->lastModified)));
+ gmtime(&t));
printf("\nKey: %s\n", content->key);
printf("Last Modified: %s\n", timebuf);
printf("ETag: %s\n", content->eTag);
@@ -1104,8 +1105,9 @@ static S3Status listBucketCallback(int isTruncated, const char *nextMarker,
}
}
else {
- strftime(timebuf, sizeof(timebuf), "%Y-%m-%dT%H:%M:%SZ",
- gmtime(&(content->lastModified)));
+ time_t t = (time_t) content->lastModified;
+ strftime(timebuf, sizeof(timebuf), "%Y-%m-%dT%H:%M:%SZ",
+ gmtime(&t));
char sizebuf[16];
if (content->size < 100000) {
sprintf(sizebuf, "%5llu", (unsigned long long) content->size);
@@ -1749,7 +1751,7 @@ static void copy_object(int argc, char **argv, int optind)
&responseCompleteCallback
};
- time_t lastModified;
+ int64_t lastModified;
char eTag[256];
do {
@@ -1762,8 +1764,9 @@ static void copy_object(int argc, char **argv, int optind)
if (statusG == S3StatusOK) {
if (lastModified >= 0) {
char timebuf[256];
+ time_t t = (time_t) lastModified;
strftime(timebuf, sizeof(timebuf), "%Y-%m-%dT%H:%M:%SZ",
- gmtime(&lastModified));
+ gmtime(&t));
printf("Last-Modified: %s\n", timebuf);
}
if (eTag[0]) {
diff --git a/src/util.c b/src/util.c
index 4557d0e..613f695 100644
--- a/src/util.c
+++ b/src/util.c
@@ -95,7 +95,7 @@ int urlEncode(char *dest, const char *src, int maxSrcSize)
}
-time_t parseIso8601Time(const char *str)
+int64_t parseIso8601Time(const char *str)
{
// Check to make sure that it has a valid format
if (!checkString(str, "dddd-dd-ddTdd:dd:dd")) {
@@ -130,7 +130,7 @@ time_t parseIso8601Time(const char *str)
stm.tm_isdst = -1;
- time_t ret = mktime(&stm);
+ int64_t ret = mktime(&stm);
// Skip the millis