net.http: send Host headers with port (when the port is != 80 or 443) (fix #22941) (#22942)

This commit is contained in:
Vithorio Polten 2024-11-23 13:51:28 -03:00 committed by GitHub
parent 393e4ea8b2
commit f89cffad53
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 41 additions and 9 deletions

View File

@ -33,7 +33,7 @@ fn net_ssl_do(req &Request, port int, method Method, host_name string, path stri
break break
} }
req_headers := req.build_request_headers(method, host_name, path) req_headers := req.build_request_headers(method, host_name, port, path)
$if trace_http_request ? { $if trace_http_request ? {
eprint('> ') eprint('> ')
eprint(req_headers) eprint(req_headers)

View File

@ -20,7 +20,7 @@ fn vschannel_ssl_do(req &Request, port int, method Method, host_name string, pat
C.vschannel_init(&ctx) C.vschannel_init(&ctx)
mut buff := unsafe { malloc_noscan(C.vsc_init_resp_buff_size) } mut buff := unsafe { malloc_noscan(C.vsc_init_resp_buff_size) }
addr := host_name addr := host_name
sdata := req.build_request_headers(method, host_name, path) sdata := req.build_request_headers(method, host_name, port, path)
$if trace_http_request ? { $if trace_http_request ? {
eprintln('> ${sdata}') eprintln('> ${sdata}')
} }

View File

@ -85,9 +85,9 @@ fn (pr &HttpProxy) build_proxy_headers(host string) string {
} }
fn (pr &HttpProxy) http_do(host urllib.URL, method Method, path string, req &Request) !Response { fn (pr &HttpProxy) http_do(host urllib.URL, method Method, path string, req &Request) !Response {
host_name, _ := net.split_address(host.hostname())! host_name, port := net.split_address(host.hostname())!
s := req.build_request_headers(req.method, host_name, path) s := req.build_request_headers(req.method, host_name, port, path)
if host.scheme == 'https' { if host.scheme == 'https' {
mut client := pr.ssl_dial('${host.host}:443')! mut client := pr.ssl_dial('${host.host}:443')!
@ -99,7 +99,7 @@ fn (pr &HttpProxy) http_do(host urllib.URL, method Method, path string, req &Req
// return response_text // return response_text
} $else { } $else {
response_text := req.do_request(req.build_request_headers(req.method, host_name, response_text := req.do_request(req.build_request_headers(req.method, host_name,
path), mut client)! port, path), mut client)!
client.shutdown()! client.shutdown()!
return response_text return response_text
} }

View File

@ -181,7 +181,7 @@ fn (req &Request) method_and_url_to_response(method Method, url urllib.URL) !Res
return error('http.request.method_and_url_to_response: unsupported scheme: "${scheme}"') return error('http.request.method_and_url_to_response: unsupported scheme: "${scheme}"')
} }
fn (req &Request) build_request_headers(method Method, host_name string, path string) string { fn (req &Request) build_request_headers(method Method, host_name string, port int, path string) string {
mut sb := strings.new_builder(4096) mut sb := strings.new_builder(4096)
version := if req.version == .unknown { Version.v1_1 } else { req.version } version := if req.version == .unknown { Version.v1_1 } else { req.version }
sb.write_string(method.str()) sb.write_string(method.str())
@ -192,7 +192,11 @@ fn (req &Request) build_request_headers(method Method, host_name string, path st
sb.write_string('\r\n') sb.write_string('\r\n')
if !req.header.contains(.host) { if !req.header.contains(.host) {
sb.write_string('Host: ') sb.write_string('Host: ')
if port != 80 && port != 443 && port != 0 {
sb.write_string('${host_name}:${port}')
} else {
sb.write_string(host_name) sb.write_string(host_name)
}
sb.write_string('\r\n') sb.write_string('\r\n')
} }
if !req.header.contains(.user_agent) { if !req.header.contains(.user_agent) {
@ -254,8 +258,8 @@ fn (req &Request) build_request_cookies_header() string {
} }
fn (req &Request) http_do(host string, method Method, path string) !Response { fn (req &Request) http_do(host string, method Method, path string) !Response {
host_name, _ := net.split_address(host)! host_name, port := net.split_address(host)!
s := req.build_request_headers(method, host_name, path) s := req.build_request_headers(method, host_name, port, path)
mut client := net.dial_tcp(host)! mut client := net.dial_tcp(host)!
client.set_read_timeout(req.read_timeout) client.set_read_timeout(req.read_timeout)
client.set_write_timeout(req.write_timeout) client.set_write_timeout(req.write_timeout)

View File

@ -248,3 +248,31 @@ fn test_my_counting_handler_on_random_port() {
} }
assert true assert true
} }
//
struct MyCustomHttpHostHandler {}
fn (mut handler MyCustomHttpHostHandler) handle(req http.Request) http.Response {
dump(req.header)
return http.Response{
body: 'Host was: ${req.header.get(.host) or { '-' }}'
}
}
fn test_host_header_sent_to_server() {
port := 54671
log.warn('${@FN} started')
defer { log.warn('${@FN} finished') }
mut server := &http.Server{
handler: MyCustomHttpHostHandler{}
addr: ':${port}'
}
t := spawn server.listen_and_serve()
server.wait_till_running()!
defer { server.stop() }
dump(server.addr)
x := http.get('http://${server.addr}/')!
dump(x)
assert x.body.ends_with(':${port}')
}