summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuca Casonato <lucacasonato@yahoo.com>2021-04-19 17:07:44 +0200
committerGitHub <noreply@github.com>2021-04-19 17:07:44 +0200
commitfe59e7ae6034249c47eaf94f4258bb4467153f0d (patch)
tree2c9fbc10382dc151c2f5c6d0284b98faf19a2052
parent4786e1d92dcbdcbe743c5e2be0878c3c4f68e781 (diff)
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.
-rw-r--r--cli/tests/unit/http_test.ts1
-rw-r--r--runtime/ops/http.rs24
2 files changed, 24 insertions, 1 deletions
diff --git a/cli/tests/unit/http_test.ts b/cli/tests/unit/http_test.ts
index 6383afd42..d661acbd1 100644
--- a/cli/tests/unit/http_test.ts
+++ b/cli/tests/unit/http_test.ts
@@ -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" } }));
}
diff --git a/runtime/ops/http.rs b/runtime/ops/http.rs
index 57df19d84..bdef14594 100644
--- a/runtime/ops/http.rs
+++ b/runtime/ops/http.rs
@@ -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);