fix(rt/http): correct URL in Request (#10256)

This commit fixes the URL returned from `request.url` in the HTTP server
to be fully qualified. This previously existed, but was removed and
accidentially not readded during optimizations of the HTTP ops.

Returning a non fully qualified URL from `Request#url` is not spec
compliant.
This commit is contained in:
Luca Casonato 2021-04-19 17:07:44 +02:00 committed by GitHub
parent 4786e1d92d
commit fe59e7ae60
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 24 additions and 1 deletions

View File

@ -12,6 +12,7 @@ unitTest({ perms: { net: true } }, async function httpServerBasic() {
for await (const conn of listener) {
const httpConn = Deno.serveHttp(conn);
for await (const { request, respondWith } of httpConn) {
assertEquals(new URL(request.url).href, "http://127.0.0.1:4501/");
assertEquals(await request.text(), "");
respondWith(new Response("Hello World", { headers: { "foo": "bar" } }));
}

View File

@ -32,6 +32,7 @@ use serde::Serialize;
use std::borrow::Cow;
use std::cell::RefCell;
use std::future::Future;
use std::net::SocketAddr;
use std::pin::Pin;
use std::rc::Rc;
use std::task::Context;
@ -100,6 +101,7 @@ enum ConnType {
struct ConnResource {
hyper_connection: ConnType,
deno_service: Service,
addr: SocketAddr,
}
impl ConnResource {
@ -190,7 +192,23 @@ async fn op_http_request_next(
headers.push((name, value));
}
let url = req.uri().to_string();
let url = {
let scheme = {
match conn_resource.hyper_connection {
ConnType::Tcp(_) => "http",
ConnType::Tls(_) => "https",
}
};
let host: Cow<str> = if let Some(host) = req.uri().host() {
Cow::Borrowed(host)
} else if let Some(host) = req.headers().get("HOST") {
Cow::Borrowed(host.to_str()?)
} else {
Cow::Owned(conn_resource.addr.to_string())
};
let path = req.uri().path_and_query().unwrap();
format!("{}://{}{}", scheme, host, path)
};
let has_body = if let Some(exact_size) = req.size_hint().exact() {
exact_size > 0
@ -267,12 +285,14 @@ fn op_http_start(
.expect("Only a single use of this resource should happen");
let (read_half, write_half) = resource.into_inner();
let tcp_stream = read_half.reunite(write_half)?;
let addr = tcp_stream.local_addr()?;
let hyper_connection = Http::new()
.with_executor(LocalExecutor)
.serve_connection(tcp_stream, deno_service.clone());
let conn_resource = ConnResource {
hyper_connection: ConnType::Tcp(Rc::new(RefCell::new(hyper_connection))),
deno_service,
addr,
};
let rid = state.resource_table.add(conn_resource);
return Ok(rid);
@ -286,6 +306,7 @@ fn op_http_start(
.expect("Only a single use of this resource should happen");
let (read_half, write_half) = resource.into_inner();
let tls_stream = read_half.unsplit(write_half);
let addr = tls_stream.get_ref().0.local_addr()?;
let hyper_connection = Http::new()
.with_executor(LocalExecutor)
@ -293,6 +314,7 @@ fn op_http_start(
let conn_resource = ConnResource {
hyper_connection: ConnType::Tls(Rc::new(RefCell::new(hyper_connection))),
deno_service,
addr,
};
let rid = state.resource_table.add(conn_resource);
return Ok(rid);