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 ...
随机推荐
- 斯坦福NLP课程 | 第11讲 - NLP中的卷积神经网络
作者:韩信子@ShowMeAI,路遥@ShowMeAI,奇异果@ShowMeAI 教程地址:http://www.showmeai.tech/tutorials/36 本文地址:http://www. ...
- 渗透:winpcap
winpcap(windows packet capture)是windows平台下一个免费,公共的网络访问系统.开发winpcap这个项目的目的在于为win32应用程序提供访问网络底层的能力.它提供 ...
- Slab 分配器
1.什么是Slab 分配器: 以下摘自维基百科:https://en.wikipedia.org/wiki/Slab_allocation Slab firstly introduced in ke ...
- 【单片机】使用 sscanf 提取AT命令返回结果中的有效数据
摘要:1. sscanf函数 sscanf是C标准库函数,用于从字符串中读取格式化输入. 头文件: #include <stdio.h>函数原型如下: int sscanf(const c ...
- 微信小程序开发 记录
采坑了 微信小程序--TabBar不出现的一种原因 学习微信小程序中,遇到底部的TabBar不出现的问题.经过多番尝试,终于解决问题.在此记录问题产生的原因和对策.下面先描述错误现象,接着指出错误原因 ...
- dubbo是如何实现可扩展的?(二)
牛逼的框架,看似复杂难懂,思路其实很清晰.---me 上篇文章,在整体扩展思路上进行了源码分析,比较粗糙,现在就某些点再详细梳理下. dubbo SPi的扩展,基于一类.三注解. 一类是Extensi ...
- [第18届 科大讯飞杯 J] 能到达吗
能到达吗 题目链接:牛客5278 J 能到达吗 Description 给定一个 \(n\times m\) 的地图,地图的左上角为 \((1, 1)\) ,右下角为 \((n,m)\). 地图上有 ...
- 免费CDN:jsDelivr+Github 使用方法
转自 https://zhuanlan.zhihu.com/p/76951130 本文在CSDN上的链接:https://blog.csdn.net/qq_36759224/article/detai ...
- 【ASP.NET Core】配置应用程序地址的N多种方法
下面又到了老周误人子弟的时间,今天要误大伙的话题是:找找有多少种方法可以设置 ASP.NET Core 应用的地址,即 URL. 精彩马上开始! 1.UseUrls 方法 这是一个扩展方法,参数是可变 ...
- Java添加条形码到PDF表格
条码的应用已深入生活和工作的方方面面.在处理条码时,常需要和各种文档格式相结合.当需要在文档中插入.编辑或者删除条码时,可借助于一些专业的类库工具来实现.本文,以操作PDF文件为例,介绍如何在编辑表格 ...