Skip to content

Commit 913f09d

Browse files
committed
fix: send http requests in origin not absolute form
Absolute form is meant for proxies and for example nginx rejects it with 400 if the host contains an underscore, breaking autoconfig discovery.
1 parent 5aa4d80 commit 913f09d

3 files changed

Lines changed: 28 additions & 8 deletions

File tree

deltachat-rpc-client/src/deltachat_rpc_client/pytestplugin.py

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -338,10 +338,7 @@ def remote_bob_loop(channel):
338338
# ACFactory would configure from a "dcaccount" QR,
339339
# which old cores cannot use on underscore domains
340340
bob = dc.add_account()
341-
bob.set_config_from_qr(dclogin_qr)
342-
if not bob.is_configured():
343-
# cores <=2.22 only store login values from a "dclogin" QR
344-
bob.configure()
341+
bob.add_transport_from_qr(dclogin_qr)
345342
bob.bring_online()
346343

347344
alice_vcard = channel.receive()

deltachat-rpc-client/tests/test_cross_core.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ def test_qr_setup_contact(acfactory, alice_and_remote_bob, version) -> None:
4545

4646
def test_send_and_receive_message(alice_and_remote_bob) -> None:
4747
"""Test other-core Bob profile can send a message to Alice on current core."""
48-
alice, alice_contact_bob, remote_eval = alice_and_remote_bob("2.20.0")
48+
alice, alice_contact_bob, remote_eval = alice_and_remote_bob("2.23.0")
4949

5050
remote_eval("bob_contact_alice.create_chat().send_text('hello')")
5151

@@ -55,7 +55,7 @@ def test_send_and_receive_message(alice_and_remote_bob) -> None:
5555

5656
def test_second_device(acfactory, alice_and_remote_bob) -> None:
5757
"""Test setting up current version as a second device for old version."""
58-
_alice, alice_contact_bob, remote_eval = alice_and_remote_bob("2.20.0")
58+
_alice, alice_contact_bob, remote_eval = alice_and_remote_bob("2.23.0")
5959

6060
remote_eval("locals().setdefault('future', bob._rpc.provide_backup.future(bob.id))")
6161
qr = remote_eval("bob._rpc.get_backup_qr(bob.id)")

src/net/http.rs

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,15 @@ pub(crate) async fn http_cache_cleanup(context: &Context) -> Result<()> {
258258
Ok(())
259259
}
260260

261+
/// Returns the request target in origin form, i.e. the path and query of `url`.
262+
///
263+
/// The absolute form is only for proxy requests and
264+
/// nginx rejects it if the host starts contains an underscore.
265+
fn origin_form(url: &hyper::Uri) -> &str {
266+
url.path_and_query()
267+
.map_or("/", |path_and_query| path_and_query.as_str())
268+
}
269+
261270
/// Fetches URL and updates the cache.
262271
///
263272
/// URL is fetched regardless of whether there is an existing result in the cache.
@@ -276,7 +285,7 @@ async fn fetch_url(context: &Context, original_url: &str, strict_tls: bool) -> R
276285
.context("URL has no authority")?
277286
.clone();
278287

279-
let req = hyper::Request::builder().uri(parsed_url);
288+
let req = hyper::Request::builder().uri(origin_form(&parsed_url));
280289

281290
// OSM usage policy requires
282291
// that User-Agent is set for HTTP GET requests
@@ -409,7 +418,7 @@ pub(crate) async fn post_empty(context: &Context, url: &str) -> Result<(String,
409418
.authority()
410419
.context("URL has no authority")?
411420
.clone();
412-
let req = hyper::Request::post(parsed_url)
421+
let req = hyper::Request::post(origin_form(&parsed_url))
413422
.header(hyper::header::HOST, authority.as_str())
414423
.body(http_body_util::Empty::<Bytes>::new())?;
415424

@@ -432,6 +441,20 @@ mod tests {
432441
use crate::test_utils::TestContext;
433442
use crate::tools::SystemTime;
434443

444+
#[test]
445+
fn test_origin_form() {
446+
let url = "https://_cm0.localchat/autoconfig?emailaddress=x%40_cm0.localchat"
447+
.parse()
448+
.unwrap();
449+
assert_eq!(
450+
origin_form(&url),
451+
"/autoconfig?emailaddress=x%40_cm0.localchat"
452+
);
453+
454+
let url = "https://example.org".parse().unwrap();
455+
assert_eq!(origin_form(&url), "/");
456+
}
457+
435458
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
436459
async fn test_http_cache() -> Result<()> {
437460
let t = &TestContext::new().await;

0 commit comments

Comments
 (0)