- mongodb - 在 MongoDB mapreduce 中,如何展平值对象?
- javascript - 对象传播与 Object.assign
- html - 输入类型 ="submit"Vs 按钮标签它们可以互换吗?
- sql - 使用 MongoDB 而不是 MS SQL Server 的优缺点
我将二进制数据从客户端 (Debian 6.0.3) 发送到服务器 (Windows Server 2003)。为了绕过大多数防火墙,我使用 HTTPS POST。客户端和服务器使用 Boost.Asio 和 OpenSSL 实现。首先,我实现了最简单的版本,它运行良好。
HTTP header :
POST / HTTP/1.1
User-Agent: my custom client v.1
[binary data]
([binary data]
不是 base64 编码,如果这很重要)
然后,在另一台客户端机器上它失败了(连接到同一台服务器机器)。行为不稳定。连接始终建立良好(端口 443)。大多数时候我通过 SSL 握手很好,但服务器没有收到数据(几乎没有数据,有时实际上收到一两个数据包)。有时我会收到 SSL 握手错误“短读”。有时我会收到无效数据。
客户端连接到服务器,握手,发送 HTTP POST header ,然后无限发送二进制数据,直到出现问题。对于测试,我使用自定义生成的 SSL 证书。
服务器代码:
namespace ssl = boost::asio::ssl;
ssl::context context(io_service, ssl::context::sslv23);
context.set_options(ssl::context::default_workarounds | ssl::context::no_sslv2);
context.use_certificate_chain_file("server.pem");
context.use_private_key_file("server.pem", boost::asio::ssl::context::pem);
ssl::stream<tcp::socket> socket(io_service, context);
// standard connection accepting
socket.async_handshake(ssl::stream_base::server, ...);
...
boost::asio::async_read_until(socket, POST_header, "\r\n\r\n", ...);
...
客户端代码:
ssl::context context(io_service, ssl::context::sslv23);
context.load_verify_file("server.crt");
socket.reset(new ssl::stream<tcp::socket>(io_service, context));
socket->set_verify_mode(ssl::verify_none);
// standard connection
socket.async_handshake(ssl::stream_base::client, ...);
...
(错误处理连同无关代码一起省略)
如您所见,这是最简单的 SSL 连接。怎么了?原因可能是防火墙吗?
我在同一个 443 端口上尝试了不带 SSL 的简单 TCP,效果很好。
编辑:
尝试添加“Content-Type: application/octet-stream”,没有帮助。
编辑 2:
通常我会收到 HTTP POST header 。然后我将数据 block 作为 chunk-size(4 bytes)chunk(chunk-size bytes)...
发送。服务器接收到 chunk-size
很好,但是什么也没有。客户端不通知服务器问题(无错误)并继续发送数据。有时服务器可以接收到一两个 block ,有时它接收到无效的 chunk-size
,但大多数时候什么都没有。
编辑 3:
比较在客户端和服务器上捕获的流量,没有发现任何差异。
解决方案
我从一开始就被这个问题误导了。将其缩小到令人惊讶的细节:
如果我在 Boost v.1.48(目前最新的一个)中使用 Boost.Asio 多缓冲区,则通过 SSL 套接字发送会失败。示例:
// data to send, protocol is [packet size: 4 bytes][packet: packet_size bytes]
std::vector<char> packet = ...;
uint32_t packet_size = packet.size();
// prepare buffers
boost::array<boost::asio::const_buffer, 2> bufs = {{boost::asio::buffer(&packet_size, sizeof(packet_size)), boost::asio::buffer(packet)}};
// send multi buffers by single call
boost::asio::async_write(socket, bufs, ...);
在此示例中分别发送 packet_size
和 packet
可以解决此问题。我绝不会将任何可疑行为称为错误,尤其是当它与 Boost 库有关时。但这一个看起来真的像一个错误。在 Boost v.1.47 上试过 - 工作正常。尝试使用通常的 TCP 套接字(不是 SSL 套接字) - 工作正常。在 Linux 和 Windows 上都一样。
我将在 Asio 邮件列表中找到有关此问题的任何报告,如果没有找到,我将报告。
最佳答案
如果你不必在web服务器前操作,你就没有使用 HTTPS 协议(protocol)。从防火墙的角度来看 HTTPS 看起来还像另一个 SSL 连接,它不知道发生了什么。所以如果您唯一需要的只是传递数据 - 而不是实际的 Web 服务器,使用只是通过 443 端口的 SSL 连接。
所以只需对您的 SSL 连接进行故障排除,该问题与 HTTP 无关。
如果您想使用 HTTP Web 服务器而不是自定义客户端:
两点:
最简单的应该是
POST /url HTTP/1.0
User-Agent: my custom client v.1
Content-Type: application/octet-stream
Content-Length: NNN
Actual Content
或者对于 HTTP/1.1
POST /url HTTP/1.1
Host: www.example.com
User-Agent: my custom client v.1
Content-Type: application/octet-stream
Content-Length: NNN
Actual Content
注意:您不能发送无限数据。 HTTP 协议(protocol)需要固定的内容长度大多数情况下,Web 服务器会先加载数据,然后再将其传递给后端。
所以你必须按 block 传输数据。
关于c++ - 如何通过 HTTPS POST 正确发送二进制数据?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9128258/
我已经制作了一个用于报名参加 Activity 的小应用程序。用户输入他们的数据,然后单击“登录我”。 现在有时人们在数据库中是双倍的,完全相同的数据彼此之间很快被插入了两次。这只能表示某人单击了两次
这个问题在这里已经有了答案: 关闭 10 年前。 Possible Duplicate: PHP: “Notice: Undefined variable” and “Notice: Undefin
这个问题在这里已经有了答案: 关闭 10 年前。 Possible Duplicate: PHP: “Notice: Undefined variable” and “Notice: Undefin
我正在尝试将数据从 Textarea 发布到经典的 ASP 脚本,该脚本更新本地计算机上的 MS SQL,然后发布到另一台服务器上的 PHP 脚本。但是,执行以下操作不起作用,因为它会切断文本区域的数
无效的代码: login_form = page.form_with(:method => 'post') 和有效的代码: login_form = page.form_with(:method =>
我希望能够在 HTTP Post 请求被触发时拦截它,然后修改其请求正文(或参数),然后发送它。 这怎么可能用 jquery/js 实现。 谢谢 最佳答案 Jquery ajax beforeSend
我想编写一个 Mysql 语句,从表(发布)中选择所有内容,其中标题类似于 $title 除了 $title 的标题。基本上我想显示某个帖子的所有相关帖子。我希望查询选择表中标题或详细信息中具有标题名
我已经成功创建了一个简单的 HTML 表单,它将上传的文件发布到我的 Amazon S3 存储桶。我遵循了以下说明: http://aws.amazon.com/articles/1434 现在我正在
我正在实现一个 PayPal IPN 页面,并想检查以确保请求真正来自 PayPal 而不是被欺骗。我假设 HTTP_REFERRER 不是一个好的检查方式?我已经尝试过这种方法,但变量只是空的。 有
我有一个非常简单的设置有一个非常特殊的问题。 该设置部署了 nginx Web 服务器以提供一些静态页面。它还有一个用于处理 POST 请求的后端 uwsgi 守护进程。 我的nginx位置配置如下
我认为我做错了什么,或者误解了我在网上阅读的有关 POST 和 GET 请求的内容。我在 myNumber.ejs 上有一个提交表单。当我按下提交时,有 Add.ejs 的 View 。 Add.ej
我需要将数据从 Express 应用程序的前端发送到后端,然后使用需要显示该数据的 EJS 呈现页面。 问题是 app.post() 方法,随后 res.render() 函数似乎没有完全执行或者当我
根据AWS Documentation对于 CloudFormation cfn-hup 帮助程序脚本,cfn-hup Hook 可以具有“要检测的以逗号分隔的条件列表”。这些条件/触发器可以是 po
位于“wp-admin/includes/”的“post.php”文件中的 wordpress 函数“get_default_post_to_edit”无法正常工作。 当我加载页面时:wp-admin
我使用请求库发布数据,但在服务器上收到空主体,没有传递任何数据。我在代码中遗漏了什么吗? Map map = new Map(); map[csrfNameKey] = csrfName;
我正在尝试使用 siege 3.0.1 测试我的网站。但是好像siege不发送POST数据。这是我从网络浏览器收到的请求 POST / HTTP/1.0 Accept: text/html,appli
我正在尝试为 stockfigher 游戏 api 编写包装器,只是为了了解 feign 是如何工作的,而且我在第一个 POST 方法中遇到了问题: @RequestMapping(method =
如何使用 Jersey 获取原始 POST? @FormParam将不起作用,因为我发布的原始 JSON 不在任何特定的 POST 字段中。 最佳答案 Jersey 带有一个用于将 JSON 映射到
我正在尝试同时创建一个实体和两个子实体的实例。 如果我将以下 JSON 发布到/user_objects 资源,它会很高兴地创建父 user_object 实体和链接的 User_object_att
在 IPV6 中如何使用 IPV6 地址和端口号构建 CURL POST http 请求。任何类型的线程都将受到赞赏。 尝试构建如下请求 >curl --interface 'http://[2001
我是一名优秀的程序员,十分优秀!