Skip to content

Align the semantics of http.request.size with http.response.size #7100

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 3 commits into
base: master
Choose a base branch
from

Conversation

qdongxu
Copy link

@qdongxu qdongxu commented Jun 29, 2025

This PR is for Issue #7087

  1. record replacer "http.request.size" as well as "http.response.size"
  2. let metrics record accurate reqeust size by read from req.Body. ( metrics read from Content-Length field, which not applicable to web socket or chunked Body)
  3. cache RequestRecorder to handle records in multiple modules. ( logRequest and metrics creates its own ResponseRecorder.)
  4. refactor, put the recording function in a single place. lengthReader as a member of ResponseRecorder. it takes quite a time to understand when they separated and share a common int pointer.

2. make metrics records accurate reqeust size by read from req.Body. ( metrics read from Content-Length field, which not applicable to web socket or chunked Body)
3. cache RequestRecorder to handle records in multiple moudles. ( logRequest and metrics creates its own ResponseRecorder.)
@CLAassistant
Copy link

CLAassistant commented Jun 29, 2025

CLA assistant check
All committers have signed the CLA.

Comment on lines 373 to 374
Source io.ReadCloser
Length int
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just at first glance, is there any need for these fields to be exported? If not, could you lowercase them please?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure.

@mohammed90
Copy link
Member

There are 2 things that are unclear to me:
1- can you explain the reasoning for the double pointer on http.Request?
2- I don't understand how could you have used the ` for the imports

@@ -134,12 +141,27 @@ type responseRecorder struct {
// As a special case, 1xx responses are not buffered nor recorded
// because they are not the final response; they are passed through
// directly to the underlying ResponseWriter.
func NewResponseRecorder(w http.ResponseWriter, buf *bytes.Buffer, shouldBuffer ShouldBufferFunc) ResponseRecorder {
return &responseRecorder{
func NewResponseRecorder(w http.ResponseWriter, req **http.Request, buf *bytes.Buffer,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we should/can change this signature at this point. I'm also not clear as to why this signature is better?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some thinking as below.

@qdongxu
Copy link
Author

qdongxu commented Jun 30, 2025

There are 2 things that are unclear to me:
1- can you explain the reasoning for the double pointer on http.Request?
2- I don't understand how could you have used the ` for the imports

As for the import, it shocks me too🤣. It was mostly generated by the goland IDE. I am sorry I didn't check formattings before checking in.

As for the double pointer, the http.Request.WithContext works in a immutable way, it should returns a new instance when change the context. It looks cohensive to make the change inside the NewResponseRecorder implementation.

    c := context.WithValue(r.Context(), ResponseRecorderVarKey, rr)
    *req = r.WithContext(c)

A alternative way is to let the invoker to take care of the new r . The side effect is not obvious for the invoker(The input r changed??)

    func NewResponseRecorder(w http.ResponseWriter, req *http.Request, buf *bytes.Buffer,
	shouldBuffer ShouldBufferFunc) (wrec ResponseRecorder, newReq *http.Request , cached bool)
    // ....
    wrec, r, cached := NewResponseRecorder(w, r, nil, nil)

It's weird to input a double pointer but it's may get the invoker's attention as I had thought.

What's your opinion on the alternatives ?

qdongxu added 2 commits July 1, 2025 04:39
2. do not export internal fields of lengthReader
@qdongxu qdongxu marked this pull request as draft July 2, 2025 14:24
@qdongxu
Copy link
Author

qdongxu commented Jul 2, 2025

I converted this PR to draft. During review the caching of responseRecorder, I found its better to decouple responseRecorder into responseBuffer and responseMeter. I will do some more investigation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants