in protocol/triple/triple_protocol/protocol_triple.go [126:221]
func (h *tripleHandler) NewConn(
responseWriter http.ResponseWriter,
request *http.Request,
) (handlerConnCloser, bool) {
if request.Method != http.MethodPost {
return nil, false
}
// We need to parse metadata before entering the interceptor stack; we'll
// send the error to the client later on.
var contentEncoding, acceptEncoding string
contentEncoding = getHeaderCanonical(request.Header, tripleUnaryHeaderCompression)
acceptEncoding = getHeaderCanonical(request.Header, tripleUnaryHeaderAcceptCompression)
requestCompression, responseCompression, failed := negotiateCompression(
h.CompressionPools,
contentEncoding,
acceptEncoding,
)
if failed == nil {
version := getHeaderCanonical(request.Header, tripleHeaderProtocolVersion)
if version == "" && h.RequireTripleProtocolHeader {
failed = errorf(CodeInvalidArgument, "missing required header: set %s to %q", tripleHeaderProtocolVersion, tripleProtocolVersion)
} else if version != "" && version != tripleProtocolVersion {
failed = errorf(CodeInvalidArgument, "%s must be %q: got %q", tripleHeaderProtocolVersion, tripleProtocolVersion, version)
}
}
var requestBody io.ReadCloser
var contentType, codecName string
requestBody = request.Body
//Prioritize codec specified by content-type
contentType = getHeaderCanonical(request.Header, headerContentType)
codecName = tripleCodecFromContentType(
h.Spec.StreamType,
contentType,
)
codec := h.Codecs.Get(codecName)
backupCodec := h.Codecs.Get(h.ExpectedCodecName)
// todo:// need to figure it out
// The codec can be nil in the GET request case; that's okay: when failed
// is non-nil, codec is never used.
if failed == nil && codec == nil {
failed = errorf(CodeInvalidArgument, "invalid message encoding: %q", codecName)
}
// Write any remaining headers here:
// (1) any writes to the stream will implicitly send the headers, so we
// should get all of gRPC's required response headers ready.
// (2) interceptors should be able to see these headers.
//
// Since we know that these header keys are already in canonical form, we can
// skip the normalization in Header.Set.
header := responseWriter.Header()
header[headerContentType] = []string{contentType}
acceptCompressionHeader := tripleUnaryHeaderAcceptCompression
header[acceptCompressionHeader] = []string{h.CompressionPools.CommaSeparatedNames()}
var conn handlerConnCloser
peer := Peer{
Addr: request.RemoteAddr,
Protocol: ProtocolTriple,
}
conn = &tripleUnaryHandlerConn{
spec: h.Spec,
peer: peer,
request: request,
responseWriter: responseWriter,
marshaler: tripleUnaryMarshaler{
writer: responseWriter,
codec: codec,
backupCodec: backupCodec,
compressMinBytes: h.CompressMinBytes,
compressionName: responseCompression,
compressionPool: h.CompressionPools.Get(responseCompression),
bufferPool: h.BufferPool,
header: responseWriter.Header(),
sendMaxBytes: h.SendMaxBytes,
},
unmarshaler: tripleUnaryUnmarshaler{
reader: requestBody,
codec: codec,
backupCodec: backupCodec,
compressionPool: h.CompressionPools.Get(requestCompression),
bufferPool: h.BufferPool,
readMaxBytes: h.ReadMaxBytes,
},
responseTrailer: make(http.Header),
}
conn = wrapHandlerConnWithCodedErrors(conn)
if failed != nil {
// Negotiation failed, so we can't establish a stream.
_ = conn.Close(failed)
return nil, false
}
return conn, true
}