When including the header options to copy_object, the headers DO NOT get updated.
Headers don't get updated until I make a separate call using update_object. I hope I'm doing something wrong, but I've tested this 4-5 different ways even getting into the sdk code to poke around.
Is this a bug?
I'm using the latest 1.4.3 SDK
Here is my call:
$amazonS3->copy_object(
array( //Source
'bucket' => SOURCE_BUCKET,
'filename' => $source_file
),
array( //Target
'bucket' => VIDEO_BUCKET,
'filename' => $dest_file,
),
array( //Options
'acl' => AmazonS3::ACL_PRIVATE,
'headers' => array(
'Content-Type' => 'application/octet-stream',
'Content-Disposition' => 'attachment'
)
);
I had this problem myself and solved it iamdev. After about a half-day of going insane, I started looking at the actual API rather than just trying to use it.
In sdk.class.php, on line 1690, you'll see the following:
if (isset($opt['metadataDirective']))
$opt['headers']['x-amz-metadata-directive'] = $opt['metadataDirective'];
unset($opt['metadataDirective']);
}
This means if you are not copying an object to itself, it will not replace the key, hence not update it.
What worked for me was explicitly setting the metadataDirective in my opts in my call, so:
$amazonS3->copy_object(
array( //Source
'bucket' => SOURCE_BUCKET,
'filename' => $source_file
),
array( //Target
'bucket' => VIDEO_BUCKET,
'filename' => $dest_file,
),
array( //Options
'acl' => AmazonS3::ACL_PRIVATE,
'headers' => array(
'Content-Type' => 'application/octet-stream',
'Content-Disposition' => 'attachment'
),
'metadataDirective' => 'REPLACE',
);
Hope this works for you, although this is an old post and you've probably found a workaround.
Best,
HG
Related
I'm trying to upload to s3 based on the documentation in Eventbrite but I'm getting nowhere. I think it's down to the structure of my request but I've tried multiple different things and nothing is really working and I get a 'Bucket POST must contain a field named 'key' error.
The instructions are here, so it provides you with a presigned POST object, but I can't figure out how to then provide those details in Guzzle
https://www.eventbrite.com/developer/v3/resources/uploads/
I would use the s3client but I don't think it's suitable, as I do not have the region name.
So this is the array back from EB, as given in the documentation
$postFields = [
'key' => $post_args['key'],
'AWSAccessKeyId' => $post_args['AWSAccessKeyId'],
'bucket' => $post_args['bucket'],
'acl' => $post_args['acl'],
'signature' => $post_args['signature'],
'policy' => $post_args['policy'],
];
and I've tried various structures:
$args = [
'query' => $postFields,
'multipart' => [
[
'name' => $instructions_response['body']['file_parameter_name'],
'Content-type' => 'multipart/form-data',
'contents' => $image,
]
],
]
Or
$args = [
'multipart' => [
[
'key' => $post_args['key'],
'AWSAccessKeyId' => $post_args['AWSAccessKeyId'],
'bucket' => $post_args['bucket'],
'acl' => $post_args['acl'],
'signature' => $post_args['signature'],
'policy' => $post_args['policy'],
'name' => $instructions_response['body']['file_parameter_name'],
'Content-type' => 'multipart/form-data',
'contents' => $image,
]
],
];
Or
$args = [
'key' => $post_args['key'],
'AWSAccessKeyId' => $post_args['AWSAccessKeyId'],
'bucket' => $post_args['bucket'],
'acl' => $post_args['acl'],
'signature' => $post_args['signature'],
'policy' => $post_args['policy'],
'multipart' => [
[
'name' => $instructions_response['body']['file_parameter_name'],
'Content-type' => 'multipart/form-data',
'contents' => $image,
]
],
];
(Plus a bunch of more spurious ones that I can't remember anymore)
Anyway, I'm stuck. I just can't think how this POST data is meant to be structured for it to post to S3. I've gone down the rabbit hole with Xdebug and it's still not clear what is even going on when it makes the request tbh
Request called like so
$upload_response = $this->client->request('POST', $upload_url, $args);
UPDATE: It was pointed out to me that whilst 'key' is lowercase in the error message and what comes back from aws, it's capitalised in the documentation. I changed it to 'Key' and now I get 'Conflicting query string parameters: acl, policy'
I'm trying to retrieve a report from the AdExchange Seller API.
I am using the maximum allowed amount of dimensions and metrics so the reports is quite big (>100.000 rows). According to the documentation on large reports this is possible using the limit break feature by adding the alt=media parameter. But I can't figure out how to add that parameter using the Google API client for PHP. I would prefer to stick to the official Google libraries, but I'm open for suggestions.
Note: adding alt=csv or alt=media to the optParams does not work and I can easily access the data if I remove some of the dimensions and metrics.
More specifically I'm using the accounts_reports resource and then the generate method. Looking at the source code (shown below), I can't see anywhere that it would be able to accept a alt parameter, but I'm obviously missing something.
$this->accounts_reports = new Google_Service_AdExchangeSeller_Resource_AccountsReports(
$this,
$this->serviceName,
'reports',
array(
'methods' => array(
'generate' => array(
'path' => 'accounts/{accountId}/reports',
'httpMethod' => 'GET',
'parameters' => array(
'accountId' => array(
'location' => 'path',
'type' => 'string',
'required' => true,
),
'startDate' => array(
'location' => 'query',
'type' => 'string',
'required' => true,
),
'endDate' => array(
'location' => 'query',
'type' => 'string',
'required' => true,
),
'dimension' => array(
'location' => 'query',
'type' => 'string',
'repeated' => true,
),
'filter' => array(
'location' => 'query',
'type' => 'string',
'repeated' => true,
),
'locale' => array(
'location' => 'query',
'type' => 'string',
),
'maxResults' => array(
'location' => 'query',
'type' => 'integer',
),
'metric' => array(
'location' => 'query',
'type' => 'string',
'repeated' => true,
),
'sort' => array(
'location' => 'query',
'type' => 'string',
'repeated' => true,
),
'startIndex' => array(
'location' => 'query',
'type' => 'integer',
),
),
),
)
)
);
Digging further I found this statement in the Google_Service_AdExchangeSeller_Resource_AccountsReports class.
Generate an Ad Exchange report based on the report request sent in the query
parameters. Returns the result as JSON; to retrieve output in CSV format
specify "alt=csv" as a query parameter. (reports.generate)
But how exactly would that work? As far as I can figure out, it doesn't.
Not really an answer but to long for a comment.
I don't think you are going to get that to work with the client library. The client libraries are generated via the Discovery Services API. Which gives information about what parameters the API takes. For some reason this alt=csv is not registered in the discovery services for that API. Its there in the description but its not registered as a parameter. So the Client library itself isn't going to build it for you.
You can see the response I am looking at here
An idea would be to make the change to the client library yourself you have the code. While altering the client libraries manually is not ideal it is doable.
Try and add alt and give it a value of CSV.
I don't have enough experience with the inner workings of the PHP client library but you can post this as an issue on their forum. Mention that its not in discovery they may have an easer way of applying a random parameter to the query string. I doubt it but its worth a shot.
This should be possible with the PHP client library. The following example demonstrates how to do it with the Drive API:
$fileId = '0BwwA4oUTeiV1UVNwOHItT0xfa2M';
$content = $driveService->files->get($fileId, array(
'alt' => 'media' ));
https://developers.google.com/drive/v3/web/manage-downloads#examples
How can one create valid XML files using log4php? The file is not created with valid XML headers. I am using the append option, so I understand I can append to a proper file, but if I want to start a new file I have to make one each time. There must be a proper way to include the XML header if the file is new?
return array(
'appenders' => array(
'default' => array(
'class' => 'LoggerAppenderFile',
'layout' => array(
'class' => 'LoggerLayoutXml',
),
'params' => array(
'file' => $_SERVER['DOCUMENT_ROOT'] . '/logs/log.xml',
'append' => true
),
),
),
'rootLogger' => array(
'appenders' => array('default'),
),
);
This is my config setup.
I would like to create a pure redirect bucket in AWS S3, I am sure the s3client is operational without problems.
$subdomain = 'test.example.com';
$redirectURL = 'https://www.somedomain.com/redirect?someparam';
$bucketID = $s3->createBucket(['Bucket' => $bucket ]);
$arg = array(
'Bucket' => $bucket, // REQUIRED
'WebsiteConfiguration' => array( // REQUIRED
'ErrorDocument' => array( 'Key' => 'err.html', ),
'IndexDocument' => array( 'Suffix' => 'index.html', ),
'RedirectAllRequestsTo' => array('HostName' => $redirectURL, ),
'RoutingRules' => array(
array(
'Redirect' => array(
'HostName' => $redirectURL,
'HttpRedirectCode' => '301',
),
),
),
),
);
$result = $s3->putBucketWebsite($arg);
However, it output following error even i tried to change some other settings.
> Request ID E00C517E4F812581
Error Type client
Error Code MalformedXML
I wonder if there's any hidden setting I need to add on it.
RedirectAllRequestsTo is mutually exclusive with ErrorDocument, IndexDocument, and RoutingRules. If you are redirecting everything elsewhere, there would be no evaluation of the error or index documents, nor would the routing rules be applicable.
RedirectAllRequestsTo
Describes the redirect behavior for every request to this bucket's website endpoint. If this element is present, no other siblings are allowed.
Type: Container
Ancestors: WebsiteConfiguration
http://docs.aws.amazon.com/AmazonS3/latest/API/RESTBucketPUTwebsite.html
finally i got the solution by this, it works
$subdomain = 'test.example.com';
$protocol = 'https';
$redirectURL = 'www.somedomain.com/redirect?someparam';
$bucketID = $s3->createBucket(['Bucket' => $bucket ]);
$arg = array(
'Bucket' => $bucket,
'WebsiteConfiguration' => array(
'RedirectAllRequestsTo' => array('HostName' => $redirectURL, 'Protocol'=>$protocol),
),
);
$result = $s3->putBucketWebsite($arg);
I need to upload my files inside specific directories that I created on my amazon s3 storage. I always uploaded the files on the "absolute path" of my bucket doing something like so:
$s3->putObject(array(
'Bucket' => $bucket,
'ContentType' => $mime,
'Key' => $localImage,
'ACL' => 'public-read',
'SourceFile' => $localImage,
'CacheControl' => 'max-age=172800',
"Expires" => gmdate("D, d M Y H:i:s T", strtotime("+5 years")),
'Metadata' => array(
'profile' => $localImage,
),
));
How can I define where this file should be uploaded on a given directory?
You must include that information in the "Key" parameter. S3 isn't actually a filesystem, it's more like a big (hash table) associative array. The "Bucket" is the name of the hash table, and the "Key" is the key (e.g., $bucket[$key] = $content). So all path/directory information must be a part of the "Key".
$localImage = '/Users/jim/Photos/summer-vacation/DP00342654.jpg';
$s3->putObject(array(
'Bucket' => 'my-uniquely-named-bucket',
'SourceFile' => $localImage,
'Key' => 'photos/summer/' . basename($localImage)
));
thank you Jeremy Lindblom, this is my python example that worked for me.
import boto3
s3 = boto3.resource('s3')
data = open('/home/briansanchez/www/red-hat.jpg', 'rb')
s3.Bucket('briansanchez').put_object(Key='www/red-hat.jpg', Body=data)
Updated code according to the latest SDK of AWS:-
$result = $s3->putObject(array(
'Bucket' => 'bucket name of S3',
'Key' => 'pawan-trying',
'SourceFile' => 'local image path or document root image path ',
'ContentType' => 'image',
'ACL' => 'public-read',
'StorageClass' => 'REDUCED_REDUNDANCY',
'Metadata' => array(
'param1' => 'value 1',
'param2' => 'value 2'
)
));