OSS在文件上传完成的时,可以提供回调(Callback)给用户的回调服务器(Callback Server)。在上传请求中携带相应的回调参数,即能实现上传回调。支持上传回调的 API 接口有:PutObject、PostObject、CompleteMultipartUpload。
更详细的介绍请参看 开发人员指南、API。
提示:回调服务器(Callback Server),有时也叫业务服务器。
OSS上传回调流程,如下图:
-----------1---------> -----------2---------> 客户端(SDK/PostObject) OSS 回调服务器(Callback Server) <----------4---------- <----------3----------上图中的数据流含义,见下表:
数据流含义说明1上传文件并携带回调参数1通过SDK(PutObject、CompleteMultipartUpload)/PostObject完成2OSS存储文件后发起回调OSS向上传请求中指定的 CallbackUrl 发起 POST2 请求,回调超时时间是 5秒33回调服务器返回处理结果回调服务器返回的消息体一定要是 Json 格式;OSS认为非 200 请求为回调失败44OSS返回上传、回调结果上传、回调都成功,返回 200;上传成功、回调失败返回 203, ErrorCode为 CallbackFailed, ErrorMessage描述错误原因注:
[1] 格式请参看SDK/PostObject;[2] 回调请求POST的格式详见 发起回调请求;[3] 超时时间为固定值,不支持配置;[4] 参数无效、认真失败返回40x,超时、无法连接返回50x。上传时可以通过设置回调参数,指定回调服务器URL、发送给回调服务器的数据、格式等。回调服务器处理回调时,需要一些上下文信息,如bucket、object等,通过系统变量指定;系统变量以外的上下文信息,通过自定义变量指定。
上传回调包括以下参数:
字段含义说明callbackUrl回调服务器地址必选参数callbackHost回调请求消息头中Host的值可选参数,默认为callbackUrl callbackBody回调请求的消息体必选参数,内容可以包括系统变量和自定义变量callbackBodyType回调请求消息头中Content-Type的值,即callbackBody的数据格式可选参数,支持application/x-www-form-urlencoded和application/json,默认为前者上传回调参数通过上传请求携带,有两种方式:
通过消息头中的 x-oss-callback,携带回调参数。这种方式比较常用,推荐该方式;通过QueryString的 callback,携带回调参数。x-oss-callback 或 callback 的值生成规则如下:
Callback := Base64(CallbackJson) CallbackJson := '{' CallbackUrlItem, CallbackBodyItem [, CallbackHostItem, CallbackBodyTypeItem] '}' CallbackUrlItem := '"'callbackUrl'"' ':' '"'CallbackUrlValue'"' CallbackBodyItem := '"'callbackBody'"' ':' '"'CallbackBodyValue'"' CallbackHostItem := '"'callbackHost'"' ':' '"'CallbackHostValue'"' CallbackBodyTypeItem := '"'callbackBodyType'"' : '"'CallbackBodyType'"' CallbackBodyType := application/x-www-form-urlencoded | application/jsonCallbackJson的值示例如下:
{ "callbackUrl" : "http://abc.com/test.php", "callbackHost" : "oss-cn-hangzhou.aliyuncs.com", "callbackBody" : "{\"bucket\":${mimeType}, \"object\":${object},\"size\":${size},\"mimeType\":${mimeType},\"my_var\":${x:my_var}}", "callbackBodyType" : "application/json" }或
{ "callbackUrl" : "http://abc.com/test.php", "callbackBody" : "bucket=${bucket}&object=${object}&etag=${etag}&size=${size}&mimeType=${mimeType}&my_var=${x:my_var}" }CallbackJson示例中的 callbackBody 包括如 ${bucket}、${object}、${size} 的变量,即为OSS定义的系统变量,OSS回调时会用实际值替换掉系统变量。OSS定义的系统变量如下表:
变量含义${bucket}存储空间名称${object}文件名称${etag}文件的ETag${size}文件大小${mimeType}文件类型,如image/jpeg等${imageInfo.height}图片高度${imageInfo.width}图片宽度${imageInfo.format}图片格式,如jpg、png等注意:
系统变量大小写敏感;系统的变量的格式一定是 ${bucket};imageInfo针对于图片格式,为非图片格式值为空。CallbackJson示例中的 callbackBody 包括如 ${x:my_var} 的变量,即自定义变量,OSS回调时会用自定义的值替换掉自定义变量。自定义变量的值可以在上传请求中定义并携带,有以下两种方式:
通过消息头中的 x-oss-callback-var,携带自定义变量。这种方式比较常用,也是推荐方式;通过QueryString的callback-var,携带自定义变量。x-oss-callback-var 或 callback-var 的生成规则如下:
CallbackVar := Base64(CallbackVarJson) CallbackVarJson := '{' CallbackVarItem [, CallbackVarItem]* '}' CallbackVarItem := '"''x:'VarName'"' : '"'VarValue'"'CallbackVarJson 的值示例如下:
{ "x:my_var1" : "value1", "x:my_var2" : "value2" }注意:
自定义变量必须以 x: 开头,大小写敏感,格式是 ${x:my_var};自定义变量的长度受消息头、URL的长度限制,建议自定义变量不超过10个,总长度不超过512Byte。部分SDK对上述步骤进行了封装,如Java、JS;部分SDK需要使用上面的规则生成上传回调参数和自定义变量,如Python、PHP、C。SDK的使用示例如下:
SDK上传回调示例说明JavaCallbackSample.java注意CallbackBody中的转义字符Pythonobject_callback.py PHPCallback.php注意上传的$options中OSS_CALLBACK、OSS_CALLBACK_VAR不需要base64,SDK会做C#UploadCallbackSample.cs注意 PutObjectResult.ResponseStream 请使用 using 读取,确保关闭JSobject.test.js Coss_callback_sample.c Rubycallback.rb iOS上传后回调通知注意<var1> 的格式应该是x:var1 Andriod上传后回调通知注意CallbackBody中的转义字符注意:C# SDK、Go SDK尚不支持上传回调。
PostObject支持上传回调,回调参数通过表单域callback携带,自定义变量通过独立的表单域携带,详细请参看 PostObjet。PostObject的使用示例如下:
SDK上传回调示例JavaPostObjectSample.javaPythonobject_post.pyJSJavaScript客户端签名直传C#PostPolicySample.cs回调服务器(Callback Server),是一个HTTP服务器,处理OSS发送的回调请求,POST消息。回调服务器的URL即上传回调参数中的 callbackUrl。回调服务器是用户自己实现的处理逻辑,实现上传数据的记录、审查、处理、统计等。
回调服务器为了确认收到的POST请求,来自于OSS的上传回调,需要验证该POST消息的签名。当然,回调服务器也可以不验证签名,直接处理该消息。为了提高回调服务器的安全性,建议验证消息签名。回调签名规则请参看回调签名。
提示:OSS的回调服务器示例中提供了签名校验的实现,推荐直接使用该部分代码。
回调服务器的主要逻辑,对OSS的回调请求进行处理。以下几点请注意:
回调服务器必须处理OSS的 POST 请求;OSS回调的超时时间是 5秒,回调服务器必须在5秒内完成处理并返回;回调服务器返回给OSS的消息体必须是 JSON 格式;回调服务器是用户自己的逻辑,OSS提供示例而不提供具体业务逻辑实现。回调服务器的实现示例如下:
语言示例运行方法JavaAppCallbackServer.zip解压后执行java -jar oss-callback-server-demo.jar 9000 PHPcallback-php-demo.zip Apache环境下部署运行Pythoncallback_app_server.py.zip解压后执行python callback_app_server.py Rubyoss-callback-server执行ruby aliyun_oss_callback_server.rb上传回调的调试分为两部分,上传的客户端、处理回调的回调服务器。建议先调试客户端上传部分,再调试回调服务器部分。两部分单独调试完成后,再运行完整的上传回调。
客户端调试时,可使用OSS提供的回调服务器 http://callback.oss-demo.com:23450,即回调参数 callbackUrl。该回调服务器只验证回调请求的签名,对回调请求不做处理。对于签名验证成功的回调请求,返回 {"Status":"OK"};签名验证失败的回调请求,返回 400 Bad Request;非POST请求返回501 Unsupported method。示例回调服务器的代码请参看callback_app_server.py.zip
回调服务器是一个支持处理 POST 请求的 HTTP 服务器,可以在OSS提供的示例基础上修改,也可以自己独立实现。OSS提供的回调服务器示例:
语言示例运行方法JavaAppCallbackServer.zip解压后执行java -jar oss-callback-server-demo.jar 9000 PHPcallback-php-demo.zip Apache环境下部署运行Pythoncallback_app_server.py.zip解压后执行python callback_app_server.py C#callback-server-dotnet.zip编译后执行aliyun-oss-net-callback-server.exe 127.0.0.1 80 Gocallback-server-go.zip编译后执行aliyun_oss_callback_server Rubyoss-callback-server执行ruby aliyun_oss_callback_server.rb回调服务器可以通过 cRUL 命令调试,下面几个命令可能会用到:
# 向回调服务器发送消息体为 `object=test_obj` 的 `POST` 请求,可以使用如下命令 curl -d "object=test_obj" http://callback.oss-demo.com:23450 -v # 向回调服务器发送消息体为文件 `post.txt` 内容 的 `POST` 请求,可以使用如下命令 curl -d @post.txt http://callback.oss-demo.com:23450 -v #向回调服务器发送消息体为文件 `post.txt` 内容的 `POST` 请求,并携带指定的消息头 `Content-Type` curl -d @post.txt -H "Content-Type: application/json" http://callback.oss-demo.com:23450 -v注意:
调试回调服务器时,可以先忽略签名验证部分,因为 cURL 模拟签名功能比较困难;签名验证功能OSS示例中已经提供,建议直接使用;回调服务器建议有日志功能,记录收到的所有消息,方便调试、跟踪;回调服务器正确处理回调请求后,一定要返回 200,而不是其它的 20x;回调服务器返回给OSS的消息体,一定要是 JSON 格式,Content-Type 设置为application/json。原因:回调参数设置错误,或参数格式错误。常见的错误是ArgumentValue之间的回调参数,不是有效 JSON 格式。在 JSON 中 \、" 是转移字符,如 "callbackBody":"{"bucket":${bucket},"object":${object}}"应该为 "callbackBody":"{\"bucket\":${bucket},\"object\":${object}}"。针对具体的SDK,请参看对应的上传回调示例,详细请参考 SDK使用示例 部分。
转义后的字符转义前的字符\\\\\\"\\"\b\b\f\f\n\n\r\r\t\t原因:回调服务器返回给OSS的消息体非 JSON 格式。您可以通过 curl -d "<Content>" <CallbackServerURL> -v或抓包确认内容。Windows下推荐使用工具 Wireshark 抓包,Linux下使用命令 tcpdump 抓包。一些非法返回消息体如下:OK,\357\273\277{"Status":"OK"}(即含有ef bb bf三个字节的BOM头)等
<Error> <Code>CallbackFailed</Code> <Message>Error status : -1.OSS can not connect to your callbackUrl, please check it.</Message> <RequestId>587C8735355BE8694A8E9100</RequestId> <HostId>bucket.oss-cn-hangzhou.aliyuncs.com</HostId> </Error>原因:回调服务器处理时间超过 5秒,OSS认为超时。建议回调服务器的处理逻辑修改为异步,保证在5秒内处理完毕并返回结果OSS。
<Error> <Code>CallbackFailed</Code> <Message>Error status : -1 8.8.8.8:9090 reply timeout, cost:5000ms, timeout:5000ms (err -4, errno115)</Message> <RequestId>587C8D382AE0B92FA3EEF62C</RequestId> <HostId>bucket.oss-cn-hangzhou.aliyuncs.com</HostId> </Error>原因:回调服务器处理时间超过5秒,OSS认为超时。
<Error> <Code>CallbackFailed</Code> <Message>Error status : 400.</Message> <RequestId>587C89A02AE0B92FA3C7981D</RequestId> <HostId>bucket.oss-cn-hangzhou.aliyuncs.com</HostId> </Error>原因:回调服务器返回给OSS的消息的状态码是400,请检查回调服务器的处理逻辑。
<Error> <Code>CallbackFailed</Code> <Message>Error status : 502.</Message> <RequestId>587C8D382AE0B92FA3EEF62C</RequestId> <HostId>bucket.oss-cn-hangzhou.aliyuncs.com</HostId> </Error>原因:回调服务器未启动,或者上传回调参数中的CallbackUrl,或者OSS与回调服务器的网络不通。推荐在ECS上部署回调服务器,与OSS同属内网可以节省流量费用,同时保证网络质量。