We do this by shoving it into Rust. We believe our python http client is a bit slow. Also bumps minimum rust version to 1.81.0, released last September (over six months ago) To allow for async Rust, includes some adapters between Tokio in Rust and the Twisted reactor in Python.
73 lines
2.2 KiB
Rust
73 lines
2.2 KiB
Rust
/*
|
|
* This file is licensed under the Affero General Public License (AGPL) version 3.
|
|
*
|
|
* Copyright (C) 2024 New Vector, Ltd
|
|
*
|
|
* This program is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU Affero General Public License as
|
|
* published by the Free Software Foundation, either version 3 of the
|
|
* License, or (at your option) any later version.
|
|
*
|
|
* See the GNU Affero General Public License for more details:
|
|
* <https://www.gnu.org/licenses/agpl-3.0.html>.
|
|
*/
|
|
|
|
#![allow(clippy::new_ret_no_self)]
|
|
|
|
use std::collections::HashMap;
|
|
|
|
use http::{HeaderMap, StatusCode};
|
|
use pyo3::{exceptions::PyValueError, import_exception};
|
|
|
|
import_exception!(synapse.api.errors, SynapseError);
|
|
|
|
impl SynapseError {
|
|
pub fn new(
|
|
code: StatusCode,
|
|
message: String,
|
|
errcode: &'static str,
|
|
additional_fields: Option<HashMap<String, String>>,
|
|
headers: Option<HeaderMap>,
|
|
) -> pyo3::PyErr {
|
|
// Transform the HeaderMap into a HashMap<String, String>
|
|
let headers = if let Some(headers) = headers {
|
|
let mut map = HashMap::with_capacity(headers.len());
|
|
for (key, value) in headers.iter() {
|
|
let Ok(value) = value.to_str() else {
|
|
// This should never happen, but we don't want to panic in case it does
|
|
return PyValueError::new_err(
|
|
"Could not construct SynapseError: header value is not valid ASCII",
|
|
);
|
|
};
|
|
|
|
map.insert(key.as_str().to_owned(), value.to_owned());
|
|
}
|
|
Some(map)
|
|
} else {
|
|
None
|
|
};
|
|
|
|
SynapseError::new_err((code.as_u16(), message, errcode, additional_fields, headers))
|
|
}
|
|
}
|
|
|
|
import_exception!(synapse.api.errors, NotFoundError);
|
|
|
|
impl NotFoundError {
|
|
pub fn new() -> pyo3::PyErr {
|
|
NotFoundError::new_err(())
|
|
}
|
|
}
|
|
|
|
import_exception!(synapse.api.errors, HttpResponseException);
|
|
|
|
impl HttpResponseException {
|
|
pub fn new(status: StatusCode, bytes: Vec<u8>) -> pyo3::PyErr {
|
|
HttpResponseException::new_err((
|
|
status.as_u16(),
|
|
status.canonical_reason().unwrap_or_default(),
|
|
bytes,
|
|
))
|
|
}
|
|
}
|