.NET Core HttpClient调用腾讯云对象存储Web API的"ERROR_CGI_PARAM_NO_SUCH_OP"问题

腾讯云提供的对象存储(COS)C# SDK 是基于 .NET Framework 用 WebRequest 实现的,我们直接将这个实现迁移到 .NET Core 是可以正常调用,但后来我们基于 HttpClient 实现,调用 web api 时总是返回 "ERROR_CGI_PARAM_NO_SUCH_OP" 错误。

用 Wireshark 抓包后发现,基于 WebRequest 的实现的请求包开头比基于 HttpClient 的实现多了个 "Preamble: 0d0a"。

1)基于 WebRequest 的实现

2)基于 HttpClient 的实现

检查代码后发现,在构建 multipart/form-data 时,腾讯云官方基于 WebRequest 的实现是这样构建数据包的开头的:

var boundary = "---------------" + DateTime.Now.Ticks.ToString("x");
var beginBoundary = Encoding.ASCII.GetBytes("\r\n--" + boundary + "\r\n");

我们基于 HttpClient 的实现用的是 MultipartFormDataContent :

var boundary = "---------------" + DateTime.Now.Ticks.ToString("x");
var data = new MultipartFormDataContent(boundary);

前者构建的 Multipart 数据包比后者多出了 \r\n (回车换行),而 0d0a 正是 \r\n 的 ASCII 码。根据 Multipart Content-Type 规范,这个多出来的 \r\n 是多余的,所以被解析为  "Preamble: 0d0a" 。

于是修改基于 HttpClient 的实现,也加上这个额外的 \r\n :

var ms = new MemoryStream();
var bytes = Encoding.UTF8.GetBytes("\r\n");
ms.Write(bytes, 0, bytes.Length);
(await data.ReadAsStreamAsync()).CopyTo(ms);
ms.Position = 0;
var sc = new StreamContent(ms);
sc.Headers.ContentType = data.Headers.ContentType;
request.Content = sc;

但加上后依然是"ERROR_CGI_PARAM_NO_SUCH_OP"错误(实际上不加开头的 \r\n 也没关系,问题与这个无关)。

继续仔细对比抓包,发现 HttpClient 的实现中 form-data 部署少了双引号,比如 name=op ,基于 WebRequest 的实现用的是 name="op"

但加上后依旧是"ERROR_CGI_PARAM_NO_SUCH_OP"错误。

再继续对比抓包,发现 HttpClient 的实现这 Content-Type 中比 WebRequest 的实现多了2个双引号

1) Content-Type: multipart/form-data; boundary="---------------8d5289300ea3a0d"

2)  Content-Type: multipart/form-data; boundary=---------------8d527aeed341201

去找这2个双引号之后,问题终于解决了。

最终基于 .NET Core HttpClient 的实现代码如下("Preamble: 0d0a"没有影响,不需要加):

var request = new HttpRequestMessage(HttpMethod.Post, url);
request.Headers.Authorization = new AuthenticationHeaderValue("Authorization", signature);

var boundary = "---------------" + DateTime.Now.Ticks.ToString("x");
var data = new MultipartFormDataContent(boundary);
data.Add(new ByteArrayContent(Encoding.UTF8.GetBytes("upload")), "\"op\"");

var streamContent = new StreamContent(uploadStream);
streamContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data")
{
    Name = "\"fileContent\"",
    FileName = "\"" + fileName + "\""
};
streamContent.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
data.Add(streamContent);

data.Headers.Remove("Content-Type");
data.Headers.Add("Content-Type", "multipart/form-data; boundary=" + boundary);
request.Content = data;
var response = await _httpClient.SendAsync(request);
var json = await response.Content.ReadAsStringAsync();
时间: 2024-07-30 10:09:12

.NET Core HttpClient调用腾讯云对象存储Web API的"ERROR_CGI_PARAM_NO_SUCH_OP"问题的相关文章

微信小程序基于腾讯云对象存储的图片上传

在使用腾讯云对象存储之前,公司一直使用的是传统的FTP的上传模式,而随着用户量的不断增加,FTP所暴露出来的问题也越来越多,1.传输效率低,上传速度慢.2.时常有上传其他文件来攻击服务器,安全上得不到保障.所以我们在经过慎重考虑觉得使用第三方的云存储服务. 在最开始的时候我们在腾讯云与阿里云中选择,最终我们选择腾讯云,腾讯云在文件上传用时方面的性能比较突出,文件越大表现越好:在下载用时方面表现略优于阿里云:文件删除用时方面总体速度略逊于,但在不同大小文件删除用时上都比较稳定.当然这与我们主要用于

WordPress安装WPCOS插件分离图片至腾讯云对象存储加速网站

我们在前面的文章中已经通过"WordPress配置腾讯云对象存储COS之存储桶创建和设置"和"腾讯云对象存储COS绑定域名/开启CDN/设置免费SSL证书"两篇文章完成对于腾讯云对象存储COS的梳理,我们已经会在腾讯云COS中创建存储桶,以及绑定自己的域名和开启CDN加速.如果我们不绑定域名也是可以用的,只不过理论上用自己的域名连接比较专业一些. 同时我们在上一篇文章中也有知道获取腾讯云API密钥,因为在这篇文章中我们会在WordPress课堂网站安装WPCOS插件

腾讯云对象存储COS安全方案介绍

本文分享自微信公众号 - 腾讯云存储 相信所有企业和个人开发者在选用云存储产品时都把数据安全作为重要考量标准. 本文介绍了用户如何使用腾讯云对象存储COS的事前防护.事中监控.事后追溯三个手段来保证自己的数据安全. 一.事前防护手段 1. 权限隔离对上云企业来说,账号安全和资源合理授权是构筑立体防护体系的第一道门锁.云上资源管理的授权应该规避如下风险:使用腾讯云主账号进行日常操作:为员工建了子账号,但是授权过大:缺乏对使用帐号权限的管理制度和流程:没有定期审计管理用户的权限和登录信息:对高权限子

腾讯云对象存储服务(cos)之PHP实践

云对象存储服务, BAT都有其业务, 本文选择腾讯是因为腾讯有每月免费流量, 而阿里和百度都是需要先付费后使用, 另外新兴的像七牛云存储, 也是很不错的解决方案. 贴代码 <?php /** * Simple Tencent COS SDK * 2016/05/09 * Author: hldh214 <[email protected]> */ // 配置项 start $appid = ''; $bucket_name = ''; $dir_name = ''; $secretID

php5.2版本如何成功调用腾讯云短信API,实现短信发送功能

一.简要说明 我们在生活中经常会遇到一种情况,当你注册某个平台账户时,只要输入你的手机号码,点击获取验证码,随后就会收到发给你的短信验证码. 一般来说,实现这种功能都是用阿里云或者腾讯云提供的云短信服务.价格也很便宜,1000条起订,每条0.005元.因为公司的业务需求,最近需要实现这个功能,经过了解后决定使用腾讯云的云短信服务.(其实两个平台价格差不多,但是腾讯云首次开启会免费赠送100条短信,非常适合前期测试,所以理所当然选择了腾讯云.) 在官方的文档中提供了C#,node.js,Java,

阿里云对象存储应用服务器搭建代码

背景说明 最近做一个APP客户端图片直传阿里云OSS的服务,需要在后台开一个阿里云的OSSToken获取的接口. 阿里云官方文档地址:快速搭建移动应用直传服务. 略过移动端说明,直接看服务端的. 不是移动端直传吗,为什么需要服务端呢?原因如下: Android和iOS应用不能直接存储AccessKey,这样会存在数据泄露的风险.所以应用必须向用户的应用服务器申请一个Token. 这个Token是有时效性的,如果Token的过期时间是30分钟(由应用服务器指定),那么在这30分钟里,该Androi

WPOSS – WordPress阿里云对象存储OSS插件 网站图片分离加速

我们WordPress课堂在前面有一篇文章中介绍到WPCOS插件,这是针对WordPress程序集合腾讯云COS对象存储进行网站图片分离的插件,包括我们网站目前也有在用.可以降低网站的带宽占用,提高网站的访问速度,当然这个需要我们购买对象存储和流量包,必要的成本还是需要的. 不过有些网友提到自己如果在使用阿里云服务器建站的时候,也想用到类似的插件分离网站的图片或者其他附件文件,那在这里笔者就推荐使用类似的WPOSS插件,基于阿里云对象存储OSS的.功能上有些类似WPCOS,但是稍微设置上有一些不

阿里云对象存储OSS支持版本管理特性

阿里云对象存储OSS现已经全面支持"对象版本管理"特性.该功能适用于所有的存储类型以及区域.当Bucket启用该特性后,"对象版本管理"功能可以保护和恢复误删除.误覆盖的数据. 对象存储OSS"版本管理"具有如下特点: 提供"应用级"数据保护,可防止文件意外覆盖:当Bucket开启版本管理特性后,该Bucket内对象的每次修改.删除操作,OSS都会生成对应的历史版本.授权的用户可以通过控制台.API.SDK等方式查询.下载以及

利用腾讯云COS云对象存储定时远程备份网站

版权声明:本文由张戈 原创文章,转载请注明出处: 文章原文链接:https://www.qcloud.com/community/article/942851001487125915 来源:腾云阁 https://www.qcloud.com/community 一.优点分析 内网传输:和阿里云OSS一样,腾讯云COS同样支持内网和外网文件传输,对于腾讯云服务器,使用内网传输绝对是最快.最稳定的备份方案! 免费方案:看了下腾讯云COS的定价说明,发现对于备份网站来说简直是绝佳搭档,甚至可以说是钻