mirror of https://github.com/grpc/grpc-web.git
Supports base64 encoded gRPC-Web with content-type: application/grpc-web-text and content-type: application/grpc-web-text+proto.
This commit is contained in:
parent
ce71327260
commit
6e5d2dcef3
|
|
@ -0,0 +1,25 @@
|
|||
#include "net/grpc/gateway/codec/grpc_web_text_decoder.h"
|
||||
|
||||
namespace grpc {
|
||||
namespace gateway {
|
||||
|
||||
GrpcWebTextDecoder::GrpcWebTextDecoder() {}
|
||||
|
||||
GrpcWebTextDecoder::~GrpcWebTextDecoder() {}
|
||||
|
||||
Status GrpcWebTextDecoder::Decode() {
|
||||
std::vector<Slice> buffer;
|
||||
if (!base64_.Decode(*inputs(), &buffer)) {
|
||||
return Status(StatusCode::INVALID_ARGUMENT, "Invalid base64 inputs.");
|
||||
}
|
||||
|
||||
inputs()->clear();
|
||||
for (Slice& s : buffer) {
|
||||
Append(s);
|
||||
}
|
||||
|
||||
return GrpcWebDecoder::Decode();
|
||||
}
|
||||
|
||||
} // namespace gateway
|
||||
} // namespace grpc
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
#ifndef NET_GRPC_GATEWAY_CODEC_GRPC_WEB_TEXT_DECODER_H_
|
||||
#define NET_GRPC_GATEWAY_CODEC_GRPC_WEB_TEXT_DECODER_H_
|
||||
|
||||
#include "net/grpc/gateway/codec/base64.h"
|
||||
#include "net/grpc/gateway/codec/grpc_web_decoder.h"
|
||||
|
||||
namespace grpc {
|
||||
namespace gateway {
|
||||
|
||||
class GrpcWebTextDecoder : public GrpcWebDecoder {
|
||||
public:
|
||||
GrpcWebTextDecoder();
|
||||
~GrpcWebTextDecoder() override;
|
||||
GrpcWebTextDecoder(const GrpcWebTextDecoder&) = delete;
|
||||
GrpcWebTextDecoder& operator=(const GrpcWebTextDecoder&) = delete;
|
||||
|
||||
Status Decode() override;
|
||||
|
||||
private:
|
||||
Base64 base64_;
|
||||
};
|
||||
|
||||
} // namespace gateway
|
||||
} // namespace grpc
|
||||
|
||||
#endif // NET_GRPC_GATEWAY_CODEC_GRPC_WEB_TEXT_DECODER_H_
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
#include "net/grpc/gateway/codec/grpc_web_text_encoder.h"
|
||||
|
||||
namespace grpc {
|
||||
namespace gateway {
|
||||
|
||||
GrpcWebTextEncoder::GrpcWebTextEncoder() {}
|
||||
|
||||
GrpcWebTextEncoder::~GrpcWebTextEncoder() {}
|
||||
|
||||
void GrpcWebTextEncoder::Encode(grpc::ByteBuffer* input,
|
||||
std::vector<Slice>* result) {
|
||||
std::vector<Slice> buffer;
|
||||
GrpcWebEncoder::Encode(input, &buffer);
|
||||
base64_.Encode(buffer, result);
|
||||
}
|
||||
|
||||
void GrpcWebTextEncoder::EncodeStatus(const grpc::Status& status,
|
||||
const Trailers* trailers,
|
||||
std::vector<Slice>* result) {
|
||||
std::vector<Slice> buffer;
|
||||
GrpcWebEncoder::EncodeStatus(status, trailers, &buffer);
|
||||
base64_.Encode(buffer, result);
|
||||
}
|
||||
|
||||
} // namespace gateway
|
||||
} // namespace grpc
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
#ifndef NET_GRPC_GATEWAY_CODEC_GRPC_WEB_TEXT_ENCODER_H_
|
||||
#define NET_GRPC_GATEWAY_CODEC_GRPC_WEB_TEXT_ENCODER_H_
|
||||
|
||||
#include "net/grpc/gateway/codec/base64.h"
|
||||
#include "net/grpc/gateway/codec/grpc_web_encoder.h"
|
||||
|
||||
namespace grpc {
|
||||
namespace gateway {
|
||||
|
||||
class GrpcWebTextEncoder : public GrpcWebEncoder {
|
||||
public:
|
||||
GrpcWebTextEncoder();
|
||||
~GrpcWebTextEncoder() override;
|
||||
GrpcWebTextEncoder(const GrpcWebTextEncoder&) = delete;
|
||||
GrpcWebTextEncoder& operator=(const GrpcWebTextEncoder&) = delete;
|
||||
|
||||
void Encode(grpc::ByteBuffer* input, std::vector<Slice>* result) override;
|
||||
void EncodeStatus(const grpc::Status& status, const Trailers* trailers,
|
||||
std::vector<Slice>* result) override;
|
||||
|
||||
private:
|
||||
Base64 base64_;
|
||||
};
|
||||
|
||||
} // namespace gateway
|
||||
} // namespace grpc
|
||||
|
||||
#endif // NET_GRPC_GATEWAY_CODEC_GRPC_WEB_TEXT_ENCODER_H_
|
||||
|
|
@ -512,6 +512,9 @@ void NginxHttpFrontend::SendResponseHeadersToClient(Response *response) {
|
|||
case GRPC_WEB:
|
||||
AddHTTPHeader(http_request_, kContentType, kContentTypeGrpcWeb);
|
||||
break;
|
||||
case GRPC_WEB_TEXT:
|
||||
AddHTTPHeader(http_request_, kContentType, kContentTypeGrpcWebText);
|
||||
break;
|
||||
case JSON_STREAM_BODY:
|
||||
AddHTTPHeader(http_request_, kContentType, kContentTypeJson);
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -78,6 +78,9 @@ const char kContentLength[] = "content-length";
|
|||
// The metadata name of content-transfer-encoding.
|
||||
const char kContentTransferEncoding[] = "content-transfer-encoding";
|
||||
|
||||
// The metadata name of accept.
|
||||
const char kAccept[] = "accept";
|
||||
|
||||
// The metadata value of content-transfer-encoding for base64.
|
||||
const char kContentTransferEncoding_Base64[] = "base64";
|
||||
const size_t kContentTransferEncoding_Base64_Length =
|
||||
|
|
@ -103,6 +106,7 @@ enum Protocol {
|
|||
UNKNOWN = 0,
|
||||
GRPC,
|
||||
GRPC_WEB,
|
||||
GRPC_WEB_TEXT,
|
||||
JSON_STREAM_BODY,
|
||||
PROTO_STREAM_BODY,
|
||||
B64_PROTO_STREAM_BODY,
|
||||
|
|
|
|||
|
|
@ -14,6 +14,8 @@
|
|||
#include "net/grpc/gateway/codec/grpc_encoder.h"
|
||||
#include "net/grpc/gateway/codec/grpc_web_decoder.h"
|
||||
#include "net/grpc/gateway/codec/grpc_web_encoder.h"
|
||||
#include "net/grpc/gateway/codec/grpc_web_text_decoder.h"
|
||||
#include "net/grpc/gateway/codec/grpc_web_text_encoder.h"
|
||||
#include "net/grpc/gateway/codec/json_decoder.h"
|
||||
#include "net/grpc/gateway/codec/json_encoder.h"
|
||||
#include "net/grpc/gateway/codec/proto_decoder.h"
|
||||
|
|
@ -62,6 +64,19 @@ bool IsResponseB64(ngx_http_request_t* http_request) {
|
|||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool IsResponseGrpcWebText(ngx_http_request_t* http_request) {
|
||||
string_ref value =
|
||||
GetHTTPHeader(&http_request->headers_in.headers.part, kAccept);
|
||||
if ((kContentTypeGrpcWebTextLength == value.size() &&
|
||||
strncasecmp(kContentTypeGrpcWebText, value.data(), value.size()) == 0) ||
|
||||
(kContentTypeGrpcWebTextProtoLength == value.size() &&
|
||||
strncasecmp(kContentTypeGrpcWebTextProto, value.data(), value.size()) ==
|
||||
0)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
Runtime::Runtime() {
|
||||
|
|
@ -116,6 +131,8 @@ std::unique_ptr<Encoder> Runtime::CreateEncoder(
|
|||
return std::unique_ptr<Encoder>(new GrpcEncoder());
|
||||
case GRPC_WEB:
|
||||
return std::unique_ptr<Encoder>(new GrpcWebEncoder());
|
||||
case GRPC_WEB_TEXT:
|
||||
return std::unique_ptr<Encoder>(new GrpcWebTextEncoder());
|
||||
case JSON_STREAM_BODY:
|
||||
return std::unique_ptr<Encoder>(new JsonEncoder());
|
||||
case PROTO_STREAM_BODY:
|
||||
|
|
@ -151,6 +168,8 @@ std::unique_ptr<Decoder> Runtime::CreateDecoder(
|
|||
}
|
||||
case GRPC_WEB:
|
||||
return std::unique_ptr<Decoder>(new GrpcWebDecoder());
|
||||
case GRPC_WEB_TEXT:
|
||||
return std::unique_ptr<Decoder>(new GrpcWebTextDecoder());
|
||||
case JSON_STREAM_BODY:
|
||||
return std::unique_ptr<Decoder>(new JsonDecoder());
|
||||
case PROTO_STREAM_BODY:
|
||||
|
|
@ -208,11 +227,22 @@ Protocol Runtime::DetectRequestProtocol(ngx_http_request_t* http_request) {
|
|||
0) {
|
||||
return GRPC;
|
||||
}
|
||||
if (content_type_length == kContentTypeGrpcWebLength &&
|
||||
strncasecmp(kContentTypeGrpcWeb, content_type,
|
||||
kContentTypeGrpcWebLength) == 0) {
|
||||
if ((content_type_length == kContentTypeGrpcWebLength &&
|
||||
strncasecmp(kContentTypeGrpcWeb, content_type,
|
||||
kContentTypeGrpcWebLength) == 0) ||
|
||||
(content_type_length == kContentTypeGrpcWebProtoLength &&
|
||||
strncasecmp(kContentTypeGrpcWebProto, content_type,
|
||||
kContentTypeGrpcWebProtoLength) == 0)) {
|
||||
return GRPC_WEB;
|
||||
}
|
||||
if ((content_type_length == kContentTypeGrpcWebTextLength &&
|
||||
strncasecmp(kContentTypeGrpcWebText, content_type,
|
||||
kContentTypeGrpcWebTextLength) == 0) ||
|
||||
(content_type_length == kContentTypeGrpcWebTextProtoLength &&
|
||||
strncasecmp(kContentTypeGrpcWebTextProto, content_type,
|
||||
kContentTypeGrpcWebTextProtoLength) == 0)) {
|
||||
return GRPC_WEB_TEXT;
|
||||
}
|
||||
return UNKNOWN;
|
||||
}
|
||||
|
||||
|
|
@ -252,9 +282,21 @@ Protocol Runtime::DetectResponseProtocol(ngx_http_request_t* http_request) {
|
|||
0) {
|
||||
return GRPC;
|
||||
}
|
||||
if (content_type_length == kContentTypeGrpcWebLength &&
|
||||
strncasecmp(kContentTypeGrpcWeb, content_type,
|
||||
kContentTypeGrpcWebLength) == 0) {
|
||||
if ((content_type_length == kContentTypeGrpcWebLength &&
|
||||
strncasecmp(kContentTypeGrpcWeb, content_type,
|
||||
kContentTypeGrpcWebLength) == 0) ||
|
||||
(content_type_length == kContentTypeGrpcWebProtoLength &&
|
||||
strncasecmp(kContentTypeGrpcWebProto, content_type,
|
||||
kContentTypeGrpcWebProtoLength) == 0) ||
|
||||
(content_type_length == kContentTypeGrpcWebTextLength &&
|
||||
strncasecmp(kContentTypeGrpcWebText, content_type,
|
||||
kContentTypeGrpcWebTextLength) == 0) ||
|
||||
(content_type_length == kContentTypeGrpcWebTextProtoLength &&
|
||||
strncasecmp(kContentTypeGrpcWebTextProto, content_type,
|
||||
kContentTypeGrpcWebTextProtoLength) == 0)) {
|
||||
if (IsResponseGrpcWebText(http_request)) {
|
||||
return GRPC_WEB_TEXT;
|
||||
}
|
||||
return GRPC_WEB;
|
||||
}
|
||||
return UNKNOWN;
|
||||
|
|
|
|||
Loading…
Reference in New Issue