http multipart上传阿里oss失败(MalformedPOSTRequest)

#原因
先说下原因下,篇幅过长
时间节点(2020/01/20) Aliyun 的oss请求中Content-Type:multipart/form-data中的boundary不能用双引号包含
#项目背景
某PC客户端项目中,需要将文件上传至Server进行文件保存,前期由Java后端进行中转传输。但是随着业务量的增加还有大文件的增多,导致后台无法承受住这些业务量。中期技术方案变更,由Server端返回oss相关 信息客户端通过Http直接将文件上传至阿里云的oss上

#技术背景
使用QHttpMultiPartQHttpPart构造Multipart消息体

#问题发生
oss服务器返回MalformedPOSTRequest
MalformedPOSTRequest
The body of your POST request is not well-formed multipart/form-data
马赛克(_)
aijihui-dev.oss-cn-hangzhou.aliyuncs.com

#问题定位
##由于项目组使用的是成熟的Qt第三方底层库,错误的可能性很小
1.review code,查看使用是否有问题
2.抓包分析,目测header和body都没有问题
##阿里云官网查阅相关文档以及FAQ
1.未找到相关信息
##查阅RFC相关协议(rfc1867、rfc2046、rfc2616)
rfc2046 5.1.1
rfc2046-5.1.1.png
rfc2616 19.2

  1. Although RFC 2046 [40] permits the boundary string to be
    quoted, some existing implementations handle a quoted boundary
    string incorrectly.

##查阅Qt底层代码
1.代码(code_1)先判断是否设置ContentTypeHeader
2.代码(code_2)将boundary用双引号包含,注释标明 recommended in RFC 2046 section 5.1.1

QNetworkRequest QNetworkAccessManagerPrivate::prepareMultipart(const QNetworkRequest &request, QHttpMultiPart *multiPart)
{
    // copy the request, we probably need to add some headers
    QNetworkRequest newRequest(request);

    // add Content-Type header if not there already
    if (!request.header(QNetworkRequest::ContentTypeHeader).isValid()) {    // code_1
        // ....
        }
        // putting the boundary into quotes, recommended in RFC 2046 section 5.1.1
        contentType += "; boundary=\"" + multiPart->d_func()->boundary + '"'; // code_2
        newRequest.setHeader(QNetworkRequest::ContentTypeHeader, QVariant(contentType));
    }   
    // ...
    return newRequest;
}

#问题确认
Aliyun 的oss请求中Content-Type:multipart/form-data中的boundary不能用双引号包含
#问题修改

request.setHeader(QNetworkRequest::ContentTypeHeader, "multipart/form-data;boundary=" + multiPart->boundary());

可能出现的bug:
如果{boundary}中生成含有’:'的字符串可能会有问题

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值