MCPcopy
hub / github.com/connectrpc/connect-go / makeRequest

Method makeRequest

duplex_http_call.go:296–351  ·  view source on GitHub ↗
()

Source from the content-addressed store, hash-verified

294}
295
296func (d *duplexHTTPCall) makeRequest() {
297 // This runs concurrently with Write and CloseWrite. Read and CloseRead wait
298 // on d.responseReady, so we can't race with them.
299 defer close(d.responseReady)
300
301 // Promote the header Host to the request object.
302 if host := getHeaderCanonical(d.request.Header, headerHost); len(host) > 0 {
303 d.request.Host = host
304 }
305 if d.onRequestSend != nil {
306 d.onRequestSend(d.request)
307 }
308 // Once we send a message to the server, they send a message back and
309 // establish the receive side of the stream.
310 // On error, we close the request body using the Write side of the pipe.
311 // This ensures HTTP2 streams receive an io.EOF from the Read side of the
312 // pipe. Write's check for io.ErrClosedPipe and will convert this to io.EOF.
313 response, err := d.httpClient.Do(d.request) //nolint:bodyclose
314 if err != nil {
315 if errors.Is(err, io.EOF) {
316 // We use io.EOF as a sentinel in many places and don't want this
317 // transport error to be confused for those other situations.
318 err = io.ErrUnexpectedEOF
319 }
320 err = wrapIfContextError(err)
321 err = wrapIfLikelyH2CNotConfiguredError(d.request, err)
322 err = wrapIfLikelyWithGRPCNotUsedError(err)
323 err = wrapIfRSTError(d.ctx, err)
324 if _, ok := asError(err); !ok {
325 err = NewError(CodeUnavailable, err)
326 }
327 d.responseErr = err
328 _ = d.CloseWrite()
329 return
330 }
331 // We've got a response. We can now read from the response body.
332 // Closing the response body is delegated to the caller even on error.
333 d.response = response
334 if err := d.validateResponse(response); err != nil {
335 d.responseErr = err
336 _ = d.CloseWrite()
337 return
338 }
339 if (d.streamType&StreamTypeBidi) == StreamTypeBidi && response.ProtoMajor < 2 {
340 // If we somehow dialed an HTTP/1.x server, fail with an explicit message
341 // rather than returning a more cryptic error later on.
342 d.responseErr = errorf(
343 CodeUnimplemented,
344 "response from %v is HTTP/%d.%d: bidi streams require at least HTTP/2",
345 d.request.URL,
346 response.ProtoMajor,
347 response.ProtoMinor,
348 )
349 _ = d.CloseWrite()
350 }
351}
352
353// getNoBody is a GetBody function for http.NoBody.

Callers 3

SendMethod · 0.95
sendUnaryMethod · 0.95
CloseWriteMethod · 0.95

Calls 12

CloseWriteMethod · 0.95
getHeaderCanonicalFunction · 0.85
wrapIfContextErrorFunction · 0.85
wrapIfRSTErrorFunction · 0.85
asErrorFunction · 0.85
NewErrorFunction · 0.85
errorfFunction · 0.85
onRequestSendMethod · 0.65
DoMethod · 0.65
validateResponseMethod · 0.45

Tested by

no test coverage detected