Qt库(QHttpMultiPart)上传文件至Ali oss失败(MalformedPOSTRequest)

原因

先说下原因下,篇幅过长
时间节点(2020/01/20) Aliyun 的oss请求中Content-Type:multipart/form-data中的boundary不能用双引号包含

项目背景

某PC客户端项目中,需要将文件上传至Server进行文件保存,前期由Java后端进行中转传输。但是随着业务量的增加还有大文件的增多,导致后台无法承受住这些业务量。中期技术方案变更,由Server端返回oss相关 信息客户端通过Http直接将文件上传至阿里云的oss上

技术背景

使用QHttpMultiPart和QHttpPart构造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}中生成含有':'的字符串可能会有问题

你可能感兴趣的:(Qt库(QHttpMultiPart)上传文件至Ali oss失败(MalformedPOSTRequest))