Как мне сопоставить мою рабочую команду curl с вызовом grpc-web?
Я пытаюсь получить работающий экземпляр grpc-web. У меня есть бэкэнд-сервис, который выглядит следующим образом.
var grpc = require('grpc');
var messages = require('./example_pb');
var service = require('./example_grpc_pb');
function exampleOne(call) {
var response = new messages.ExampleOneRequest();
call.write(response);
call.end();
}
function main() {
var server = new grpc.Server();
server.addService(
services.MyExampleService,
{
example : exampleOne
}
);
server.bind('0.0.0.0:8050', grpc.ServerCredentials.createInsecure());
server.start();
}
main();
Я проверил это с помощью "клиентской части" на стороне сервера, поэтому сейчас я пытаюсь подключить реальный клиент на основе веб-браузера. Сначала я настроил прокси, который, по-видимому, необходим? Я решил использовать grpcwebproxy, основанный на GoLang, который кажется приемлемым выбором в соответствии с документацией grpc-web.
>> grpcwebproxy --backend_addr=localhost:8050 \
--server_tls_cert_file=/usr2/certs/server/localhost.localdomain.crt \
--server_tls_key_file=/usr2/certs/server/localhost.localdomain.key
Вывод выглядит так
INFO[0000] dialing to target with scheme: "" system=system
INFO[0000] ccResolverWrapper: sending new addresses to cc: [{localhost:8050 0 <nil>}] system=system
INFO[0000] listening for http on: [::]:8080
INFO[0000] listening for http_tls on: [::]:8443
INFO[0000] pickfirstBalancer: HandleSubConnStateChange: 0xc4201638a0, CONNECTING system=system
INFO[0000] pickfirstBalancer: HandleSubConnStateChange: 0xc4201638a0, READY system=system
Я не могу заставить работать веб-браузер, просто получаю несколько общих / связанных с CORS 500 ошибок.
Я вернулся на свою серверную часть и решил свернуть прокси. Кажется, что http2 не поддерживается с моей текущей версией curl, поэтому я вместо этого использую инструмент под названием h2c.
Короче говоря, я пытаюсь проверить связь с портом tls 8443 и получаю следующее (наиболее многообещающее).
>> ./h2c_linux_amd64 get https://localhost:8443/service.path/ExampleOne
invalid gRPC request method
Я пытаюсь это
>> ./h2c_linux_amd64 get http://localhost:8443/service.path/ExampleOne
http connections not supported.
Я пытаюсь это
>> ./h2c_linux_amd64 get http://localhost:8080/service.path/ExampleOne
http connections not supported.
Я пытаюсь это
>> ./h2c_linux_amd64 get https://localhost:8080/service.path/ExampleOne
Failed to connect to localhost:8080: tls: oversized record received with length 20527
Я не ожидаю мгновенного ответа типа "это ваше решение", так как я многое не учел, но есть ли у кого-нибудь какие-либо предложения о том, как с этим работать?
Я получил ошибку
"invalid gRPC request method"
кажется наиболее многообещающим, хотя и общим.
РЕДАКТИРОВАТЬ:
Кажется, они стали немного ближе, по крайней мере, для отладки серверной части. Вернулся к использованию curl. Это была моя команда
curl 'https://localhost:8443/service.path/ExampleOne' \
-H 'content-type: application/grpc-web+proto' \
-H 'x-grpc-web: 1' \
-H 'authority: localhost:8443' \
--data-binary $'\x00\x00\x00\x00\x04\n\x02yo' \
--insecure
С помощью этой команды я смог сделать это через grpcwebproxy, к моей службе и обратно на другую сторону. Кажется, что-то в обеспечении curl двоичной строкой помогает. Я говорю это, потому что
curl 'https://localhost:8443/service.path/ExampleOne' \
-H 'content-type: application/grpc-web+proto' \
-H 'x-grpc-web: 1' \
-H 'authority: localhost:8443' \
--insecure
приводит к сообщению об ошибке
gRPC requires HTTP/2
Теперь мне нужно отобразить приведенную выше команду curl в действительный веб-запрос grpc.
РЕДАКТИРОВАТЬ 2:
Я сейчас нахожусь в точке, где я думаю, что мне требуется сертификат. Код из браузера бьет мой grpcwebproxy, но я вижу сообщение об ошибке
2018/10/17 12:21:56 http2: server: error reading preface from client 127.0.0.1:45056: remote error: tls: unknown certificate authority
2018/10/17 12:21:56 http2: server: error reading preface from client 127.0.0.1:45058: remote error: tls: unknown certificate authority
2018/10/17 12:21:56 http2: server: error reading preface from client 127.0.0.1:45060: remote error: tls: unknown certificate authority
Это происходит в выводе grpcwebproxy, поэтому я знаю, что запрос по крайней мере делает его там.
Я думаю, что я обошел это ранее с помощью curl, включив тег --insecure... не знаю, как повторить это в браузере.
1 ответ
Один из вариантов, который у вас есть, - начать с нашего примера с Echo и настроить его оттуда. Я только что попробовал наш пример (тот, который использует grpcwebproxy), и это работает.
$ git clone https://github.com/grpc/grpc-web
$ cd grpc-web
$ docker-compose build prereqs common node-server grpcwebproxy binary-client
$ docker-compose up -d node-server grpcwebproxy binary-client
Браузер: localhost:8081/echotest.html
Из браузера, если я "скопировать как cURL", я получил
curl 'http://localhost:8080/grpc.gateway.testing.EchoService/Echo' -H 'Pragma: no-cache' -H 'X-User-Agent: grpc-web-javascript/0.1' -H 'Origin: http://localhost:8081' -H 'Accept-Encoding: gzip, deflate, br' -H 'Accept-Language: en-US,en;q=0.9' -H 'custom-header-1: value1' -H 'User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36' -H 'Content-Type: application/grpc-web+proto' -H 'Accept: */*' -H 'X-Grpc-Web: 1' -H 'Cache-Control: no-cache' -H 'Referer: http://localhost:8081/echotest.html' -H 'Connection: keep-alive' --data-binary $'\x00\x00\x00\x00\x05\n\x03abc' --compressed