Ceph RGW服务 使用s3 java sdk 分片文件上传API 报‘SignatureDoesNotMatch’ 异常的定位及规避方案
importjava.io.File;
import com.amazonaws.AmazonClientException;import com.amazonaws.auth.profile.ProfileCredentialsProvider;import com.amazonaws.services.s3.transfer.TransferManager;import com.amazonaws.services.s3.transfer.Upload;public class UploadObjectMultipartUploadUsingHighLevelAPI { public static void main(String[] args) throws Exception { String existingBucketName = "*** Provide existing bucket name ***"; String keyName = "*** Provide object key ***"; String filePath = "*** Path to and name of the file to upload ***"; TransferManager tm = new TransferManager(new ProfileCredentialsProvider()); System.out.println("Hello"); // TransferManager processes all transfers asynchronously, // so this call will return immediately. Upload upload = tm.upload( existingBucketName, keyName, new File(filePath)); System.out.println("Hello2"); try { // Or you can block and wait for the upload to finish upload.waitForCompletion(); System.out.println("Upload complete."); } catch (AmazonClientException amazonClientException) { System.out.println("Unable to upload file, upload was aborted."); amazonClientException.printStackTrace(); } }}问题描述:使用s3 java sdk 的如上代码分片文件上传,报‘SignatureDoesNotMatch’ 异常如下
Unable to abort multipart upload, you may need to manually remove uploaded parts: null (Service: Amazon S3; Status Code: 403; Error Code: SignatureDoesNotMatch; Request ID: tx000000000000000003ddf-005853b76e-1a56f9b-default)
com.amazonaws.services.s3.model.AmazonS3Exception: null (Service: Amazon S3; Status Code: 403; Error Code: SignatureDoesNotMatch; Request ID: tx000000000000000003ddf-005853b76e-1a56f9b-default), S3 Extended Request ID: 1a56f9b-default-default

定位过程:
下载s3 java sdk 源码,并配置好 log4j, 打印aws debug日志;
# For JBoss: Avoid to setup Log4J outside $JBOSS_HOME/server/default/deploy/log4j.xml!
# For all other servers: Comment out the Log4J listener in web.xml to activate Log4J.
#log4j.rootLogger=INFO, stdout, logfile
log4j.rootLogger=INFO,stdout,logfile
log4j.logger.com.amazonaws = DEBUG
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - <%m>%n
RGW配置文件/etc/ceph/ceph.conf 中的日志级别调整为20,重启RGW进程
debug rgw = 20
执行分片上传代码,分别截获客户端和服务端的请求日志。 如下2个图片可以发现uploadId客户端和服务端不一致,导致服务端进行签名校验失败。


那么问题来了,到底是RGW服务端,还是java s3 sdk实现有bug呢? 通过查看java 代码和aws文档描述,我认为是RGW签名实现存在bug。 RGW 应该在
获取从客户端url中的参数中值(已经被URLEncode)后,先decode,再根据aws文档描述的步骤进行encode(~特殊字符不encode),得到符合规则的参数字符串。
.\src\rgw\rgw_rest_s3.cc

http://docs.aws.amazon.com/general/latest/gr/sigv4-create-canonical-request.html

规避方案:
因为修改RGW的代码周期比较长,暂时先修改好修改的java代码,编译一个新的jar包。 如下是修改方法,不按照aws的规则来,对参数值只执行URLencode。
提交了一个bugfix到rgw git库, https://github.com/ceph/ceph/pull/12647/commits

https://github.com/BodihTao/aws-sdk-java/blob/master/aws-java-sdk-core/src/main/java/com/amazonaws/auth/AbstractAWSSigner.java
为了方便大家,我上传修改后编译好的class文件(java 1.8版本),把这2个文件用winrar 放到aws-java-sdk-1.11.69.jar包中com/amazonaws/auth目录下 替换原来文件即可得到新的jar包。
https://github.com/BodihTao/aws-sdk-java/raw/master/aws-java-sdk/AbstractAWSSigner%241.class
https://github.com/BodihTao/aws-sdk-java/raw/master/aws-java-sdk/AbstractAWSSigner.class
java 1.7版本的sdk包:
http://s3.yyclouds.com/public/aws-java-sdk-1.11.69rgw.jar
Ceph RGW服务 使用s3 java sdk 分片文件上传API 报‘SignatureDoesNotMatch’ 异常的定位及规避方案的更多相关文章
- Java FtpClient 实现文件上传服务
一.Ubuntu 安装 Vsftpd 服务 1.安装 sudo apt-get install vsftpd 2.添加用户(uftp) sudo useradd -d /home/uftp -s /b ...
- Java开发系列-文件上传
概述 Java开发中文件上传的方式有很多,常见的有servlet3.0.common-fileUpload.框架.不管哪种方式,对于文件上传的本质是不变的. 文件上传的准备 文件上传需要客户端跟服务都 ...
- Java中实现文件上传下载的三种解决方案
第一点:Java代码实现文件上传 FormFile file=manform.getFile(); String newfileName = null; String newpathname=null ...
- 【原创】用JAVA实现大文件上传及显示进度信息
用JAVA实现大文件上传及显示进度信息 ---解析HTTP MultiPart协议 (本文提供全部源码下载,请访问 https://github.com/grayprince/UploadBigFil ...
- Java下载https文件上传到阿里云oss服务器
Java下载https文件上传到阿里云oss服务器 今天做了一个从Https链接中下载音频并且上传到OSS服务器,记录一下希望大家也少走弯路. 一共两个类: 1 .实现自己的证书信任管理器类 /** ...
- 【Java】JavaWeb文件上传和下载
文件上传和下载在web应用中非常普遍,要在jsp环境中实现文件上传功能是非常容易的,因为网上有许多用java开发的文件上传组件,本文以commons-fileupload组件为例,为jsp应用添加文件 ...
- java+web+大文件上传下载
文件上传是最古老的互联网操作之一,20多年来几乎没有怎么变化,还是操作麻烦.缺乏交互.用户体验差. 一.前端代码 英国程序员Remy Sharp总结了这些新的接口 ,本文在他的基础之上,讨论在前端采用 ...
- Java结合WebUploader文件上传
之前自己写小项目的时候也碰到过文件上传的问题,没有找到很好的解决方案.虽然之前网找各种解决方案的时候也看到过WebUploader,但没有进一步深究.这次稍微深入了解了些,这里也做个小结. 简单的文件 ...
- Java Web(十一) 文件上传与下载
文件上传 上传的准备工作 表单method必须为post 提供file组件 设置form标签的enctype属性为multipart/form-data,如果没有设置enctype属性,浏览器是无法将 ...
随机推荐
- 前端开发:setTimeout与setInterval 定时器与异步循环数组
前端开发:setTimeout与setInterval 定时器与异步循环数组 前言: 开通博客园三个月以来,随笔记录了工作中遇到的大大小小的难题,也看过无数篇令人启发的文章,我觉得这样的环境是极好的, ...
- No-args constructor for class X does not exist. Register an InstanceCreator with Gson for this type to fix this problem.
Gson解析JSON字符串时出现了下面的错误: No-args constructor for class X does not exist. Register an InstanceCreator ...
- python之最强王者(8)——字典(dictionary)
1.Python 字典(Dictionary) 字典是另一种可变容器模型,且可存储任意类型对象. 字典的每个键值(key=>value)对用冒号(:)分割,每个对之间用逗号(,)分割,整个字典包 ...
- Python3.5安装及opencv安装
Python安装注意事项(版本3.5,系统windows)1.安装好Python后将D:\Program Files\Python.D:\Program Files\Python\Scripts加入P ...
- SpringMVC + Spring + MyBatis 整合 + Spring shrio + easyUI + 权限管理框架,带shrio session和shrio cache集群实现方案
工作之余先来写了一个不算规范的简单架子 基于spring mvc + spring + mybatis + Spring shrio 基于redis的集群方案 系统权限部分,分成多个机构,其中每个机构 ...
- elasticsearch高级配置二----线程池设置
一个Elasticsearch节点会有多个线程池,但重要的是下面四个: 索引(index):主要是索引数据和删除数据操作(默认是cached类型) 搜索(search):主要是获取,统计和搜索操作(默 ...
- 五个典型的 JavaScript 面试题
阅读原文 在IT界,需要大量的 JavaScript 开发者.如果你的能力能够胜任这一角色,那么你将获得许多更换工作和提高薪水的机会.但是在你被公司录取之前,你需要展现你的技术实力,以便通过面试环节. ...
- jquery的选择器
一.基本选择器 1.$("#id") id选择器,返回单个元素 2.$(".class") class选择器,返回集合元素 3.$("element& ...
- java socket传送一个结构体给用C++编写的服务器解析的问题
另一端是Java写客户端程序,两者之间需要通信.c++/c接收和发送的都是结构体,而Java是直接发送的字节流或者byte 数组.解决方法:c++/c socket 在发送结构体的时候其实发送的也是字 ...
- javaScript基础语法(上)
相关理论概念: 直接量的概念:直接描述某个(些)存储空间的值的量,如变量的值.对象的值.数组的值. 数据类型:在数据结构中的定义是一个值的集合以及定义在这个值集上的一组操作. 1.变量的声明和使用 变 ...