访问http:h2

了解如何访问Http2。

例子

示例/http_c++

大约h2

brpc将HTTP/2协议命名为“h2”,无论是否加密。然而,不带SSL的HTTP/2连接显示在官方名称为“h2c”的/connections上,而带SSL的连接显示为“h2”。

brpc中http和h2的API基本相同。在没有明确声明的情况下,提到的http特性也适用于h2。

创建频道

为了使用brpc::频道访问http/h2服务,ChannelOptions.protocol(通道选项协议)必须设置为协议_HTTP协议_H2

一旦设置了协议频道::初始化可以是任何有效的URL。注释:Init()只使用URL内的主机和端口,其他部分被丢弃。允许完整的URL只会让用户省去额外的解析代码。

brpc公司::频道选项 选项;
选项协议 = brpc公司::协议_HTTP;  //或brpc::PROTOCOL_H2如果 (通道初始化(“www.baidu.com” /*任何url*/, &选项) != 0) {
     日志(错误) << “无法初始化通道”;
     返回 -1;
}

http/h2通道还支持BNS地址或其他命名服务。

GET(获取)

brpc公司::控制器 碳纳米管;
碳纳米管http_请求().乌里() = “www.baidu.com/index.html”;  //请求URL通道调用方法(无效的, &碳纳米管, 无效的, 无效的, 无效的/*已完成*/);

http/h2与protobuf关系不大,因此调用方法为NULL,但控制器完成。发出非NULL的异步RPC完成

cntl.响应_附件()是http/h2响应的主体并键入butil::IOBufIOBuf公司可以转换为标准::字符串通过to_string(),它需要分配内存并复制所有数据。如果性能很重要,则代码应考虑支持IOBuf公司而不需要连续记忆。

邮政

默认的HTTP方法是GET,可以更改为POST或其他http方法。应将要POST的数据放入请求_附件(),已键入butil::IOBuf并且能够附加std::字符串字符*直接。

brpc公司::控制器 碳纳米管;
碳纳米管http_请求().乌里() = "...";  //请求URL碳纳米管http_请求().设置方法(brpc公司::HTTP_方法_测试);
碳纳米管请求_附件().追加("{\"消息\"以下为:\"你好,世界!\"}");
通道调用方法(无效的, &碳纳米管, 无效的, 无效的, 无效的/*已完成*/);

如果车身需要大量打印才能构建,请考虑使用butil::IOBufBuilder,具有与相同的接口标准::鸵鸟流当需要打印大量对象时,可能比c-style printf更简单、更高效。

brpc公司::控制器 碳纳米管;
碳纳米管http_请求().乌里() = "...";  //请求URL碳纳米管http_请求().设置方法(brpc公司::HTTP_方法_测试);
但是::IOBufBuilder公司 操作系统;
操作系统 << “大量打印” << 可打印对象 << ...;
操作系统移动到(碳纳米管请求_附件());
通道调用方法(无效的, &碳纳米管, 无效的, 无效的, 无效的/*已完成*/);

更改HTTP版本

brpc的默认行为是http/1.1。

与http/1.1相比,http/1.0缺少长连接(KeepAlive)。要将brpc客户端与一些旧的http服务器通信,可以按以下方式配置客户端:

碳纳米管http_请求().设置版本(1, 0);

设置http版本不适用于h2,但客户端接收到的h2响应和服务器接收到的h2请求中的版本设置为(2,0)。

brpc服务器自动识别http版本,并在无需用户帮助的情况下做出相应响应。

网址

URL的一般形式:

//URI方案:http://en.wikipedia.org/wiki/URI_scheme////  foo://用户名:密码@example.com:8042/over/here/index.dtb?type=动物&name=独角鲸#鼻子//  \_/   \_______________/ \_________/ \__/            \___/ \_/ \______________________/ \__///   |           |               |       |                |    |            |                |//|userinfo主机端口||查询片段//   |    \________________________________/\_____________|____|/ \__/        \__///方案||||||//权限|||||//可解释为键的路径//                                                        |    |//        \_______________________________________________|____|/       \____/     \_____///                             |                          |    |          |           |//可解释为值的层次部分//                                                        |    |//可解释为文件名|//                                                             |//|//可解释为扩展

正如我们在上面的例子中看到的,频道。首字母()cntl.http_request().uri()两者都需要URL。为什么uri()需要额外设置,而不是使用URL初始化()直接?

实际上,在简单的情况下会重复这些设置。但在更复杂的场景中,它们是不同的:

  • 访问NamingService下的多个服务器(例如BNS),在这种情况下频道::初始化接受对NamingService有意义的名称(例如BNS中的节点名称),而uri()使用URL分配。
  • 通过http/h2代理访问服务器,在这种情况下频道::初始化采用代理服务器的地址,而uri()仍分配有URL。

主机标头

如果用户已设置主机标头(不区分大小写),框架不做任何更改。

如果用户未设置主机标头和URL具有主机,例如http://www.foo.com/path,http请求包含“主机:网址:www.foo.com”.

如果用户未设置主机标头,并且URL也没有主机,例如“/index.html?name=value”,但通道初始化的地址包含域名。框架集主机带有目标服务器域名的标头。如果此地址是“网址:http://www.foo.com“,此http服务器应看到主持人:www.foo.com,如果此地址为“http://www.foo.com:8989“,此http服务器应该是主持人:www.foo.com:8989

如果用户没有设置主机头,并且URL也没有主机,例如“/index.html?name=value”,并且频道初始化的地址不包含域名。框架集主机标头和目标服务器的IP和端口。位于10.46.188.39:8989的http服务器应看到主持人:10.46.188.39:8989

标头在h2中命名为“:authority”。

常见用法

以http请求为例(与http响应类似),常见操作如下:

访问名为的HTTP标头

常数 标准::一串* 价值 = 碳纳米管->http_请求().获取标题(“Foo”); //不存在时为NULL

设置名为

碳纳米管->http_请求().设置标题(“傻瓜”, “价值”);

访问名为的查询

常数 标准::一串* 价值 = 碳纳米管->http_请求().乌里().获取查询(“傻瓜”); //不存在时为NULL

设置名为的查询

碳纳米管->http_请求().乌里().SetQuery(设置查询)(“傻瓜”, “价值”);

设置HTTP方法

碳纳米管->http_请求().设置方法(brpc公司::HTTP_方法_测试);

设置URL

碳纳米管->http_请求().乌里() = http://www.baidu.com(百度);

设置内容类型

碳纳米管->http_请求().集合内容类型(“文本/纯文本”);

获取HTTP正文

但是::IOBuf公司& 缓冲器 = 碳纳米管->请求_附件();
标准::一串 字符串 = 碳纳米管->请求_附件().到字符串(_S)(); //触发复制基础

设置HTTP正文

碳纳米管->请求_附件().追加("....");
但是::IOBufBuilder公司 操作系统; 操作系统 << "....";
操作系统移动(_T)(碳纳米管->请求_附件());

http头说明:

  • 标头的field_name是区分大小写的,根据rfc2616型.brpc支持区分大小写的字段名,并在打印时保持与用户设置的大小写相同。
  • 如果多个标题具有相同的字段名,根据rfc2616型,值应合并并用逗号(,)分隔。用户可以自己找出如何使用这种值。
  • 查询用“&”分隔,查询中的键/值用“=”分隔。值可以省略。例如,key1=值1&key2&key3=值3是有效的查询字符串,其中键2是空字符串。

调试HTTP消息

打开-http_详细以便框架打印每个http请求和响应。注意,这应该只用于测试或调试,而不是在线服务。

HTTP错误

当服务器返回非2xx HTTP状态代码时,HTTP RPC被视为失败并且cntl->错误代码()在客户端设置为EHTTP公司,用户可以检查cntl->http_response().status_code()了解更具体的HTTP错误。此外,服务器可以将描述错误的html或json放入cntl->response_attachment()它作为http主体发送回客户端。

压缩请求正文

控制器::set_request_compress_type(brpc::compress_type_GZIP)使框架尝试gzip HTTP主体。“尝试”意味着压缩可能不会发生,因为:

  • 正文的大小小于-http_body_compress_threshold指定的字节,默认值为512。原因是gzip不是一种非常快的压缩算法,当主体较小时,压缩引起的延迟甚至可能大于更快传输所节省的延迟。

减压响应机构

由于通用性,brpc不会自动解压缩响应体。解压缩代码并不复杂,用户可以自己完成。代码如下:

#包括 <brpc/policy/gzip_compress.h>
...
常数 标准::一串* 编码 = 碳纳米管->http_响应().获取标题(“内容编码”);
如果 (编码 != 无效的 && *编码 == “gzip”) {
    但是::IOBuf公司 未压缩的;
    如果 (!brpc公司::政策::Gzip解压缩(碳纳米管->响应_附件(), &未压缩的)) {
        日志(错误) << “无法解压缩响应正文”;
        返回;
    }
    碳纳米管->响应_附件().互换(未压缩的);
}
//现在,cntl->response_attachment()包含解压缩的数据

渐进式下载

http客户端通常在http主体完全下载之前不会完成RPC。在此过程中,http正文存储在内存中。如果主体非常大或无限大(用于实时流的FLV文件),内存将持续增长,直到RPC超时。这种http客户端不适合下载非常大的文件。

brpc客户端支持在读取整个正文之前完成RPC,以便用户可以在RPC之后逐步读取http正文。请注意,此功能并不意味着“支持http分块模式”,实际上brpc中的http实现从一开始就支持分块模式。真正的问题是如何让用户处理非常大或无限大的http主体,这并不意味着采用分块模式。

如何使用:

  1. 实施下面的ProgressiveReader:

    #包括 <brpc/progressive_reader.h>
    ...
     渐进式阅读器 {
    公众的以下为:
        //读取一个部分时调用。    //返回的错误被视为*permenant*和套接字,其中    //读取的数据将被关闭。    //可以通过阻塞此函数来处理临时错误    //可能会阻止套接字上的HTTP解析。    事实上的 但是::状态 OnReadOnePart(常数 空隙* 数据, 尺寸_t 长度) = 0;
    
        //当没有什么可读的时调用。“状态”是    //为什么调用此方法。    //-status.ok():消息已完成并成功使用。    //-否则:套接字已损坏或OnReadOnePart()失败。    //此方法将调用一次且仅调用一次。没有其他方法    //在后面被调用。用户可以释放内部此对象的内存。    事实上的 空隙 OnEndOf消息(常数 但是::状态& 地位) = 0;
    };
    

    OnReadOnePart每次读取一段数据时都会调用。OnEndOf消息在数据结束时调用,或者连接断开。在实施之前仔细阅读评论。

  2. 设置cntl.response_will_be_read_progressively();在RPC之前,使brpc在读取所有标头后立即结束RPC。

  3. 呼叫中国。ReadProgressiveAttachmentBy(新的MyProgressiveReader);RPC之后。MyProgressiveReader(我的进步阅读器)是用户实现的实例渐进式阅读器用户可以删除其中的对象OnEndOf消息

渐进式上传

目前,在启动http调用之前,POST数据应该是完整的,因此brpc http客户端仍然不适合上载非常大的主体。

使用身份验证访问服务器

生成授权数据(_D)根据服务器的身份验证方法,并将其设置为授权收割台。如果使用curl,请添加选项-H“授权:<auth_data>”

发送https请求

https是“http-over-SSL”的缩写,SSL不是http的专用协议,但对所有协议都有效。打开客户端SSL的通用方法是在这里.brpc自动为以https://开头的URI启用SSL,以使使用更加方便。


上次修改时间:2024年5月6日更新index.md(66353dc)