Php 使用签名URL通过应用程序引擎在地面军事系统上强制下载
我通过以下方式获取我的文件:Php 使用签名URL通过应用程序引擎在地面军事系统上强制下载,php,google-app-engine,google-cloud-storage,pre-signed-url,Php,Google App Engine,Google Cloud Storage,Pre Signed Url,我通过以下方式获取我的文件: require_once 'google/appengine/api/cloud_storage/CloudStorageTools.php'; use google\appengine\api\cloud_storage\CloudStorageTools; $public_link = CloudStorageTools::getPublicUrl("gs://bucket/file.pdf", false); 如果我在浏览器中转到$public\u
require_once 'google/appengine/api/cloud_storage/CloudStorageTools.php';
use google\appengine\api\cloud_storage\CloudStorageTools;
$public_link = CloudStorageTools::getPublicUrl("gs://bucket/file.pdf", false);
如果我在浏览器中转到$public\u link
,它会在浏览器中显示PDF。我正在试图找出如何强制下载此文件
谷歌应用程序引擎只有60秒的超时时间,因此我担心通过GAE无法使用服务功能。有人有什么建议吗
--
编辑
安德烈·伏尔加(Andrei Volga)此前在这篇文章中的回答建议我使用带有响应内容分发
标题的签名URL
到目前为止,我能够创建一个成功显示文件的签名URL,但我无法生成一个具有任何类型头的签名URL,即创建一个将强制下载的签名URL,而不仅仅是显示它
这就是我到目前为止所拥有的,其中大部分是
函数googleBuildConfigurationString($method、$expiration、$file、array$options=[]))
{
$allowedMethods=['GET','HEAD','PUT','DELETE'];
//初始化
$method=strtoupper($method);
$contentType=$options['Content_-Type'];
$contentMd5=$options['Content\u MD5']?base64\u编码($options['Content\u MD5']):'';
$headers=$options['Canonicalized_Extension_headers']?$options['Canonicalized_Extension_headers']。PHP_EOL:“”;
$file=$file?$file:$options['Canonicalized_Resource'];
//证实
if(数组搜索($method,$allowedMethods)==false)
{
抛出新的RuntimeException(“不允许使用方法“{$Method}”);
}
如果(!$expiration)
{
抛出新的RuntimeException(“应提供到期日期”);
}
返回getTimestamp();
$bucket='bucket';
$fileToGet='picture.jpg';
$file=“/{$bucket}/{$fileToGet}”;
$string=googleBuildConfigurationString('GET',$expiration,$file,array(“规范化的_扩展名_头”=>“”));
$signedString=googleSignString($p12FilePath,$string);
$signedUrl=googleBuildSignedUrl($serviceEmail,$file,$expiration,$signedString);
echo$signedUrl;
对于小文件,您可以使用服务
选项,而不是将另存为
选项设置为true的公共URL。请参阅
对于大文件,您可以使用with
response content disposition
参数。但如果我提供的是1GB文件,这不会超过60秒的限制吗?对于任何超过32MB的文件,这都不起作用-这是App Engine上任何响应的限制。我将更新我的答案。我能够成功获得签名URL(检查以前的编辑)但我不知道如何获得正确的标题。有什么建议吗?这是我Java代码中的一个片段。您可以修改它:.append(“&response content disposition=“).append(urlcoder.encode(“attachment;filename=“+”\”+”+“\”+”file.name+“\”,“UTF-8”))
因此,基本上,您需要添加&response content disposition=attachment;filename=
,后跟一个文件名。我会对其进行URL编码,但如果您事先知道文件名并且文件名是URL安全的(例如,没有空格等),则不需要这样做
function googleBuildConfigurationString($method, $expiration, $file, array $options = [])
{
$allowedMethods = ['GET', 'HEAD', 'PUT', 'DELETE'];
// initialize
$method = strtoupper($method);
$contentType = $options['Content_Type'];
$contentMd5 = $options['Content_MD5'] ? base64_encode($options['Content_MD5']) : '';
$headers = $options['Canonicalized_Extension_Headers'] ? $options['Canonicalized_Extension_Headers'] . PHP_EOL : '';
$file = $file ? $file : $options['Canonicalized_Resource'];
// validate
if(array_search($method, $allowedMethods) === false)
{
throw new RuntimeException("Method '{$method}' is not allowed");
}
if(!$expiration)
{
throw new RuntimeException("An expiration date should be provided.");
}
return <<<TXT
{$method}
{$contentMd5}
{$contentType}
{$expiration}
{$headers}{$file}
TXT;
}
function googleSignString($p12FilePath, $string)
{
$certs = [];
if (!openssl_pkcs12_read(file_get_contents($p12FilePath), $certs, 'notasecret'))
{
echo "Unable to parse the p12 file. OpenSSL error: " . openssl_error_string(); exit();
}
$RSAPrivateKey = openssl_pkey_get_private($certs["pkey"]);
$signed = '';
if(!openssl_sign( $string, $signed, $RSAPrivateKey, 'sha256' ))
{
error_log( 'openssl_sign failed!' );
$signed = 'failed';
}
else $signed = base64_encode($signed);
return $signed;
}
function googleBuildSignedUrl($serviceEmail, $file, $expiration, $signature)
{
return "http://storage.googleapis.com{$file}" . "?GoogleAccessId={$serviceEmail}" . "&Expires={$expiration}" . "&Signature=" . urlencode($signature);
}
$serviceEmail = '<EMAIL>';
$p12FilePath = '../../path/to/cert.p12';
$expiration = (new DateTime())->modify('+3hours')->getTimestamp();
$bucket = 'bucket';
$fileToGet = 'picture.jpg';
$file = "/{$bucket}/{$fileToGet}";
$string = googleBuildConfigurationString('GET', $expiration, $file, array("Canonicalized_Extension_Headers" => ''));
$signedString = googleSignString($p12FilePath, $string);
$signedUrl = googleBuildSignedUrl($serviceEmail, $file, $expiration, $signedString);
echo $signedUrl;