Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

http compatibility #286

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions crux_http/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ default = ["encoding"]
# requires web-sys for TextDecoder on wasm
encoding = ["encoding_rs", "web-sys"]
typegen = ["crux_core/typegen"]
http-compat = ["dep:http"]

[dependencies]
anyhow.workspace = true
Expand All @@ -24,6 +25,7 @@ derive_builder = "0.20.2"
encoding_rs = { version = "0.8.34", optional = true }
futures-util = "0.3"
http-types = { package = "http-types-red-badger-temporary-fork", version = "2.12.0", default-features = false }
http = { version = "1.1", optional = true }
pin-project-lite = "0.2.14"
serde = { workspace = true, features = ["derive"] }
serde_bytes = "0.11"
Expand Down
2 changes: 1 addition & 1 deletion crux_http/src/client.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
use std::fmt;
use std::sync::Arc;

use crate::http::{Method, Url};
use crate::middleware::{Middleware, Next};
use crate::protocol::{EffectSender, HttpResult, ProtocolRequestBuilder};
use crate::{Config, Request, RequestBuilder, ResponseAsync, Result};
use http_types::{Method, Url};

/// An HTTP client, capable of sending `Request`s
///
Expand Down
6 changes: 4 additions & 2 deletions crux_http/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@

use std::{collections::HashMap, fmt::Debug};

use http_types::headers::{HeaderName, HeaderValues, ToHeaderValues};
use http_types::{
headers::{HeaderName, HeaderValues, ToHeaderValues},
Url,
};

use crate::http::Url;
use crate::Result;

/// Configuration for `crux_http::Http`s and their underlying HTTP client.
Expand Down
8 changes: 4 additions & 4 deletions crux_http/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ pub enum HttpError {
#[error("HTTP error {code}: {message}")]
#[serde(skip)]
Http {
code: crate::http::StatusCode,
code: http_types::StatusCode,
message: String,
body: Option<Vec<u8>>,
},
Expand All @@ -21,8 +21,8 @@ pub enum HttpError {
Timeout,
}

impl From<crate::http::Error> for HttpError {
fn from(e: crate::http::Error) -> Self {
impl From<http_types::Error> for HttpError {
fn from(e: http_types::Error) -> Self {
HttpError::Http {
code: e.status(),
message: e.to_string(),
Expand Down Expand Up @@ -50,7 +50,7 @@ mod tests {
#[test]
fn test_error_display() {
let error = HttpError::Http {
code: crate::http::StatusCode::BadRequest,
code: http_types::StatusCode::BadRequest,
message: "Bad Request".to_string(),
body: None,
};
Expand Down
6 changes: 3 additions & 3 deletions crux_http/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
// #![warn(missing_docs)]

use crux_core::capability::CapabilityContext;
use http::Method;
use http_types::Method;
use url::Url;

mod config;
Expand All @@ -21,7 +21,7 @@ pub mod middleware;
pub mod protocol;
pub mod testing;

pub use http_types::{self as http};
pub use http_types;

pub use self::{
config::Config,
Expand Down Expand Up @@ -307,7 +307,7 @@ where
///
/// When finished, the response will be wrapped in an event and dispatched to
/// the app's `update function.
pub fn request(&self, method: http::Method, url: Url) -> RequestBuilder<Ev> {
pub fn request(&self, method: http_types::Method, url: Url) -> RequestBuilder<Ev> {
RequestBuilder::new(method, url, self.clone())
}
}
6 changes: 3 additions & 3 deletions crux_http/src/middleware/redirect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@
//! # }
//! ```

use crate::http::{self, headers, StatusCode, Url};
use crate::middleware::{Middleware, Next, Request};
use crate::{Client, ResponseAsync, Result};
use http_types::{headers, StatusCode, Url};

// List of acceptable 300-series redirect codes.
const REDIRECT_CODES: &[StatusCode] = &[
Expand Down Expand Up @@ -107,14 +107,14 @@ impl Middleware for Redirect {
let res: ResponseAsync = client.send(r).await?;
if REDIRECT_CODES.contains(&res.status()) {
if let Some(location) = res.header(headers::LOCATION) {
let http_req: &mut http::Request = req.as_mut();
let http_req: &mut http_types::Request = req.as_mut();
*http_req.url_mut() = match Url::parse(location.last().as_str()) {
Ok(valid_url) => {
base_url = valid_url;
base_url.clone()
}
Err(e) => match e {
http::url::ParseError::RelativeUrlWithoutBase => {
http_types::url::ParseError::RelativeUrlWithoutBase => {
base_url.join(location.last().as_str())?
}
e => return Err(e.into()),
Expand Down
2 changes: 1 addition & 1 deletion crux_http/src/protocol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ impl ProtocolRequestBuilder for crate::Request {

impl From<HttpResponse> for crate::ResponseAsync {
fn from(effect_response: HttpResponse) -> Self {
let mut res = crate::http::Response::new(effect_response.status);
let mut res = http_types::Response::new(effect_response.status);
res.set_body(effect_response.body);
for header in effect_response.headers {
res.append_header(header.name.as_str(), header.value);
Expand Down
63 changes: 40 additions & 23 deletions crux_http/src/request.rs
Original file line number Diff line number Diff line change
@@ -1,21 +1,22 @@
use crate::http::{
self,
use crate::middleware::Middleware;
use http_types::{
headers::{self, HeaderName, HeaderValues, ToHeaderValues},
Body, Method, Mime, Url,
};
use crate::middleware::Middleware;

use serde::Serialize;

use std::fmt;
use std::ops::Index;
use std::str::FromStr;
use std::sync::Arc;
use anyhow::anyhow;

/// An HTTP request, returns a `Response`.
#[derive(Clone)]
pub struct Request {
/// Holds the state of the request.
req: http::Request,
req: http_types::Request,
/// Holds an optional per-request middleware stack.
middleware: Option<Vec<Arc<dyn Middleware>>>,
}
Expand All @@ -31,14 +32,14 @@ impl Request {
///
/// ```
/// fn main() -> crux_http::Result<()> {
/// use crux_http::http::{Url, Method};
/// use crux_http::http_types::{Url, Method};
///
/// let url = Url::parse("https://httpbin.org/get")?;
/// let req = crux_http::Request::new(Method::Get, url);
/// # Ok(()) }
/// ```
pub fn new(method: Method, url: Url) -> Self {
let req = http::Request::new(method, url);
let req = http_types::Request::new(method, url);
Self {
req,
middleware: None,
Expand Down Expand Up @@ -199,7 +200,7 @@ impl Request {
/// # struct Capabilities { http: crux_http::Http<Event> }
/// # fn update(caps: &Capabilities) -> crux_http::Result<()> {
/// let req = caps.http.get("https://httpbin.org/get").build();
/// assert_eq!(req.method(), crux_http::http::Method::Get);
/// assert_eq!(req.method(), crux_http::http_types::Method::Get);
/// # Ok(()) }
/// ```
pub fn method(&self) -> Method {
Expand All @@ -214,7 +215,7 @@ impl Request {
/// # enum Event {}
/// # struct Capabilities { http: crux_http::Http<Event> }
/// # fn update(caps: &Capabilities) -> crux_http::Result<()> {
/// use crux_http::http::Url;
/// use crux_http::http_types::Url;
/// let req = caps.http.get("https://httpbin.org/get").build();
/// assert_eq!(req.url(), &Url::parse("https://httpbin.org/get")?);
/// # Ok(()) }
Expand Down Expand Up @@ -362,44 +363,60 @@ impl Request {
}
}

impl AsRef<http::Headers> for Request {
fn as_ref(&self) -> &http::Headers {
impl AsRef<http_types::Headers> for Request {
fn as_ref(&self) -> &http_types::Headers {
self.req.as_ref()
}
}

impl AsMut<http::Headers> for Request {
fn as_mut(&mut self) -> &mut http::Headers {
impl AsMut<http_types::Headers> for Request {
fn as_mut(&mut self) -> &mut http_types::Headers {
self.req.as_mut()
}
}

impl AsRef<http::Request> for Request {
fn as_ref(&self) -> &http::Request {
impl AsRef<http_types::Request> for Request {
fn as_ref(&self) -> &http_types::Request {
&self.req
}
}

impl AsMut<http::Request> for Request {
fn as_mut(&mut self) -> &mut http::Request {
impl AsMut<http_types::Request> for Request {
fn as_mut(&mut self) -> &mut http_types::Request {
&mut self.req
}
}

impl From<http::Request> for Request {
/// Converts an `http::Request` to a `crux_http::Request`.
fn from(req: http::Request) -> Self {
impl From<http_types::Request> for Request {
/// Converts an `http_types::Request` to a `crux_http::Request`.
fn from(req: http_types::Request) -> Self {
Self {
req,
middleware: None,
}
}
}

#[cfg(feature = "http-compat")]
impl<B: Into<Body>> TryFrom<http::Request<B>> for Request {
type Error = anyhow::Error;

fn try_from(req: http::Request<B>) -> Result<Self, Self::Error> {
let mut o = Request::new(Method::from_str(req.method().as_str()).map_err(|e| anyhow!(e))?, req.uri().to_string().parse()?);

for (k, v) in req.headers().iter() {
o.append_header(k.as_str(), v.to_str()?);
}

o.set_body(req.into_body());
Ok(o)
}
}

#[allow(clippy::from_over_into)]
impl Into<http::Request> for Request {
/// Converts a `crux_http::Request` to an `http::Request`.
fn into(self) -> http::Request {
impl Into<http_types::Request> for Request {
/// Converts a `crux_http::Request` to an `http_types::Request`.
fn into(self) -> http_types::Request {
self.req
}
}
Expand All @@ -414,7 +431,7 @@ impl IntoIterator for Request {
type Item = (HeaderName, HeaderValues);
type IntoIter = headers::IntoIter;

/// Returns a iterator of references over the remaining items.
/// Returns an iterator of references over the remaining items.
#[inline]
fn into_iter(self) -> Self::IntoIter {
self.req.into_iter()
Expand Down
20 changes: 9 additions & 11 deletions crux_http/src/request_builder.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,14 @@
use crate::expect::ResponseExpectation;
use crate::expect::{ExpectBytes, ExpectJson, ExpectString};
use crate::middleware::Middleware;
use crate::{
expect::ResponseExpectation,
http::{
headers::{HeaderName, ToHeaderValues},
Body, Method, Mime, Url,
},
};
use crate::{Client, HttpError, Request, Response, ResponseAsync, Result};

use futures_util::future::BoxFuture;
use http_types::convert::DeserializeOwned;
use http_types::{
convert::DeserializeOwned,
headers::{HeaderName, ToHeaderValues},
Body, Method, Mime, Url,
};
use serde::Serialize;

use std::{fmt, marker::PhantomData};
Expand All @@ -23,7 +21,7 @@ use std::{fmt, marker::PhantomData};
/// # Examples
///
/// ```no_run
/// use crux_http::http::{mime::HTML};
/// use crux_http::http_types::{mime::HTML};
/// # enum Event { ReceiveResponse(crux_http::Result<crux_http::Response<Vec<u8>>>) }
/// # struct Capabilities { http: crux_http::Http<Event> }
/// # fn update(caps: &Capabilities) {
Expand Down Expand Up @@ -107,7 +105,7 @@ where
/// # Examples
///
/// ```no_run
/// # use crux_http::http::mime;
/// # use crux_http::http_types::mime;
/// # enum Event { ReceiveResponse(crux_http::Result<crux_http::Response<Vec<u8>>>) }
/// # struct Capabilities { http: crux_http::Http<Event> }
/// # fn update(caps: &Capabilities) {
Expand Down Expand Up @@ -137,7 +135,7 @@ where
/// # struct Capabilities { http: crux_http::Http<Event> }
/// # fn update(caps: &Capabilities) {
/// use serde_json::json;
/// use crux_http::http::mime;
/// use crux_http::http_types::mime;
/// caps.http
/// .post("https://httpbin.org/post")
/// .body(json!({"any": "Into<Body>"}))
Expand Down
2 changes: 1 addition & 1 deletion crux_http/src/response/decode.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::http::Error;
use http_types::Error;

use std::fmt;
use std::io;
Expand Down
4 changes: 2 additions & 2 deletions crux_http/src/response/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ mod response_async;

pub use self::{response::Response, response_async::ResponseAsync};

pub(crate) fn new_headers() -> crate::http::Headers {
pub(crate) fn new_headers() -> http_types::Headers {
// http-types doesn't seem to let you construct a Headers, very annoying.
// So here's a horrible hack to do it.
crate::http::Request::new(crate::http::Method::Get, "https://thisisveryannoying.com")
http_types::Request::new(http_types::Method::Get, "https://thisisveryannoying.com")
.as_ref()
.clone()
}
Loading