Skip to content
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

Allow to set Host header for Client #1169

Merged
merged 4 commits into from Dec 17, 2021
Merged
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
7 changes: 6 additions & 1 deletion http.go
Expand Up @@ -56,6 +56,9 @@ type Request struct {
// Request timeout. Usually set by DoDeadline or DoTimeout
// if <= 0, means not set
timeout time.Duration

// Allow to change Host header with parsedURI == true (E.g. Client for type).
AllowToChangeHostHeader bool
Copy link
Collaborator

Choose a reason for hiding this comment

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

I think something like this is cleaner?

Suggested change
// Allow to change Host header with parsedURI == true (E.g. Client for type).
AllowToChangeHostHeader bool
// Use Host header (request.Header.SetHost) instead of the host from SetRequestURI, SetHost, or URI().SetHost
UseHostHeader bool

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good comment. I've rename attribute and add test for it.

}

// Response represents HTTP response.
Expand Down Expand Up @@ -1360,7 +1363,9 @@ func (req *Request) Write(w *bufio.Writer) error {
if len(host) == 0 {
return errRequestHostRequired
}
req.Header.SetHostBytes(host)
if len(req.Header.Host()) == 0 || !req.AllowToChangeHostHeader {
req.Header.SetHostBytes(host)
Copy link
Collaborator

Choose a reason for hiding this comment

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

Shouldn't the if len(host) == 0 { return errRequestHostRequired check then also be inside the if req.AllowToChangeHostHeader?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I don't think so. The uri.Host() used as connection address at least for Client type. If host will be empty but Host header is not, connection will be broken. I've checked such code in http.go

	if len(req.Header.Host()) == 0 || !req.UseHostHeader {
		req.Header.SetHostBytes(host)
	} else if len(host) == 0 {
		return errRequestHostRequired
	}

And such usage for this code

	req.UseHostHeader = true
	req.SetHost("")
	req.Header.SetHost(host)

There is result - lookup : no such host

We can use headers for setting uri.Host() but I am not sure that it is correct.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I've check code again. It is not important for Client, because error raised inside dialAddr. But I am still not sure that it is correct allow uri.Host() to be empty if Host header presents.

Copy link
Collaborator

Choose a reason for hiding this comment

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

But shouldn't len(host) == 0 be allowed when req.UseHostHeader === true? (when it's used outside of Client). It makes more sense to me to put that inside the if?

Sorry I'm replying bit slow, I'm traveling.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I am not sure how it should work in other cases. But when used in Client len(host) == 0 does not work. Is it ok for you if I change code to this?

if len(req.Header.Host()) == 0 || !req.UseHostHeader {
	req.Header.SetHostBytes(host)
} else if len(host) == 0 {
	return errRequestHostRequired
} 

In my case it does not important at all.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I've checked logic again and pushed a new version. errRequestHostRequired should be returned only if both uri.Host() and req.Header.Host() are empty. And it does not depend from UseHostHeader. If Header.Host() is empty we always need to set header from uri.Host(). And only when both are not empty we need to check UseHostHeader.

}
req.Header.SetRequestURIBytes(uri.RequestURI())

if len(uri.username) > 0 {
Expand Down