import java.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’ 异常的定位及规避方案的更多相关文章

  1. Java FtpClient 实现文件上传服务

    一.Ubuntu 安装 Vsftpd 服务 1.安装 sudo apt-get install vsftpd 2.添加用户(uftp) sudo useradd -d /home/uftp -s /b ...

  2. Java开发系列-文件上传

    概述 Java开发中文件上传的方式有很多,常见的有servlet3.0.common-fileUpload.框架.不管哪种方式,对于文件上传的本质是不变的. 文件上传的准备 文件上传需要客户端跟服务都 ...

  3. Java中实现文件上传下载的三种解决方案

    第一点:Java代码实现文件上传 FormFile file=manform.getFile(); String newfileName = null; String newpathname=null ...

  4. 【原创】用JAVA实现大文件上传及显示进度信息

    用JAVA实现大文件上传及显示进度信息 ---解析HTTP MultiPart协议 (本文提供全部源码下载,请访问 https://github.com/grayprince/UploadBigFil ...

  5. Java下载https文件上传到阿里云oss服务器

    Java下载https文件上传到阿里云oss服务器 今天做了一个从Https链接中下载音频并且上传到OSS服务器,记录一下希望大家也少走弯路. 一共两个类: 1 .实现自己的证书信任管理器类 /** ...

  6. 【Java】JavaWeb文件上传和下载

    文件上传和下载在web应用中非常普遍,要在jsp环境中实现文件上传功能是非常容易的,因为网上有许多用java开发的文件上传组件,本文以commons-fileupload组件为例,为jsp应用添加文件 ...

  7. java+web+大文件上传下载

    文件上传是最古老的互联网操作之一,20多年来几乎没有怎么变化,还是操作麻烦.缺乏交互.用户体验差. 一.前端代码 英国程序员Remy Sharp总结了这些新的接口 ,本文在他的基础之上,讨论在前端采用 ...

  8. Java结合WebUploader文件上传

    之前自己写小项目的时候也碰到过文件上传的问题,没有找到很好的解决方案.虽然之前网找各种解决方案的时候也看到过WebUploader,但没有进一步深究.这次稍微深入了解了些,这里也做个小结. 简单的文件 ...

  9. Java Web(十一) 文件上传与下载

    文件上传 上传的准备工作 表单method必须为post 提供file组件 设置form标签的enctype属性为multipart/form-data,如果没有设置enctype属性,浏览器是无法将 ...

随机推荐

  1. 再谈JavaScript闭包及应用

    .title-bar { width: 80%; height: 35px; padding-left: 35px; color: white; line-height: 35px; font-siz ...

  2. DateHelper.cs日期时间操作辅助类C#

    //==================================================================== //** Copyright © classbao.com ...

  3. Java语言中的面向对象特性总结

    Java语言中的面向对象特性 (总结得不错) [课前思考]  1. 什么是对象?什么是类?什么是包?什么是接口?什么是内部类?  2. 面向对象编程的特性有哪三个?它们各自又有哪些特性?  3. 你知 ...

  4. Redis 简单搭建

    ======== redis ======== 1. redis setup and test : 1. download the package from https://redis.io/down ...

  5. GJM : Unity3D HIAR -【 快速入门 】 四、创建 Hello World

    创建 Hello World 本文将介绍如何在 Windows 系统下,使用 HiAR SDK 创建一个简单的 AR 应用.在开始之前,请先完成下列准备工作: 注册 HiAR 帐户 获取 AppKey ...

  6. Javascript绝不要使用在文档加载之后使用 document.write(), 怎么理解?

    在文档加载之后使用 document.write(),会覆盖该文档.   需满足两个条件:      1.在函数内部调用document.write():      2.通过按钮响应调用函数:   举 ...

  7. 安卓---Toast工具类,有点懒

    package com.liunan.myfirstapp.util; import android.content.Context; import android.widget.Toast; /** ...

  8. css属性兼容主流浏览器

    目前,对于网页中一些浏览器兼容性问题,可以使用css hack(css 招数)和浏览器Bug修复的方式解决. 名词解释: css Hack:针对特定浏览器编写冗余代码,这是一种欺骗浏览器的行为,预示着 ...

  9. SQL优化技术分析-3:SQL语句索引的利用

    使用索引来更快地遍历表.默认情况下建立的索引是非聚集索引,但有时它并不是最佳的.在非聚集索引下,数据 在物理上随机存放在数据页上.合理的索引设计要建立在对各种查询的分析和预测上.一般来说: 有大量重复 ...

  10. hdfs以及hbase动态增加和删除节点

    一个知乎上的问题:Hbase的Region server和hadoop的datanode是否可以部署在一台服务器上?如果是的话,二者是否是一对一的关系?部署在同一台服务器上,可以减少数据跨网络传输的流 ...