func()

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
}