GRPC头测试记录
GRPC头记录
http://nodejs.cn/api/http2/note_on_authority_and_host.html
https://cloud.tencent.com/developer/section/1189948
https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers/User-Agent
Header说明
:authority
个人理解:可视为host
,表示服务的IP+Port
HTTP/2 要求请求具有 :authority 伪标头或 host 标头。 当直接构建 HTTP/2 请求时首选 :authority,从 HTTP/1 转换时首选 host(例如在代理中)。
如果 :authority 不存在,则兼容性 API 将回退到 host。 有关详细信息,请参阅 request.authority。 但是,如果不使用兼容性 API(或直接使用 req.headers),则需要自己实现任何回退行为。
":authority" 伪头字段包含目标 URI 的部分权限([RFC3986],第 3.2 节)。权限不得包含 "http" 或 "https" scheme URI 的已弃用 "userinfo" 子组件。为了确保可以准确地再现 HTTP/1.1请求行,当从具有源或星号形式的请求目标的 HTTP/1.1 请求进行转换时,必须省略该伪头字段(参见[RFC7230],第 5.3 节)。直接生成 HTTP/2 请求的客户端应该使用 ":authority" 伪头字段而不是 Host 头字段。将 HTTP/2 请求转换为 HTTP/1.1 的网络中间件必须通过复制 ":authority" 伪头字段的值来创建 Host 头字段(如果请求中不存在的话)。
user-agent
User-Agent 首部包含了一个特征字符串,用来让网络协议的对端来识别发起请求的用户代理软件的应用类型、操作系统、软件开发商以及版本号。
记录说明
- 192.168.10.173 PC1-IP
- 192.168.10.96 PC2-IP
- 192.168.10.152 kong网关-IP
- c++ 服务在173运行
- golang服务在96运行
- 标签为服务,子标签为客户端
C++ Service
c++直接访问
Client metadata:
Header key: user-agent, value: grpc-c++/1.46.0-dev grpc-c/23.0.0 (linux; chttp2)
golang访问
Client metadata:
Header key: user-agent, value: grpc-go/1.46.2
kong网关-c++
Client metadata:
Header key: user-agent, value: grpc-c++/1.46.0-dev grpc-c/23.0.0 (linux; chttp2)
Header key: x-forwarded-for, value: 192.168.10.173
Header key: x-forwarded-host, value: 192.168.10.152
Header key: x-forwarded-path, value: /hello.HelloService/SayHello
Header key: x-forwarded-port, value: 8508
Header key: x-forwarded-proto, value: http
Header key: x-real-ip, value: 192.168.10.173
kong网关-golang
Client metadata:
Header key: user-agent, value: grpc-go/1.46.2
Header key: x-forwarded-for, value: 192.168.10.96
Header key: x-forwarded-host, value: 192.168.10.152
Header key: x-forwarded-path, value: /hello.HelloService/SayHello
Header key: x-forwarded-port, value: 8508
Header key: x-forwarded-proto, value: http
Header key: x-real-ip, value: 192.168.10.96
kong网关-grpc_web
Client metadata:
Header key: accept, value: application/grpc-web-text
Header key: accept-encoding, value: gzip, deflate
Header key: accept-language, value: zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6
Header key: content-length, value: 9
Header key: origin, value: http://192.168.10.173:8080
Header key: referer, value: http://192.168.10.173:8080/
Header key: user-agent, value: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.4951.64 Safari/537.36 Edg/101.0.1210.53
Header key: x-forwarded-for, value: 192.168.10.96
Header key: x-forwarded-host, value: 192.168.10.152
Header key: x-forwarded-path, value: /hello.HelloService/SayHello
Header key: x-forwarded-port, value: 8509
Header key: x-forwarded-prefix, value: /hello
Header key: x-forwarded-proto, value: http
Header key: x-grpc-web, value: 1
Header key: x-real-ip, value: 192.168.10.96
Header key: x-user-agent, value: grpc-web-javascript/0.1
Golang Service
c++ 直接访问
Client metadata:
:authority :: [192.168.10.96:8503]
content-type :: [application/grpc]
grpc-accept-encoding :: [identity, deflate, gzip]
user-agent :: [grpc-c++/1.46.0-dev grpc-c/23.0.0 (linux; chttp2)]
golang 访问
Client metadata:
:authority :: [192.168.10.96:8503]
content-type :: [application/grpc]
user-agent :: [grpc-go/1.46.2]
kong网关- golang
Client metadata:
x-forwarded-path :: [/hello.HelloService/SayHello]
x-real-ip :: [192.168.10.96]
x-forwarded-for :: [192.168.10.96]
x-forwarded-port :: [8508]
x-forwarded-host :: [192.168.10.152]
content-type :: [application/grpc]
user-agent :: [grpc-go/1.46.2]
:authority :: [192.168.10.96:8503]
x-forwarded-proto :: [http]
kong网关- c++
Client metadata:
x-forwarded-for :: [192.168.10.173]
content-type :: [application/grpc]
grpc-accept-encoding :: [identity, deflate, gzip]
x-forwarded-port :: [8508]
x-forwarded-host :: [192.168.10.152]
x-real-ip :: [192.168.10.173]
x-forwarded-path :: [/hello.HelloService/SayHello]
user-agent :: [grpc-c++/1.46.0-dev grpc-c/23.0.0 (linux; chttp2)]
:authority :: [192.168.10.96:8503]
x-forwarded-proto :: [http]
kong网关- grpc_web
Client metadata:
referer :: [http://192.168.10.173:8080/]
x-forwarded-for :: [192.168.10.96]
x-forwarded-path :: [/hello.HelloService/SayHello]
accept-language :: [zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6]
content-length :: [9]
x-forwarded-port :: [8509]
accept :: [application/grpc-web-text]
x-grpc-web :: [1]
x-real-ip :: [192.168.10.96]
x-user-agent :: [grpc-web-javascript/0.1]
accept-encoding :: [gzip, deflate]
x-forwarded-prefix :: [/hello]
user-agent :: [Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.4951.64 Safari/537.36 Edg/101.0.1210.53]
content-type :: [application/grpc]
origin :: [http://192.168.10.173:8080]
x-forwarded-host :: [192.168.10.152]
:authority :: [192.168.10.96:8503]
x-forwarded-proto :: [http]
总结
获取客户端IP
C++ 服务端
- C++直接访问
- Go直接访问
- C++访问kong
- Go访问kong
- Grpc-WEB访问网关
C++暂时未实现如何从**context**`获取客户端IP`
服务端如果有需要,建议和客户端约定一个**Key**作为`header`
Go 服务端
- C++直接访问
- Go直接访问
- C++访问kong
- Go访问kong
- Grpc-WEB访问网关
虽然Go
在直接访问时,无法从header
中读取到客户端IP
相关,但通过google.golang.org/grpc/peer
包获取到客户端IP
p, _ := peer.FromContext(ctx)
fmt.Println(p.Addr.String()," ",p.Addr.Network())
Addr()为IP,NetWork为传输方式(tcp/udp/..)
MetaData
Go metadata
## clinet code
ctx := context.Background()
md := metadata.New(map[string]string{"demo": "go client"})
newCtx2 := metadata.NewOutgoingContext(ctx, md)
- go service:
Client metadata:
user-agent :: [grpc-go/1.46.2]
demo :: [go client]
:authority :: [192.168.10.96:8503]
content-type :: [application/grpc]
- c++ service:
Client metadata:
Header key: go, value: programming
Header key: tour, value: book
Header key: user-agent, value: grpc-go/1.46.2
C++ metadata
## clinet code
grpc::ClientContext context;
context.AddMetadata("demo", "c++ client");
- go:
Client metadata:
:authority :: [192.168.10.96:8503]
content-type :: [application/grpc]
grpc-accept-encoding :: [identity, deflate, gzip]
user-agent :: [grpc-c++/1.46.0-dev grpc-c/23.0.0 (linux; chttp2)]
demo :: [c++ client]
- c++:
Client metadata:
Header key: demo, value: c++ client
Header key: user-agent, value: grpc-c++/1.46.0-dev grpc-c/23.0.0 (linux; chttp2)
测试程序
proto
syntax = "proto2";
package hello;
option go_package = "./hello";
service HelloService {
rpc SayHello(HelloRequest) returns (HelloResponse);
rpc LotsOfReplies(HelloRequest) returns (stream HelloResponse);
rpc LotsOfGreetings(stream HelloRequest) returns (HelloResponse);
rpc BidiHello(stream HelloRequest) returns (stream HelloResponse);
}
message HelloRequest {
optional string greeting = 1;
}
message HelloResponse {
required string reply = 1;
}
Go
/*
GRPC 服务端
*/
package main
import (
"context"
pb "demo_hello/proto/hello"
"fmt"
"google.golang.org/grpc"
"google.golang.org/grpc/metadata"
"log"
"net"
)
type Server struct {
pb.UnimplementedHelloServiceServer
}
func (S *Server) SayHello(ctx context.Context, in *pb.HelloRequest) (*pb.HelloResponse, error) {
res := "this is 96"
fmt.Println("Client metadata:")
if headers, ok := metadata.FromIncomingContext(ctx); ok {
for head, val := range headers {
fmt.Println(head, " :: ", val)
}
}
return &pb.HelloResponse{Reply: &res}, nil
}
func main() {
lis, err := net.Listen("tcp", "0.0.0.0:8503")
if err != nil {
log.Fatalf("failed listen: %v", err)
}
s := grpc.NewServer()
pb.RegisterHelloServiceServer(s, &Server{})
log.Printf("Server listen:%v", lis.Addr())
if err := s.Serve(lis); err != nil {
log.Fatalf("Failed Server: %v", err)
}
}
/*
GRPC 客户端
*/
package main
import (
"context"
"flag"
"google.golang.org/grpc/metadata"
"log"
"time"
pb "demo_hello/proto/hello"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"
)
const (
defaultName = "world"
)
var (
addr = flag.String("addr", "192.168.10.96:8503", "the address to connect to")
)
func main() {
flag.Parse()
// Set up a connection to the server.
conn, err := grpc.Dial(*addr, grpc.WithTransportCredentials(insecure.NewCredentials()))
if err != nil {
log.Fatalf("did not connect: %v", err)
}
defer conn.Close()
c := pb.NewHelloServiceClient(conn)
// Contact the server and print out its response.
ctx := context.Background()
md := metadata.New(map[string]string{"demo": "go client"})
newCtx2 := metadata.NewOutgoingContext(ctx, md)
ctx, cancel := context.WithTimeout(newCtx2, time.Second)
defer cancel()
name := "ss"
r, err := c.SayHello(ctx, &pb.HelloRequest{Greeting: &name})
if err != nil {
log.Fatalf("could not greet: %v", err)
}
log.Printf("Greeting: %s", r.GetReply())
}
C++
/*
GRPC server
*/
#include <iostream>
#include <memory>
#include <string>
#include <grpcpp/grpcpp.h>
#ifdef BAZEL_BUILD
#include "examples/protos/helloworld.grpc.pb.h"
#else
#include "hello_world/hello_world.grpc.pb.h"
#endif
using grpc::Server;
using grpc::ServerBuilder;
using grpc::ServerContext;
using grpc::Status;
using hello::HelloRequest;
using hello::HelloResponse;
using hello::HelloService;
using Service = hello::HelloService::Service;
// Logic and data behind the server's behavior.
class GreeterServiceImpl final : public Service {
Status SayHello(ServerContext *context, const HelloRequest *request, hello::HelloResponse *reply) override {
std::string prefix("Hello ");
// Get the client's initial metadata
std::cout << "Client metadata: " << std::endl;
const std::multimap<grpc::string_ref, grpc::string_ref> metadata = context->client_metadata();
for (auto iter = metadata.begin(); iter != metadata.end(); ++iter) {
std::cout << "Header key: " << iter->first << ", value: ";
// Check for binary value
size_t isbin = iter->first.find("-bin");
if ((isbin != std::string::npos) && (isbin + 4 == iter->first.size())) {
std::cout << std::hex;
for (auto c : iter->second) {
std::cout << static_cast<unsigned int>(c);
}
std::cout << std::dec;
} else {
std::cout << iter->second;
}
std::cout << std::endl;
}
reply->set_reply("173");
return Status::OK;
}
};
void RunServer() {
std::string server_address("0.0.0.0:8503");
GreeterServiceImpl service;
ServerBuilder builder;
// Listen on the given address without any authentication mechanism.
builder.AddListeningPort(server_address, grpc::InsecureServerCredentials());
// Register "service" as the instance through which we'll communicate with
// clients. In this case it corresponds to an *synchronous* service.
builder.RegisterService(&service);
// Finally assemble the server.
std::unique_ptr<Server> server(builder.BuildAndStart());
std::cout << "Server listening on " << server_address << std::endl;
// Wait for the server to shutdown. Note that some other thread must be
// responsible for shutting down the server for this call to ever return.
server->Wait();
}
int main(int argc, char **argv) {
RunServer();
return 0;
}
/*
GRPC client
*/
//
// Created by mimo on 2022/5/24.
//
#include "iostream"
#include "memory"
#include "grpcpp/grpcpp.h"
#include "hello_world/hello_world.grpc.pb.h"
using namespace std;
using namespace hello;
class HelloClient {
public:
explicit HelloClient(const std::shared_ptr<grpc::Channel> &channel)
: stub_(hello::HelloService::NewStub(channel)) {}
void SayHello() {
grpc::ClientContext context;
context.AddMetadata("demo", "c++ client");
HelloRequest request;
HelloResponse response;
request.set_greeting("dd");
auto res = stub_->SayHello(&context, request, &response);
if (!res.ok()) {
std::cout << "Failed IsConnected alarm server" << std::endl;
return;
}
std::cout << response.reply();
}
private:
std::unique_ptr<hello::HelloService::Stub> stub_;
};
int main(){
HelloClient client(grpc::CreateChannel("192.168.10.96:8503", grpc::InsecureChannelCredentials()));
client.SayHello();
return 0;
}
GRPC头测试记录的更多相关文章
- linux .net mono方案测试记录与报告(一)
第一阶段 linux .net 方案测试 硬件为4核8线程的笔记本i7-4710mq 分配了4个线程 情况下 1.方案一 nginx+fastcgi-mono-server4方式 性能为每秒处理140 ...
- Yii 增删改查 测试记录
亲们, 我是yii小白 不要笑话我奥.今天白天写一个管理模块涉及到 yii ar 下的 curd 操作,做 update 操作时纠结了好久,今天晚上花点时间学习, 下面写下我的测试记录 代码如下: ...
- Office隐藏17年的漏洞CVE_2017_11882测试记录
Office隐藏17年的漏洞CVE_2017_11882测试记录 创建时间: 2017/11/25 0:18 作者: CN_Simo 标签: Office漏洞 参考文章1:https://www.cn ...
- HDFS部署测试记录(2019/05)
目录 HDFS部署测试记录 0.HDFS基础知识 1.基本组成结构与文件访问过程 2.NameNode启动时如何维护元数据 3.HDFS文件上传流程 1.系统环境 1.安装大致记录: 2.磁盘分区 3 ...
- [转]Rapid Reporter——轻量级ET测试记录工具
下载地址:http://testing.gershon.info/reporter/ 特别感谢:邰晓梅老师 在一次ET的在线培训课程,邰晓梅老师使用的是这个工具. Rapid Reproter,是一款 ...
- linux下开发板网络速度测试记录
由于做的项目对于网络和USB的读写速度有很高的要求,因此新拿回来的板子要测试网络和usb的最佳传输速度.要考虑不少因素,先把我能想到的记录下来. 测试的环境是开发板和ubuntu虚拟机 ...
- 堡垒机jumpserver测试记录--使用
快速入门 截图就不放了,官网都有,这里只是就遇到的一些问题做下记录 必备条件 一台安装好 Jumpserver 系统的可用主机(堡垒机) 一台或多台可用的 Linux.Windows资产设备(被管理的 ...
- 堡垒机jumpserver测试记录--安装
一步一步安装(CentOS) 基本都是官网的东西,只是有些坑做了记录. http://docs.jumpserver.org/zh/docs/step_by_step.html 环境 系统: Cent ...
- ELK的高级篇(测试记录各种日志)
一.elk架构已经完成情况情况下 访问限制: 加个x-pack插件 1)一个脚本收集多个日志,if 判断写入es的索引 [root@k8s6 conf.d]# cat file.conf inpu ...
随机推荐
- 面试官:RocketMQ是什么,它有什么特性与使用场景?
哈喽!大家好,我是小奇,一位热爱分享的程序员 小奇打算以轻松幽默的对话方式来分享一些技术,如果你觉得通过小奇的文章学到了东西,那就给小奇一个赞吧 文章持续更新 一.前言 作为一名Java程序员,Roc ...
- 解决mysq服务无法正常启动问题
在mysql的启动过程中,遇到什么问题都可以反馈给我,我都会尽力帮你们解决 第一种:通过net start mysql启动MySQL服务器时,出现以下信息 是因为在MySQL5.7以上的版本中默认的没 ...
- Spring Boot 2.7.0发布,2.5停止维护,节奏太快了吧
这几天是Spring版本日,很多Spring工件都发布了新版本, Spring Framework 6.0.0 发布了第 4 个里程碑版本,此版本包含所有针对 5.3.20 的修复补丁,以及特定于 6 ...
- Spring-Batch将CSV文件转为XML文件
1 介绍 用Spring Batch实现一个简单的需求,将csv文件转换成xml文件. csv文件如下:record.csv username, user_id, transaction_date, ...
- 多态——JavaSE基础
多态 同一个方法可以根据对象的不同采取不同的动作 一个对象的实际类型是确定的,但可以指向对象的引用类型有很多 基本条件: 有继承关系 子类重写父类方法 父类引用指向子类对象Father f1 = ne ...
- C#中的枚举器
更新记录 本文迁移自Panda666原博客,原发布时间:2021年6月28日. 一.先从可枚举类型讲起 1.1 什么是可枚举类型? 可枚举类型,可以简单的理解为: 有一个类,类中有挺多的数据,用一种统 ...
- 离线环境使用NuGet
更新记录 本文迁移自Panda666原博客,原发布时间:2021年5月13日. 在Visual Studio中直接使用GUI的方式操作NuGet包非常的方便.如果喜欢命令行,也可以使用包管理控制台或者 ...
- LVS+keepalived简单搭建(二)
在LVS1的基础上进行搭建 https://www.cnblogs.com/hikoukay/p/12860476.html keeplived主机 用node01,node04两台 先清掉原先nod ...
- sharepoint 配置失败,已引发类型为System.ArgumentException的异常。其他异常信息:domainName参数不支持指定的值。
解决方法:在域控制器中加入sharepoint计算机,设置为administrators组中
- pyenv安装及使用教程
pyenv安装及使用教程 pyenv 安装 git clone https://github.com/pyenv/pyenv.git ~/.pyenv # 编辑 bashrc vim ~/.bashr ...