+ date = g_strdup_printf("%s, %02d %s %04d %02d:%02d:%02d GMT",
+ wkday[tmp.tm_wday], tmp.tm_mday, month[tmp.tm_mon], 1900+tmp.tm_year,
+ tmp.tm_hour, tmp.tm_min, tmp.tm_sec);
+
+ if (hdl->s3_api == S3_API_SWIFT_1) {
+ if (!bucket) {
+ buf = g_strdup_printf("X-Auth-User: %s", hdl->swift_account_id);
+ headers = curl_slist_append(headers, buf);
+ g_free(buf);
+ buf = g_strdup_printf("X-Auth-Key: %s", hdl->swift_access_key);
+ headers = curl_slist_append(headers, buf);
+ g_free(buf);
+ } else {
+ buf = g_strdup_printf("X-Auth-Token: %s", hdl->x_auth_token);
+ headers = curl_slist_append(headers, buf);
+ g_free(buf);
+ }
+ } else if (hdl->s3_api == S3_API_SWIFT_2) {
+ if (bucket) {
+ buf = g_strdup_printf("X-Auth-Token: %s", hdl->x_auth_token);
+ headers = curl_slist_append(headers, buf);
+ g_free(buf);
+ }
+ buf = g_strdup_printf("Accept: %s", "application/xml");
+ headers = curl_slist_append(headers, buf);
+ g_free(buf);
+ } else if (hdl->s3_api == S3_API_OAUTH2) {
+ if (bucket) {
+ buf = g_strdup_printf("Authorization: Bearer %s", hdl->access_token);
+ headers = curl_slist_append(headers, buf);
+ g_free(buf);
+ }
+ } else {
+ /* Build the string to sign, per the S3 spec.
+ * See: "Authenticating REST Requests" - API Version 2006-03-01 pg 58
+ */
+
+ /* verb */
+ auth_string = g_string_new(verb);
+ g_string_append(auth_string, "\n");
+
+ /* Content-MD5 header */
+ if (md5_hash)
+ g_string_append(auth_string, md5_hash);
+ g_string_append(auth_string, "\n");
+
+ if (content_type) {
+ g_string_append(auth_string, content_type);
+ }
+ g_string_append(auth_string, "\n");
+
+ /* Date */
+ g_string_append(auth_string, date);
+ g_string_append(auth_string, "\n");
+
+ /* CanonicalizedAmzHeaders, sorted lexicographically */
+ if (is_non_empty_string(hdl->user_token)) {
+ g_string_append(auth_string, AMAZON_SECURITY_HEADER);
+ g_string_append(auth_string, ":");
+ g_string_append(auth_string, hdl->user_token);
+ g_string_append(auth_string, ",");
+ g_string_append(auth_string, STS_PRODUCT_TOKEN);
+ g_string_append(auth_string, "\n");
+ }
+
+ if (g_str_equal(verb,"PUT") &&
+ is_non_empty_string(hdl->server_side_encryption)) {
+ g_string_append(auth_string, AMAZON_SERVER_SIDE_ENCRYPTION_HEADER);
+ g_string_append(auth_string, ":");
+ g_string_append(auth_string, hdl->server_side_encryption);
+ g_string_append(auth_string, "\n");
+ }
+
+ if (is_non_empty_string(hdl->storage_class)) {
+ g_string_append(auth_string, AMAZON_STORAGE_CLASS_HEADER);
+ g_string_append(auth_string, ":");
+ g_string_append(auth_string, hdl->storage_class);
+ g_string_append(auth_string, "\n");
+ }
+
+ /* CanonicalizedResource */
+ if (hdl->service_path) {
+ g_string_append(auth_string, hdl->service_path);
+ }
+ g_string_append(auth_string, "/");
+ if (bucket) {
+ if (hdl->use_subdomain)
+ g_string_append(auth_string, bucket);
+ else {
+ esc_bucket = curl_escape(bucket, 0);
+ if (!esc_bucket) goto cleanup;
+ g_string_append(auth_string, esc_bucket);
+ }
+ }
+
+ if (bucket && (hdl->use_subdomain || key))
+ g_string_append(auth_string, "/");
+
+ if (key) {
+ esc_key = curl_escape(key, 0);
+ if (!esc_key) goto cleanup;
+ g_string_append(auth_string, esc_key);
+ }
+
+ if (subresource) {
+ g_string_append(auth_string, "?");
+ g_string_append(auth_string, subresource);
+ }
+
+ /* run HMAC-SHA1 on the canonicalized string */
+ md = g_byte_array_sized_new(EVP_MAX_MD_SIZE+1);
+ HMAC_CTX_init(&ctx);
+ HMAC_Init_ex(&ctx, hdl->secret_key, (int) strlen(hdl->secret_key),
+ EVP_sha1(), NULL);
+ HMAC_Update(&ctx, (unsigned char*) auth_string->str, auth_string->len);
+ HMAC_Final(&ctx, md->data, &md->len);
+ HMAC_CTX_cleanup(&ctx);
+ auth_base64 = s3_base64_encode(md);
+ /* append the new headers */
+ if (is_non_empty_string(hdl->user_token)) {
+ /* Devpay headers are included in hash. */
+ buf = g_strdup_printf(AMAZON_SECURITY_HEADER ": %s",
+ hdl->user_token);
+ headers = curl_slist_append(headers, buf);
+ g_free(buf);
+
+ buf = g_strdup_printf(AMAZON_SECURITY_HEADER ": %s",
+ STS_PRODUCT_TOKEN);
+ headers = curl_slist_append(headers, buf);
+ g_free(buf);
+ }
+
+ if (g_str_equal(verb,"PUT") &&
+ is_non_empty_string(hdl->server_side_encryption)) {
+ buf = g_strdup_printf(AMAZON_SERVER_SIDE_ENCRYPTION_HEADER ": %s",
+ hdl->server_side_encryption);
+ headers = curl_slist_append(headers, buf);
+ g_free(buf);
+ }
+
+ if (is_non_empty_string(hdl->storage_class)) {
+ buf = g_strdup_printf(AMAZON_STORAGE_CLASS_HEADER ": %s",
+ hdl->storage_class);
+ headers = curl_slist_append(headers, buf);
+ g_free(buf);
+ }
+
+ buf = g_strdup_printf("Authorization: AWS %s:%s",
+ hdl->access_key, auth_base64);
+ headers = curl_slist_append(headers, buf);
+ g_free(buf);