Merge remote-tracking branch 'upstream/main' into conduwuit-changes
This commit is contained in:
commit
9e29e07ae1
28
Cargo.toml
28
Cargo.toml
@ -16,20 +16,20 @@ criterion = "0.5.0"
|
||||
http = "1.1.0"
|
||||
js_int = "0.2.2"
|
||||
maplit = "1.0.2"
|
||||
ruma-appservice-api = { version = "0.9.0", path = "crates/ruma-appservice-api" }
|
||||
ruma-common = { version = "0.12.1", path = "crates/ruma-common" }
|
||||
ruma-client = { version = "0.12.0", path = "crates/ruma-client" }
|
||||
ruma-client-api = { version = "0.17.4", path = "crates/ruma-client-api" }
|
||||
ruma-events = { version = "0.27.11", path = "crates/ruma-events" }
|
||||
ruma-federation-api = { version = "0.8.0", path = "crates/ruma-federation-api" }
|
||||
ruma-html = { version = "0.1.0", path = "crates/ruma-html" }
|
||||
ruma-identifiers-validation = { version = "0.9.3", path = "crates/ruma-identifiers-validation" }
|
||||
ruma-identity-service-api = { version = "0.8.0", path = "crates/ruma-identity-service-api" }
|
||||
ruma-macros = { version = "=0.12.0", path = "crates/ruma-macros" }
|
||||
ruma-push-gateway-api = { version = "0.8.0", path = "crates/ruma-push-gateway-api" }
|
||||
ruma-signatures = { version = "0.14.0", path = "crates/ruma-signatures" }
|
||||
ruma-server-util = { version = "0.2.0", path = "crates/ruma-server-util" }
|
||||
ruma-state-res = { version = "0.10.0", path = "crates/ruma-state-res" }
|
||||
ruma-appservice-api = { version = "0.10.0", path = "crates/ruma-appservice-api" }
|
||||
ruma-common = { version = "0.13.0", path = "crates/ruma-common" }
|
||||
ruma-client = { version = "0.13.0", path = "crates/ruma-client" }
|
||||
ruma-client-api = { version = "0.18.0", path = "crates/ruma-client-api" }
|
||||
ruma-events = { version = "0.28.0", path = "crates/ruma-events" }
|
||||
ruma-federation-api = { version = "0.9.0", path = "crates/ruma-federation-api" }
|
||||
ruma-html = { version = "0.2.0", path = "crates/ruma-html" }
|
||||
ruma-identifiers-validation = { version = "0.9.5", path = "crates/ruma-identifiers-validation" }
|
||||
ruma-identity-service-api = { version = "0.9.0", path = "crates/ruma-identity-service-api" }
|
||||
ruma-macros = { version = "=0.13.0", path = "crates/ruma-macros" }
|
||||
ruma-push-gateway-api = { version = "0.9.0", path = "crates/ruma-push-gateway-api" }
|
||||
ruma-signatures = { version = "0.15.0", path = "crates/ruma-signatures" }
|
||||
ruma-server-util = { version = "0.3.0", path = "crates/ruma-server-util" }
|
||||
ruma-state-res = { version = "0.11.0", path = "crates/ruma-state-res" }
|
||||
serde = { version = "1.0.164", features = ["derive"] }
|
||||
serde_html_form = "0.2.0"
|
||||
serde_json = "1.0.87"
|
||||
|
@ -24,7 +24,7 @@ dependencies:
|
||||
|
||||
```toml
|
||||
# crates.io release
|
||||
ruma = { version = "0.9.0", features = ["..."] }
|
||||
ruma = { version = "0.10.0", features = ["..."] }
|
||||
# git dependency
|
||||
ruma = { git = "https://github.com/ruma/ruma", branch = "main", features = ["..."] }
|
||||
```
|
||||
@ -38,7 +38,7 @@ them as a user. Check out the documentation [on docs.rs][docs] (or on
|
||||
|
||||
## Status
|
||||
|
||||
Ruma 0.9.0 supports all events and REST endpoints of Matrix 1.8.
|
||||
Ruma 0.10.0 supports all events and REST endpoints of Matrix 1.10.
|
||||
|
||||
Various changes from in-progress or finished MSCs are also implemented, gated
|
||||
behind the `unstable-mscXXXX` (where `XXXX` is the MSC number) Cargo features.
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 58 KiB After Width: | Height: | Size: 63 KiB |
@ -1,9 +1,12 @@
|
||||
# [unreleased]
|
||||
|
||||
# 0.10.0
|
||||
|
||||
Breaking changes:
|
||||
|
||||
* The `url` field of `Registration` is now an `Option<String>`. This should have
|
||||
always been the case.
|
||||
- The http crate had a major version bump to version 1.1
|
||||
|
||||
# 0.9.0
|
||||
|
||||
|
@ -7,7 +7,7 @@ license = "MIT"
|
||||
name = "ruma-appservice-api"
|
||||
readme = "README.md"
|
||||
repository = "https://github.com/ruma/ruma"
|
||||
version = "0.9.0"
|
||||
version = "0.10.0"
|
||||
edition = "2021"
|
||||
rust-version = { workspace = true }
|
||||
|
||||
|
@ -1,11 +1,15 @@
|
||||
# [unreleased]
|
||||
|
||||
# 0.18.0
|
||||
|
||||
Bug fixes:
|
||||
|
||||
- Don't require the `failures` field in the
|
||||
`ruma_client_api::keys::upload_signatures::Response` type.
|
||||
- `sync::sync_events::v3::Timeline::is_empty` now returns `false` when the
|
||||
`limited` or `prev_batch` fields are set.
|
||||
- `login_fallback::Response` now returns the proper content type
|
||||
- `sso_login[_with_provider]` responses now use the proper HTTP status code.
|
||||
|
||||
Breaking changes:
|
||||
|
||||
@ -20,7 +24,11 @@ Breaking changes:
|
||||
constructed with `ErrorKind::forbidden()`.
|
||||
- The `retry_after_ms` field of `ErrorKind::LimitExceeded` was renamed to
|
||||
`retry_after` and is now an `Option<RetryAfter>`, to add support for the
|
||||
Retry-After header, according to MSC4041 / Matrix 1.10
|
||||
Retry-After header, according to MSC4041 / Matrix 1.10
|
||||
- Make `get_uiaa_fallback::v3::Response` an enum for a redirect or an HTML page.
|
||||
It will now return the proper status code and headers depending on the variant
|
||||
used.
|
||||
- The http crate had a major version bump to version 1.1
|
||||
|
||||
Improvements:
|
||||
|
||||
|
@ -7,7 +7,7 @@ license = "MIT"
|
||||
name = "ruma-client-api"
|
||||
readme = "README.md"
|
||||
repository = "https://github.com/ruma/ruma"
|
||||
version = "0.17.4"
|
||||
version = "0.18.0"
|
||||
edition = "2021"
|
||||
rust-version = { workspace = true }
|
||||
|
||||
|
@ -6,17 +6,22 @@ use as_variant::as_variant;
|
||||
use bytes::{BufMut, Bytes};
|
||||
use ruma_common::{
|
||||
api::{
|
||||
error::{FromHttpResponseError, IntoHttpError, MatrixErrorBody},
|
||||
error::{
|
||||
FromHttpResponseError, HeaderDeserializationError, HeaderSerializationError,
|
||||
IntoHttpError, MatrixErrorBody,
|
||||
},
|
||||
EndpointError, OutgoingResponse,
|
||||
},
|
||||
RoomVersionId,
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_json::{from_slice as from_json_slice, Value as JsonValue};
|
||||
use thiserror::Error;
|
||||
use web_time::{Duration, SystemTime, UNIX_EPOCH};
|
||||
use web_time::{Duration, SystemTime};
|
||||
|
||||
use crate::PrivOwnedStr;
|
||||
use crate::{
|
||||
http_headers::{http_date_to_system_time, system_time_to_http_date},
|
||||
PrivOwnedStr,
|
||||
};
|
||||
|
||||
/// Deserialize and Serialize implementations for ErrorKind.
|
||||
/// Separate module because it's a lot of code.
|
||||
@ -372,9 +377,8 @@ impl EndpointError for Error {
|
||||
ErrorKind::LimitExceeded { retry_after } => {
|
||||
// The Retry-After header takes precedence over the retry_after_ms field in
|
||||
// the body.
|
||||
if let Some(retry_after_header) = headers
|
||||
.get(http::header::RETRY_AFTER)
|
||||
.and_then(RetryAfter::from_header_value)
|
||||
if let Some(Ok(retry_after_header)) =
|
||||
headers.get(http::header::RETRY_AFTER).map(RetryAfter::try_from)
|
||||
{
|
||||
*retry_after = Some(retry_after_header);
|
||||
}
|
||||
@ -567,59 +571,31 @@ pub enum RetryAfter {
|
||||
DateTime(SystemTime),
|
||||
}
|
||||
|
||||
impl RetryAfter {
|
||||
fn from_header_value(value: &http::HeaderValue) -> Option<Self> {
|
||||
let bytes = value.as_bytes();
|
||||
impl TryFrom<&http::HeaderValue> for RetryAfter {
|
||||
type Error = HeaderDeserializationError;
|
||||
|
||||
if bytes.iter().all(|b| b.is_ascii_digit()) {
|
||||
fn try_from(value: &http::HeaderValue) -> Result<Self, Self::Error> {
|
||||
if value.as_bytes().iter().all(|b| b.is_ascii_digit()) {
|
||||
// It should be a duration.
|
||||
Some(Self::Delay(Duration::from_secs(u64::from_str(value.to_str().ok()?).ok()?)))
|
||||
Ok(Self::Delay(Duration::from_secs(u64::from_str(value.to_str()?)?)))
|
||||
} else {
|
||||
// It should be a date.
|
||||
let ts = date_header::parse(bytes).ok()?;
|
||||
Some(Self::DateTime(UNIX_EPOCH.checked_add(Duration::from_secs(ts))?))
|
||||
Ok(Self::DateTime(http_date_to_system_time(value)?))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<&RetryAfter> for http::HeaderValue {
|
||||
type Error = RetryAfterInvalidDateTime;
|
||||
type Error = HeaderSerializationError;
|
||||
|
||||
fn try_from(value: &RetryAfter) -> Result<Self, Self::Error> {
|
||||
match value {
|
||||
RetryAfter::Delay(duration) => Ok(duration.as_secs().into()),
|
||||
RetryAfter::DateTime(time) => {
|
||||
let mut buffer = [0; 29];
|
||||
let duration =
|
||||
time.duration_since(UNIX_EPOCH).map_err(|_| RetryAfterInvalidDateTime)?;
|
||||
date_header::format(duration.as_secs(), &mut buffer)
|
||||
.map_err(|_| RetryAfterInvalidDateTime)?;
|
||||
let value = http::HeaderValue::from_bytes(&buffer)
|
||||
.expect("date_header should produce a valid header value");
|
||||
|
||||
Ok(value)
|
||||
}
|
||||
RetryAfter::DateTime(time) => system_time_to_http_date(time),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// An error when converting a [`RetryAfter`] to a [`http::HeaderValue`].
|
||||
///
|
||||
/// Happens when the `DateTime` is too far in the past (before the Unix epoch) or the
|
||||
/// future (after the year 9999).
|
||||
#[derive(Debug, Error)]
|
||||
#[allow(clippy::exhaustive_structs)]
|
||||
#[error(
|
||||
"Retry-After header serialization failed: the datetime is too far in the past or the future"
|
||||
)]
|
||||
pub struct RetryAfterInvalidDateTime;
|
||||
|
||||
impl From<RetryAfterInvalidDateTime> for IntoHttpError {
|
||||
fn from(_value: RetryAfterInvalidDateTime) -> Self {
|
||||
IntoHttpError::RetryAfterInvalidDatetime
|
||||
}
|
||||
}
|
||||
|
||||
/// Extension trait for `FromHttpResponseError<ruma_client_api::Error>`.
|
||||
pub trait FromHttpResponseErrorExt {
|
||||
/// If `self` is a server error in the `errcode` + `error` format expected
|
||||
|
@ -1,10 +1,40 @@
|
||||
//! Custom HTTP headers not defined in the `http` crate.
|
||||
//! Helpers for HTTP headers with the `http` crate.
|
||||
#![allow(clippy::declare_interior_mutable_const)]
|
||||
|
||||
use http::header::HeaderName;
|
||||
use http::{header::HeaderName, HeaderValue};
|
||||
use ruma_common::api::error::{HeaderDeserializationError, HeaderSerializationError};
|
||||
use web_time::{Duration, SystemTime, UNIX_EPOCH};
|
||||
|
||||
/// The [`Cross-Origin-Resource-Policy`] HTTP response header.
|
||||
///
|
||||
/// [`Cross-Origin-Resource-Policy`]: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cross-Origin-Resource-Policy
|
||||
pub const CROSS_ORIGIN_RESOURCE_POLICY: HeaderName =
|
||||
HeaderName::from_static("cross-origin-resource-policy");
|
||||
|
||||
/// Convert as `SystemTime` to a HTTP date header value.
|
||||
pub fn system_time_to_http_date(
|
||||
time: &SystemTime,
|
||||
) -> Result<HeaderValue, HeaderSerializationError> {
|
||||
let mut buffer = [0; 29];
|
||||
|
||||
let duration =
|
||||
time.duration_since(UNIX_EPOCH).map_err(|_| HeaderSerializationError::InvalidHttpDate)?;
|
||||
date_header::format(duration.as_secs(), &mut buffer)
|
||||
.map_err(|_| HeaderSerializationError::InvalidHttpDate)?;
|
||||
|
||||
Ok(http::HeaderValue::from_bytes(&buffer)
|
||||
.expect("date_header should produce a valid header value"))
|
||||
}
|
||||
|
||||
/// Convert a header value representing a HTTP date to a `SystemTime`.
|
||||
pub fn http_date_to_system_time(
|
||||
value: &HeaderValue,
|
||||
) -> Result<SystemTime, HeaderDeserializationError> {
|
||||
let bytes = value.as_bytes();
|
||||
|
||||
let ts = date_header::parse(bytes).map_err(|_| HeaderDeserializationError::InvalidHttpDate)?;
|
||||
|
||||
UNIX_EPOCH
|
||||
.checked_add(Duration::from_secs(ts))
|
||||
.ok_or(HeaderDeserializationError::InvalidHttpDate)
|
||||
}
|
||||
|
@ -5,7 +5,7 @@
|
||||
//! [spec]: https://spec.matrix.org/latest/client-server-api/#login-fallback
|
||||
|
||||
use ruma_common::{
|
||||
api::{request, response, Metadata},
|
||||
api::{request, Metadata},
|
||||
metadata, OwnedDeviceId,
|
||||
};
|
||||
|
||||
@ -35,14 +35,6 @@ pub struct Request {
|
||||
pub initial_device_display_name: Option<String>,
|
||||
}
|
||||
|
||||
/// Response type for the `login_fallback` endpoint.
|
||||
#[response(error = crate::Error)]
|
||||
pub struct Response {
|
||||
/// HTML to return to client.
|
||||
#[ruma_api(raw_body)]
|
||||
pub body: Vec<u8>,
|
||||
}
|
||||
|
||||
impl Request {
|
||||
/// Creates a new `Request` with the given auth type and session ID.
|
||||
pub fn new(
|
||||
@ -53,9 +45,49 @@ impl Request {
|
||||
}
|
||||
}
|
||||
|
||||
/// Response type for the `login_fallback` endpoint.
|
||||
#[derive(Debug, Clone)]
|
||||
#[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)]
|
||||
pub struct Response {
|
||||
/// HTML to return to client.
|
||||
pub body: Vec<u8>,
|
||||
}
|
||||
|
||||
impl Response {
|
||||
/// Creates a new `Response` with the given HTML body.
|
||||
pub fn new(body: Vec<u8>) -> Self {
|
||||
Self { body }
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "server")]
|
||||
impl ruma_common::api::OutgoingResponse for Response {
|
||||
fn try_into_http_response<T: Default + bytes::BufMut>(
|
||||
self,
|
||||
) -> Result<http::Response<T>, ruma_common::api::error::IntoHttpError> {
|
||||
Ok(http::Response::builder()
|
||||
.status(http::StatusCode::OK)
|
||||
.header(http::header::CONTENT_TYPE, "text/html")
|
||||
.body(ruma_common::serde::slice_to_buf(&self.body))?)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "client")]
|
||||
impl ruma_common::api::IncomingResponse for Response {
|
||||
type EndpointError = crate::Error;
|
||||
|
||||
fn try_from_http_response<T: AsRef<[u8]>>(
|
||||
response: http::Response<T>,
|
||||
) -> Result<Self, ruma_common::api::error::FromHttpResponseError<Self::EndpointError>> {
|
||||
use ruma_common::api::{error::FromHttpResponseError, EndpointError};
|
||||
|
||||
if response.status().as_u16() >= 400 {
|
||||
return Err(FromHttpResponseError::Server(Self::EndpointError::from_http_response(
|
||||
response,
|
||||
)));
|
||||
}
|
||||
|
||||
let body = response.into_body().as_ref().to_owned();
|
||||
Ok(Self { body })
|
||||
}
|
||||
}
|
||||
|
@ -32,7 +32,7 @@ pub mod v3 {
|
||||
}
|
||||
|
||||
/// Response type for the `sso_login` endpoint.
|
||||
#[response(error = crate::Error)]
|
||||
#[response(error = crate::Error, status = FOUND)]
|
||||
pub struct Response {
|
||||
/// Redirect URL to the SSO identity provider.
|
||||
#[ruma_api(header = LOCATION)]
|
||||
|
@ -38,7 +38,7 @@ pub mod v3 {
|
||||
}
|
||||
|
||||
/// Response type for the `sso_login_with_provider` endpoint.
|
||||
#[response(error = crate::Error)]
|
||||
#[response(error = crate::Error, status = FOUND)]
|
||||
pub struct Response {
|
||||
/// Redirect URL to the SSO identity provider.
|
||||
#[ruma_api(header = LOCATION)]
|
||||
|
@ -7,9 +7,8 @@ pub mod v3 {
|
||||
//!
|
||||
//! [spec]: https://spec.matrix.org/latest/client-server-api/#fallback
|
||||
|
||||
use http::header::LOCATION;
|
||||
use ruma_common::{
|
||||
api::{request, response, Metadata},
|
||||
api::{request, Metadata},
|
||||
metadata,
|
||||
};
|
||||
|
||||
@ -35,19 +34,6 @@ pub mod v3 {
|
||||
pub session: String,
|
||||
}
|
||||
|
||||
/// Response type for the `authorize_fallback` endpoint.
|
||||
#[response(error = crate::Error)]
|
||||
#[derive(Default)]
|
||||
pub struct Response {
|
||||
/// Optional URI to redirect to.
|
||||
#[ruma_api(header = LOCATION)]
|
||||
pub redirect_url: Option<String>,
|
||||
|
||||
/// HTML to return to client.
|
||||
#[ruma_api(raw_body)]
|
||||
pub body: Vec<u8>,
|
||||
}
|
||||
|
||||
impl Request {
|
||||
/// Creates a new `Request` with the given auth type and session ID.
|
||||
pub fn new(auth_type: String, session: String) -> Self {
|
||||
@ -55,15 +41,172 @@ pub mod v3 {
|
||||
}
|
||||
}
|
||||
|
||||
/// Response type for the `authorize_fallback` endpoint.
|
||||
#[derive(Debug, Clone)]
|
||||
#[allow(clippy::exhaustive_enums)]
|
||||
pub enum Response {
|
||||
/// The response is a redirect.
|
||||
Redirect(Redirect),
|
||||
|
||||
/// The response is an HTML page.
|
||||
Html(HtmlPage),
|
||||
}
|
||||
|
||||
/// The data of a redirect.
|
||||
#[derive(Debug, Clone)]
|
||||
#[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)]
|
||||
pub struct Redirect {
|
||||
/// The URL to redirect the user to.
|
||||
pub url: String,
|
||||
}
|
||||
|
||||
/// The data of a HTML page.
|
||||
#[derive(Debug, Clone)]
|
||||
#[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)]
|
||||
pub struct HtmlPage {
|
||||
/// The body of the HTML page.
|
||||
pub body: Vec<u8>,
|
||||
}
|
||||
|
||||
impl Response {
|
||||
/// Creates a new `Response` with the given HTML body.
|
||||
pub fn new(body: Vec<u8>) -> Self {
|
||||
Self { redirect_url: None, body }
|
||||
/// Creates a new HTML `Response` with the given HTML body.
|
||||
pub fn html(body: Vec<u8>) -> Self {
|
||||
Self::Html(HtmlPage { body })
|
||||
}
|
||||
|
||||
/// Creates a new `Response` with the given redirect URL and an empty body.
|
||||
/// Creates a new HTML `Response` with the given redirect URL.
|
||||
pub fn redirect(url: String) -> Self {
|
||||
Self { redirect_url: Some(url), body: Vec::new() }
|
||||
Self::Redirect(Redirect { url })
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "server")]
|
||||
impl ruma_common::api::OutgoingResponse for Response {
|
||||
fn try_into_http_response<T: Default + bytes::BufMut>(
|
||||
self,
|
||||
) -> Result<http::Response<T>, ruma_common::api::error::IntoHttpError> {
|
||||
match self {
|
||||
Response::Redirect(Redirect { url }) => Ok(http::Response::builder()
|
||||
.status(http::StatusCode::FOUND)
|
||||
.header(http::header::LOCATION, url)
|
||||
.body(T::default())?),
|
||||
Response::Html(HtmlPage { body }) => Ok(http::Response::builder()
|
||||
.status(http::StatusCode::OK)
|
||||
.header(http::header::CONTENT_TYPE, "text/html; charset=utf-8")
|
||||
.body(ruma_common::serde::slice_to_buf(&body))?),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "client")]
|
||||
impl ruma_common::api::IncomingResponse for Response {
|
||||
type EndpointError = crate::Error;
|
||||
|
||||
fn try_from_http_response<T: AsRef<[u8]>>(
|
||||
response: http::Response<T>,
|
||||
) -> Result<Self, ruma_common::api::error::FromHttpResponseError<Self::EndpointError>>
|
||||
{
|
||||
use ruma_common::api::{
|
||||
error::{DeserializationError, FromHttpResponseError, HeaderDeserializationError},
|
||||
EndpointError,
|
||||
};
|
||||
|
||||
if response.status().as_u16() >= 400 {
|
||||
return Err(FromHttpResponseError::Server(
|
||||
Self::EndpointError::from_http_response(response),
|
||||
));
|
||||
}
|
||||
|
||||
if response.status() == http::StatusCode::FOUND {
|
||||
let Some(location) = response.headers().get(http::header::LOCATION) else {
|
||||
return Err(DeserializationError::Header(
|
||||
HeaderDeserializationError::MissingHeader(
|
||||
http::header::LOCATION.to_string(),
|
||||
),
|
||||
)
|
||||
.into());
|
||||
};
|
||||
|
||||
let url = location.to_str()?;
|
||||
return Ok(Self::Redirect(Redirect { url: url.to_owned() }));
|
||||
}
|
||||
|
||||
let body = response.into_body().as_ref().to_owned();
|
||||
Ok(Self::Html(HtmlPage { body }))
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(all(test, any(feature = "client", feature = "server")))]
|
||||
mod tests {
|
||||
use assert_matches2::assert_matches;
|
||||
use http::header::{CONTENT_TYPE, LOCATION};
|
||||
#[cfg(feature = "client")]
|
||||
use ruma_common::api::IncomingResponse;
|
||||
#[cfg(feature = "server")]
|
||||
use ruma_common::api::OutgoingResponse;
|
||||
|
||||
use super::Response;
|
||||
|
||||
#[cfg(feature = "client")]
|
||||
#[test]
|
||||
fn incoming_redirect() {
|
||||
use super::Redirect;
|
||||
|
||||
let http_response = http::Response::builder()
|
||||
.status(http::StatusCode::FOUND)
|
||||
.header(LOCATION, "http://localhost/redirect")
|
||||
.body(Vec::<u8>::new())
|
||||
.unwrap();
|
||||
|
||||
let response = Response::try_from_http_response(http_response).unwrap();
|
||||
assert_matches!(response, Response::Redirect(Redirect { url }));
|
||||
assert_eq!(url, "http://localhost/redirect");
|
||||
}
|
||||
|
||||
#[cfg(feature = "client")]
|
||||
#[test]
|
||||
fn incoming_html() {
|
||||
use super::HtmlPage;
|
||||
|
||||
let http_response = http::Response::builder()
|
||||
.status(http::StatusCode::OK)
|
||||
.header(CONTENT_TYPE, "text/html; charset=utf-8")
|
||||
.body(b"<h1>My Page</h1>")
|
||||
.unwrap();
|
||||
|
||||
let response = Response::try_from_http_response(http_response).unwrap();
|
||||
assert_matches!(response, Response::Html(HtmlPage { body }));
|
||||
assert_eq!(body, b"<h1>My Page</h1>");
|
||||
}
|
||||
|
||||
#[cfg(feature = "server")]
|
||||
#[test]
|
||||
fn outgoing_redirect() {
|
||||
let response = Response::redirect("http://localhost/redirect".to_owned());
|
||||
|
||||
let http_response = response.try_into_http_response::<Vec<u8>>().unwrap();
|
||||
|
||||
assert_eq!(http_response.status(), http::StatusCode::FOUND);
|
||||
assert_eq!(
|
||||
http_response.headers().get(LOCATION).unwrap().to_str().unwrap(),
|
||||
"http://localhost/redirect"
|
||||
);
|
||||
assert!(http_response.into_body().is_empty());
|
||||
}
|
||||
|
||||
#[cfg(feature = "server")]
|
||||
#[test]
|
||||
fn outgoing_html() {
|
||||
let response = Response::html(b"<h1>My Page</h1>".to_vec());
|
||||
|
||||
let http_response = response.try_into_http_response::<Vec<u8>>().unwrap();
|
||||
|
||||
assert_eq!(http_response.status(), http::StatusCode::OK);
|
||||
assert_eq!(
|
||||
http_response.headers().get(CONTENT_TYPE).unwrap().to_str().unwrap(),
|
||||
"text/html; charset=utf-8"
|
||||
);
|
||||
assert_eq!(http_response.into_body(), b"<h1>My Page</h1>");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,7 @@
|
||||
# [unreleased]
|
||||
|
||||
# 0.13.0
|
||||
|
||||
Breaking changes:
|
||||
|
||||
- Remove `isahc` feature
|
||||
|
@ -7,7 +7,7 @@ license = "MIT"
|
||||
name = "ruma-client"
|
||||
readme = "README.md"
|
||||
repository = "https://github.com/ruma/ruma"
|
||||
version = "0.12.0"
|
||||
version = "0.13.0"
|
||||
edition = "2021"
|
||||
rust-version = { workspace = true }
|
||||
|
||||
|
@ -1,10 +1,13 @@
|
||||
# [unreleased]
|
||||
|
||||
# 0.13.0
|
||||
|
||||
Bug fixes:
|
||||
|
||||
- Allow to deserialize `Ruleset` with missing fields.
|
||||
|
||||
Breaking changes:
|
||||
|
||||
- The power levels fields in `PushConditionRoomCtx` are grouped in an optional `power_levels` field.
|
||||
If the field is missing, push rules that depend on it will never match. However, this allows to
|
||||
match the `.m.rule.invite_for_me` push rule because usually the `invite_state` doesn't include
|
||||
@ -14,6 +17,7 @@ Breaking changes:
|
||||
- `deserialize_as_f64_or_string` has been extended to also support parsing integers, and renamed to
|
||||
`deserialize_as_number_or_string` to reflect that.
|
||||
- The http crate had a major version bump to version 1.1
|
||||
- `IntoHttpError::Header` now contains a `HeaderSerializationError`
|
||||
|
||||
Improvements:
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "ruma-common"
|
||||
version = "0.12.1"
|
||||
version = "0.13.0"
|
||||
description = "Common types for other ruma crates."
|
||||
homepage = "https://ruma.dev/"
|
||||
keywords = ["matrix", "chat", "messaging", "ruma"]
|
||||
|
@ -2,7 +2,7 @@
|
||||
//! converting between http requests / responses and ruma's representation of
|
||||
//! matrix API requests / responses.
|
||||
|
||||
use std::{error::Error as StdError, fmt, sync::Arc};
|
||||
use std::{error::Error as StdError, fmt, num::ParseIntError, sync::Arc};
|
||||
|
||||
use bytes::{BufMut, Bytes};
|
||||
use serde_json::{from_slice as from_json_slice, Value as JsonValue};
|
||||
@ -127,20 +127,19 @@ pub enum IntoHttpError {
|
||||
|
||||
/// Header serialization failed.
|
||||
#[error("header serialization failed: {0}")]
|
||||
Header(#[from] http::header::InvalidHeaderValue),
|
||||
|
||||
/// Retry-After header serialization failed because the datetime provided is after the year
|
||||
/// 9999.
|
||||
#[error(
|
||||
"Retry-After header serialization failed: the year of the datetime is bigger than 9999"
|
||||
)]
|
||||
RetryAfterInvalidDatetime,
|
||||
Header(#[from] HeaderSerializationError),
|
||||
|
||||
/// HTTP request construction failed.
|
||||
#[error("HTTP request construction failed: {0}")]
|
||||
Http(#[from] http::Error),
|
||||
}
|
||||
|
||||
impl From<http::header::InvalidHeaderValue> for IntoHttpError {
|
||||
fn from(value: http::header::InvalidHeaderValue) -> Self {
|
||||
Self::Header(value.into())
|
||||
}
|
||||
}
|
||||
|
||||
/// An error when converting a http request to one of ruma's endpoint-specific request types.
|
||||
#[derive(Debug, Error)]
|
||||
#[non_exhaustive]
|
||||
@ -258,13 +257,21 @@ impl From<http::header::ToStrError> for DeserializationError {
|
||||
}
|
||||
}
|
||||
|
||||
/// An error with the http headers.
|
||||
/// An error when deserializing the HTTP headers.
|
||||
#[derive(Debug, Error)]
|
||||
#[non_exhaustive]
|
||||
pub enum HeaderDeserializationError {
|
||||
/// Failed to convert `http::header::HeaderValue` to `str`.
|
||||
#[error("{0}")]
|
||||
ToStrError(http::header::ToStrError),
|
||||
ToStrError(#[from] http::header::ToStrError),
|
||||
|
||||
/// Failed to convert `http::header::HeaderValue` to an integer.
|
||||
#[error("{0}")]
|
||||
ParseIntError(#[from] ParseIntError),
|
||||
|
||||
/// Failed to parse a HTTP date from a `http::header::Value`.
|
||||
#[error("failed to parse HTTP date")]
|
||||
InvalidHttpDate,
|
||||
|
||||
/// The given required header is missing.
|
||||
#[error("missing header `{0}`")]
|
||||
@ -303,3 +310,19 @@ impl fmt::Display for IncorrectArgumentCount {
|
||||
}
|
||||
|
||||
impl StdError for IncorrectArgumentCount {}
|
||||
|
||||
/// An error when serializing the HTTP headers.
|
||||
#[derive(Debug, Error)]
|
||||
#[non_exhaustive]
|
||||
pub enum HeaderSerializationError {
|
||||
/// Failed to convert a header value to `http::header::HeaderValue`.
|
||||
#[error(transparent)]
|
||||
ToHeaderValue(#[from] http::header::InvalidHeaderValue),
|
||||
|
||||
/// The `SystemTime` could not be converted to a HTTP date.
|
||||
///
|
||||
/// This only happens if the `SystemTime` provided is too far in the past (before the Unix
|
||||
/// epoch) or the future (after the year 9999).
|
||||
#[error("invalid HTTP date")]
|
||||
InvalidHttpDate,
|
||||
}
|
||||
|
@ -1,5 +1,7 @@
|
||||
# [unreleased]
|
||||
|
||||
# 0.28.0
|
||||
|
||||
Bug fixes:
|
||||
|
||||
- The `MembershipState::Invite` to `MembershipState::Knock` membership change
|
||||
|
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "ruma-events"
|
||||
version = "0.27.11"
|
||||
version = "0.28.0"
|
||||
description = "Serializable types for the events in the Matrix specification."
|
||||
homepage = "https://ruma.dev/"
|
||||
keywords = ["matrix", "chat", "messaging", "ruma"]
|
||||
|
@ -1,16 +1,19 @@
|
||||
# [unreleased]
|
||||
|
||||
# 0.9.0
|
||||
|
||||
Breaking changes:
|
||||
|
||||
* Use `RawValue` to represent body of `/v1/send_join` request, rather than incorrectly using
|
||||
- Use `RawValue` to represent body of `/v1/send_join` request, rather than incorrectly using
|
||||
query parameters
|
||||
- The http crate had a major version bump to version 1.1
|
||||
|
||||
Improvements:
|
||||
|
||||
* Implement `From<SpaceHierarchyParentSummary>` for `SpaceHierarchyChildSummary`
|
||||
* Add unstable support for optional `via` field on the `create_invite` endpoint request from
|
||||
- Implement `From<SpaceHierarchyParentSummary>` for `SpaceHierarchyChildSummary`
|
||||
- Add unstable support for optional `via` field on the `create_invite` endpoint request from
|
||||
MSC4125 behind the `unstable-msc4125` feature.
|
||||
* Add unstable support for the `report_content` endpoint from MSC3843 behind the
|
||||
- Add unstable support for the `report_content` endpoint from MSC3843 behind the
|
||||
`unstable-msc3843` feature.
|
||||
|
||||
# 0.8.0
|
||||
|
@ -7,7 +7,7 @@ license = "MIT"
|
||||
name = "ruma-federation-api"
|
||||
readme = "README.md"
|
||||
repository = "https://github.com/ruma/ruma"
|
||||
version = "0.8.0"
|
||||
version = "0.9.0"
|
||||
edition = "2021"
|
||||
rust-version = { workspace = true }
|
||||
|
||||
|
@ -1,5 +1,7 @@
|
||||
# [unreleased]
|
||||
|
||||
# 0.2.0
|
||||
|
||||
Breaking Changes:
|
||||
|
||||
- Do not export `Node` in the public API, it is not usable on its own and it is
|
||||
|
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "ruma-html"
|
||||
version = "0.1.0"
|
||||
version = "0.2.0"
|
||||
description = "Opinionated HTML parsing and manipulating."
|
||||
homepage = "https://ruma.dev/"
|
||||
keywords = ["matrix", "ruma", "html", "parser"]
|
||||
|
@ -1,5 +1,7 @@
|
||||
# [unreleased]
|
||||
|
||||
# 0.9.5
|
||||
|
||||
Bug fixes:
|
||||
|
||||
- Allow underscores (`_`) when validating MXC URIs.
|
||||
@ -12,6 +14,10 @@ Improvements:
|
||||
|
||||
- Point links to the Matrix 1.10 specification
|
||||
|
||||
# 0.9.4
|
||||
|
||||
Yanked because it was created from the wrong branch
|
||||
|
||||
# 0.9.3
|
||||
|
||||
Improvements:
|
||||
|
@ -4,7 +4,7 @@ description = "Validation logic for ruma-common and ruma-macros"
|
||||
homepage = "https://ruma.dev/"
|
||||
repository = "https://github.com/ruma/ruma"
|
||||
license = "MIT"
|
||||
version = "0.9.3"
|
||||
version = "0.9.5"
|
||||
edition = "2021"
|
||||
rust-version = { workspace = true }
|
||||
|
||||
|
@ -1,5 +1,15 @@
|
||||
# [unreleased]
|
||||
|
||||
# 0.9.0
|
||||
|
||||
Breaking changes:
|
||||
|
||||
- The http crate had a major version bump to version 1.1
|
||||
|
||||
Improvements:
|
||||
|
||||
- The type returned by `get_supported_versions::known_versions()` was simplified
|
||||
|
||||
# 0.8.0
|
||||
|
||||
Breaking changes:
|
||||
|
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "ruma-identity-service-api"
|
||||
version = "0.8.0"
|
||||
version = "0.9.0"
|
||||
description = "Types for the endpoints in the Matrix identity service API."
|
||||
homepage = "https://ruma.dev/"
|
||||
keywords = ["matrix", "chat", "messaging", "ruma"]
|
||||
|
@ -7,7 +7,7 @@ license = "MIT"
|
||||
name = "ruma-macros"
|
||||
readme = "README.md"
|
||||
repository = "https://github.com/ruma/ruma"
|
||||
version = "0.12.0"
|
||||
version = "0.13.0"
|
||||
edition = "2021"
|
||||
rust-version = { workspace = true }
|
||||
|
||||
|
@ -1,5 +1,11 @@
|
||||
# [unreleased]
|
||||
|
||||
# 0.9.0
|
||||
|
||||
Breaking changes:
|
||||
|
||||
- The http crate had a major version bump to version 1.1
|
||||
|
||||
# 0.8.0
|
||||
|
||||
No changes for this version
|
||||
|
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "ruma-push-gateway-api"
|
||||
version = "0.8.0"
|
||||
version = "0.9.0"
|
||||
description = "Types for the endpoints in the Matrix push gateway API."
|
||||
homepage = "https://ruma.dev/"
|
||||
keywords = ["matrix", "chat", "messaging", "ruma"]
|
||||
|
@ -1,5 +1,11 @@
|
||||
# [unreleased]
|
||||
|
||||
# 0.3.0
|
||||
|
||||
Breaking changes:
|
||||
|
||||
- The headers dependency was upgraded to 0.4.0
|
||||
|
||||
# 0.2.0
|
||||
|
||||
No changes for this version
|
||||
|
@ -7,7 +7,7 @@ license = "MIT"
|
||||
name = "ruma-server-util"
|
||||
readme = "README.md"
|
||||
repository = "https://github.com/ruma/ruma"
|
||||
version = "0.2.0"
|
||||
version = "0.3.0"
|
||||
edition = "2021"
|
||||
rust-version = { workspace = true }
|
||||
|
||||
|
@ -1,5 +1,9 @@
|
||||
# [unreleased]
|
||||
|
||||
# 0.15.0
|
||||
|
||||
No changes for this version
|
||||
|
||||
# 0.14.0
|
||||
|
||||
Breaking changes:
|
||||
|
@ -7,7 +7,7 @@ license = "MIT"
|
||||
name = "ruma-signatures"
|
||||
readme = "README.md"
|
||||
repository = "https://github.com/ruma/ruma"
|
||||
version = "0.14.0"
|
||||
version = "0.15.0"
|
||||
edition = "2021"
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
|
@ -1,11 +1,17 @@
|
||||
# [unreleased]
|
||||
|
||||
# 0.11.0
|
||||
|
||||
Breaking changes:
|
||||
|
||||
- Upgrade dependencies
|
||||
|
||||
Bug fixes:
|
||||
|
||||
* Disallow `invite` -> `knock` membership transition
|
||||
* The spec was determined to be right about rejecting it in the first place:
|
||||
<https://github.com/matrix-org/matrix-spec/pull/1717>
|
||||
* Perform extra redaction checks on room versions 1 and 2, rather than for
|
||||
- Disallow `invite` -> `knock` membership transition.
|
||||
The spec was determined to be right about rejecting it in the first place:
|
||||
<https://github.com/matrix-org/matrix-spec/pull/1717>
|
||||
- Perform extra redaction checks on room versions 1 and 2, rather than for
|
||||
version 3 and onwards
|
||||
|
||||
# 0.10.0
|
||||
|
@ -7,7 +7,7 @@ homepage = "https://ruma.dev/"
|
||||
repository = "https://github.com/ruma/ruma"
|
||||
readme = "README.md"
|
||||
license = "MIT"
|
||||
version = "0.10.0"
|
||||
version = "0.11.0"
|
||||
edition = "2021"
|
||||
rust-version = { workspace = true }
|
||||
|
||||
|
@ -1,7 +1,12 @@
|
||||
# [unreleased]
|
||||
|
||||
# 0.10.0
|
||||
|
||||
- Bump MSRV to 1.75
|
||||
- re-export the `ruma-events`'s `unstable-msc2867` feature, manually marking rooms as unread
|
||||
- The http crate had a major version bump to version 1.1
|
||||
- The `client-isahc` feature was removed
|
||||
- Most ruma crates had breaking changes, refer to their changelogs for more
|
||||
details
|
||||
|
||||
# 0.9.4
|
||||
|
||||
|
@ -7,7 +7,7 @@ homepage = "https://ruma.dev/"
|
||||
repository = "https://github.com/ruma/ruma"
|
||||
readme = "README.md"
|
||||
license = "MIT"
|
||||
version = "0.9.4"
|
||||
version = "0.10.0"
|
||||
edition = "2021"
|
||||
rust-version = { workspace = true }
|
||||
|
||||
|
@ -5,7 +5,7 @@ edition = "2021"
|
||||
publish = false
|
||||
|
||||
[dependencies]
|
||||
ruma = { version = "0.9.4", path = "../../crates/ruma", features = ["client-api-c", "client-ext-client-api", "client-hyper-native-tls", "rand"] }
|
||||
ruma = { version = "0.10.0", path = "../../crates/ruma", features = ["client-api-c", "client-ext-client-api", "client-hyper-native-tls", "rand"] }
|
||||
|
||||
anyhow = "1.0.37"
|
||||
tokio = { version = "1.0.1", features = ["macros", "rt"] }
|
||||
|
@ -5,7 +5,7 @@ edition = "2021"
|
||||
publish = false
|
||||
|
||||
[dependencies]
|
||||
ruma = { version = "0.9.4", path = "../../crates/ruma", features = ["client-api-c", "client-ext-client-api", "client-hyper-native-tls", "rand"] }
|
||||
ruma = { version = "0.10.0", path = "../../crates/ruma", features = ["client-api-c", "client-ext-client-api", "client-hyper-native-tls", "rand"] }
|
||||
# For building locally: use the git dependencies below.
|
||||
# Browse the source at this revision here: https://github.com/ruma/ruma/tree/f161c8117c706fc52089999e1f406cf34276ec9d
|
||||
# ruma = { git = "https://github.com/ruma/ruma", rev = "f161c8117c706fc52089999e1f406cf34276ec9d", features = ["client-api-c", "client", "client-hyper-native-tls", "events"] }
|
||||
|
@ -6,6 +6,6 @@ publish = false
|
||||
|
||||
[dependencies]
|
||||
anyhow = "1.0.37"
|
||||
ruma = { version = "0.9.4", path = "../../crates/ruma", features = ["client-api-c", "client-ext-client-api", "client-hyper-native-tls"] }
|
||||
ruma = { version = "0.10.0", path = "../../crates/ruma", features = ["client-api-c", "client-ext-client-api", "client-hyper-native-tls"] }
|
||||
tokio = { version = "1.0.1", features = ["macros", "rt"] }
|
||||
tokio-stream = { version = "0.1.1", default-features = false }
|
||||
|
@ -105,6 +105,11 @@ impl Package {
|
||||
///
|
||||
/// If `update` is `true`, update the changelog for the release of the given version.
|
||||
pub fn changes(&self, update: bool) -> Result<String> {
|
||||
if self.name == "ruma-macros" {
|
||||
// ruma-macros doesn't have a changelog and won't create a tag.
|
||||
return Ok(String::new());
|
||||
}
|
||||
|
||||
let mut changelog_path = self.manifest_path.clone();
|
||||
changelog_path.set_file_name("CHANGELOG.md");
|
||||
|
||||
|
@ -58,7 +58,7 @@ impl ReleaseTask {
|
||||
|
||||
let config = crate::Config::load()?.github;
|
||||
|
||||
let http_client = Client::new();
|
||||
let http_client = Client::builder().user_agent("ruma xtask").build()?;
|
||||
|
||||
Ok(Self { metadata, package, version, http_client, config, dry_run })
|
||||
}
|
||||
@ -67,7 +67,8 @@ impl ReleaseTask {
|
||||
pub(crate) fn run(&mut self) -> Result<()> {
|
||||
let title = &self.title();
|
||||
let prerelease = !self.version.pre.is_empty();
|
||||
let publish_only = self.package.name == "ruma-identifiers-validation";
|
||||
let publish_only =
|
||||
["ruma-identifiers-validation", "ruma-macros"].contains(&self.package.name.as_str());
|
||||
|
||||
println!(
|
||||
"Starting {} for {title}…",
|
||||
|
Loading…
x
Reference in New Issue
Block a user