summary refs log tree commit diff
diff options
context:
space:
mode:
authorErik Johnston <erik@matrix.org>2022-12-15 14:05:59 +0000
committerErik Johnston <erik@matrix.org>2022-12-15 14:05:59 +0000
commitf5817281f8bc707ed60562706091dadccf55efe5 (patch)
treea653fae7ca87a579fc261a746ba68910b52d2e9b
parentFixup (diff)
downloadsynapse-github/erikj/rust_http.tar.xz
-rw-r--r--Cargo.lock112
-rw-r--r--rust/Cargo.toml1
-rw-r--r--rust/src/http/mod.rs34
-rw-r--r--rust/src/http/resolver.rs6
4 files changed, 140 insertions, 13 deletions
diff --git a/Cargo.lock b/Cargo.lock
index d211a42928..23108e613c 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -138,6 +138,40 @@ dependencies = [
 ]
 
 [[package]]
+name = "env_logger"
+version = "0.10.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "85cdab6a89accf66733ad5a1693a4dcced6aeff64602b634530dd73c1f3ee9f0"
+dependencies = [
+ "humantime",
+ "is-terminal",
+ "log",
+ "regex",
+ "termcolor",
+]
+
+[[package]]
+name = "errno"
+version = "0.2.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f639046355ee4f37944e44f60642c6f3a7efa3cf6b78c78a0d989a8ce6c396a1"
+dependencies = [
+ "errno-dragonfly",
+ "libc",
+ "winapi",
+]
+
+[[package]]
+name = "errno-dragonfly"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf"
+dependencies = [
+ "cc",
+ "libc",
+]
+
+[[package]]
 name = "fastrand"
 version = "1.8.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -327,6 +361,15 @@ dependencies = [
 ]
 
 [[package]]
+name = "hermit-abi"
+version = "0.2.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7"
+dependencies = [
+ "libc",
+]
+
+[[package]]
 name = "hex"
 version = "0.4.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -378,6 +421,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421"
 
 [[package]]
+name = "humantime"
+version = "2.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4"
+
+[[package]]
 name = "hyper"
 version = "0.14.23"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -461,6 +510,16 @@ dependencies = [
 ]
 
 [[package]]
+name = "io-lifetimes"
+version = "1.0.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "46112a93252b123d31a119a8d1a1ac19deac4fac6e0e8b0df58f0d4e5870e63c"
+dependencies = [
+ "libc",
+ "windows-sys 0.42.0",
+]
+
+[[package]]
 name = "ipconfig"
 version = "0.3.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -479,6 +538,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "11b0d96e660696543b251e58030cf9787df56da39dab19ad60eae7353040917e"
 
 [[package]]
+name = "is-terminal"
+version = "0.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "927609f78c2913a6f6ac3c27a4fe87f43e2a35367c0c4b0f8265e8f49a104330"
+dependencies = [
+ "hermit-abi 0.2.6",
+ "io-lifetimes",
+ "rustix",
+ "windows-sys 0.42.0",
+]
+
+[[package]]
 name = "itoa"
 version = "1.0.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -503,6 +574,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f"
 
 [[package]]
+name = "linux-raw-sys"
+version = "0.1.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f051f77a7c8e6957c0696eac88f26b0117e54f52d3fc682ab19397a8812846a4"
+
+[[package]]
 name = "lock_api"
 version = "0.4.9"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -593,7 +670,7 @@ version = "1.14.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "f6058e64324c71e02bc2b150e4f3bc8286db6c83092132ffa3f6b1eab0f9def5"
 dependencies = [
- "hermit-abi",
+ "hermit-abi 0.1.19",
  "libc",
 ]
 
@@ -896,6 +973,20 @@ dependencies = [
 ]
 
 [[package]]
+name = "rustix"
+version = "0.36.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a3807b5d10909833d3e9acd1eb5fb988f79376ff10fce42937de71a449c4c588"
+dependencies = [
+ "bitflags",
+ "errno",
+ "io-lifetimes",
+ "libc",
+ "linux-raw-sys",
+ "windows-sys 0.42.0",
+]
+
+[[package]]
 name = "ryu"
 version = "1.0.11"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1028,6 +1119,7 @@ version = "0.1.0"
 dependencies = [
  "anyhow",
  "blake2",
+ "env_logger",
  "futures",
  "futures-util",
  "hex",
@@ -1070,6 +1162,15 @@ dependencies = [
 ]
 
 [[package]]
+name = "termcolor"
+version = "1.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755"
+dependencies = [
+ "winapi-util",
+]
+
+[[package]]
 name = "thiserror"
 version = "1.0.37"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1343,6 +1444,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
 
 [[package]]
+name = "winapi-util"
+version = "0.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178"
+dependencies = [
+ "winapi",
+]
+
+[[package]]
 name = "winapi-x86_64-pc-windows-gnu"
 version = "0.4.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
diff --git a/rust/Cargo.toml b/rust/Cargo.toml
index f96f8c4041..07ae0295e0 100644
--- a/rust/Cargo.toml
+++ b/rust/Cargo.toml
@@ -21,6 +21,7 @@ name = "synapse.synapse_rust"
 
 [dependencies]
 anyhow = "1.0.63"
+env_logger = "0.10.0"
 futures = "0.3.25"
 futures-util = "0.3.25"
 http = "0.2.8"
diff --git a/rust/src/http/mod.rs b/rust/src/http/mod.rs
index 508f7cb048..c764f7c76a 100644
--- a/rust/src/http/mod.rs
+++ b/rust/src/http/mod.rs
@@ -1,7 +1,7 @@
 use std::collections::HashMap;
 
 use anyhow::Error;
-use http::Request;
+use http::{Request, Uri};
 use hyper::Body;
 use log::info;
 use pyo3::{
@@ -12,7 +12,7 @@ use pyo3::{
 
 use self::resolver::{MatrixConnector, MatrixResolver};
 
-mod resolver;
+pub mod resolver;
 
 /// Called when registering modules with python.
 pub fn register_module(py: Python<'_>, m: &PyModule) -> PyResult<()> {
@@ -31,8 +31,8 @@ pub fn register_module(py: Python<'_>, m: &PyModule) -> PyResult<()> {
     Ok(())
 }
 
-#[derive(Clone)]
-struct Bytes(Vec<u8>);
+#[derive(Clone, Debug)]
+pub struct Bytes(pub Vec<u8>);
 
 impl ToPyObject for Bytes {
     fn to_object(&self, py: Python<'_>) -> pyo3::PyObject {
@@ -46,31 +46,34 @@ impl IntoPy<PyObject> for Bytes {
     }
 }
 
+#[derive(Debug)]
 #[pyclass]
 pub struct MatrixResponse {
     #[pyo3(get)]
-    code: u16,
+    pub code: u16,
     #[pyo3(get)]
-    phrase: &'static str,
+    pub phrase: &'static str,
     #[pyo3(get)]
-    content: Bytes,
+    pub content: Bytes,
     #[pyo3(get)]
-    headers: HashMap<String, Bytes>,
+    pub headers: HashMap<String, Bytes>,
 }
 
 #[pyclass]
 #[derive(Clone)]
 pub struct HttpClient {
     client: hyper::Client<MatrixConnector>,
+    resolver: MatrixResolver,
 }
 
 impl HttpClient {
     pub fn new() -> Result<Self, Error> {
         let resolver = MatrixResolver::new()?;
 
-        let client = hyper::Client::builder().build(MatrixConnector::with_resolver(resolver));
+        let client =
+            hyper::Client::builder().build(MatrixConnector::with_resolver(resolver.clone()));
 
-        Ok(HttpClient { client })
+        Ok(HttpClient { client, resolver })
     }
 
     pub async fn async_request(
@@ -80,7 +83,9 @@ impl HttpClient {
         headers: HashMap<Vec<u8>, Vec<Vec<u8>>>,
         body: Option<Vec<u8>>,
     ) -> Result<MatrixResponse, Error> {
-        let mut builder = Request::builder().method(&*method).uri(url);
+        let uri: Uri = url.try_into()?;
+
+        let mut builder = Request::builder().method(&*method).uri(uri.clone());
 
         for (key, values) in headers {
             for value in values {
@@ -88,6 +93,13 @@ impl HttpClient {
             }
         }
 
+        if uri.scheme_str() == Some("matrix") {
+            let endpoints = self.resolver.resolve_server_name_from_uri(&uri).await?;
+            if let Some(endpoint) = endpoints.first() {
+                builder = builder.header("Host", &endpoint.host_header);
+            }
+        }
+
         let request = if let Some(body) = body {
             builder.body(Body::from(body))?
         } else {
diff --git a/rust/src/http/resolver.rs b/rust/src/http/resolver.rs
index 77e9bf5c20..0a2641ebdf 100644
--- a/rust/src/http/resolver.rs
+++ b/rust/src/http/resolver.rs
@@ -20,7 +20,7 @@ use hyper::service::Service;
 use hyper::Client;
 use hyper_tls::HttpsConnector;
 use hyper_tls::MaybeHttpsStream;
-use log::info;
+use log::{debug, info};
 use native_tls::TlsConnector;
 use serde::Deserialize;
 use tokio::io::{AsyncRead, AsyncWrite, ReadBuf};
@@ -28,6 +28,7 @@ use tokio::net::TcpStream;
 use tokio_native_tls::TlsConnector as AsyncTlsConnector;
 use trust_dns_resolver::error::ResolveErrorKind;
 
+#[derive(Debug, Clone)]
 pub struct Endpoint {
     pub host: String,
     pub port: u16,
@@ -213,6 +214,7 @@ impl Service<Uri> for MatrixConnector {
         let resolver = self.resolver.clone();
 
         if dst.scheme_str() != Some("matrix") {
+            debug!("Got non-matrix scheme");
             return HttpsConnector::new()
                 .call(dst)
                 .map_err(|e| Error::msg(e))
@@ -227,6 +229,8 @@ impl Service<Uri> for MatrixConnector {
                 )
                 .await?;
 
+            debug!("Got endpoints: {:?}", endpoints);
+
             for endpoint in endpoints {
                 match try_connecting(&dst, &endpoint).await {
                     Ok(r) => return Ok(r),