Skip to content

Commit

Permalink
Merge branch 'master' into master
Browse files Browse the repository at this point in the history
  • Loading branch information
wca committed Jan 11, 2024
2 parents 1f09e93 + 2c3581e commit a3f5e78
Show file tree
Hide file tree
Showing 24 changed files with 234 additions and 106 deletions.
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,13 @@
### v0.3.6 (September 27, 2023)

- **Features**:
- Add ability to pass `None` to `multipart::form().max_length()`.
- Implement `Reply` for `Result<impl Reply, impl Reply>`.
- Make `multipart::Part::content_type()` return the full mime string.
- Add `TlsServer::try_bind_with_graceful_shutdown()`.
- **Fixes**:
- Updated tungstenite and rustls dependencies for security fixes.

### v0.3.5 (April 28, 2023)

- **Fixes**:
Expand Down
17 changes: 8 additions & 9 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "warp"
version = "0.3.5" # don't forget to update html_root_url
version = "0.3.6" # don't forget to update html_root_url
description = "serve the web at warp speeds"
authors = ["Sean McArthur <sean@seanmonstar.com>"]
license = "MIT"
Expand All @@ -21,7 +21,7 @@ async-compression = { version = "0.3.7", features = ["tokio"], optional = true }
bytes = "1.0"
futures-util = { version = "0.3", default-features = false, features = ["sink"] }
futures-channel = { version = "0.3.17", features = ["sink"]}
headers = "0.3"
headers = "0.3.5"
http = "0.2"
hyper = { version = "0.14", features = ["stream", "server", "http1", "http2", "tcp", "client"] }
log = "0.4"
Expand All @@ -31,17 +31,16 @@ multer = { version = "2.1.0", optional = true }
scoped-tls = "1.0"
serde = "1.0"
serde_json = "1.0"
serde_urlencoded = "0.7"
serde_urlencoded = "0.7.1"
tokio = { version = "1.0", features = ["fs", "sync", "time"] }
tokio-stream = "0.1.1"
tokio-util = { version = "0.7", features = ["io"] }
tokio-util = { version = "0.7.1", features = ["io"] }
tracing = { version = "0.1.21", default-features = false, features = ["log", "std"] }
tower-service = "0.3"
tokio-tungstenite = { version = "0.18", optional = true }
tokio-tungstenite = { version = "0.20", optional = true }
percent-encoding = "2.1"
pin-project = "1.0"
tokio-rustls = { version = "0.23", optional = true }
rustls-pemfile = "1.0"
tokio-rustls = { version = "0.25", optional = true }
rustls-pemfile = { version = "2.0", optional = true }

[dev-dependencies]
pretty_env_logger = "0.5"
Expand All @@ -57,7 +56,7 @@ listenfd = "1.0"
default = ["multipart", "websocket"]
multipart = ["multer"]
websocket = ["tokio-tungstenite"]
tls = ["tokio-rustls"]
tls = ["tokio-rustls", "rustls-pemfile"]

# Enable compression-related filters
compression = ["compression-brotli", "compression-gzip"]
Expand Down
5 changes: 2 additions & 3 deletions examples/multipart.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use bytes::BufMut;
use futures_util::TryStreamExt;
use warp::multipart::FormData;
use warp::Buf;
use warp::Filter;

#[tokio::main]
Expand All @@ -14,8 +14,7 @@ async fn main() {
// field.data() only returns a piece of the content, you should call over it until it replies None
while let Some(content) = field.data().await {
let content = content.unwrap();
let chunk: &[u8] = content.chunk();
bytes.extend_from_slice(chunk);
bytes.put(content);
}
Ok((
field.name().to_string(),
Expand Down
30 changes: 30 additions & 0 deletions examples/stream.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
use bytes::Buf;
use futures_util::{Stream, StreamExt};
use warp::{reply::Response, Filter, Reply};

#[tokio::main]
async fn main() {
// Running curl -T /path/to/a/file 'localhost:3030/' should echo back the content of the file,
// or an HTTP 413 error if the configured size limit is exceeded.
let route = warp::body::content_length_limit(65536)
.and(warp::body::stream())
.then(handler);
warp::serve(route).run(([127, 0, 0, 1], 3030)).await;
}

async fn handler(
mut body: impl Stream<Item = Result<impl Buf, warp::Error>> + Unpin + Send + Sync,
) -> Response {
let mut collected: Vec<u8> = vec![];
while let Some(buf) = body.next().await {
let mut buf = buf.unwrap();
while buf.remaining() > 0 {
let chunk = buf.chunk();
let chunk_len = chunk.len();
collected.extend_from_slice(chunk);
buf.advance(chunk_len);
}
}
println!("Sending {} bytes", collected.len());
collected.into_response()
}
4 changes: 4 additions & 0 deletions examples/tls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,12 @@ async fn main() {

warp::serve(routes)
.tls()
// RSA
.cert_path("examples/tls/cert.pem")
.key_path("examples/tls/key.rsa")
// ECC
// .cert_path("examples/tls/cert.ecc.pem")
// .key_path("examples/tls/key.ecc")
.run(([127, 0, 0, 1], 3030))
.await;
}
Expand Down
12 changes: 12 additions & 0 deletions examples/tls/cert.ecc.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
-----BEGIN CERTIFICATE-----
MIIBtDCCAVoCCQDFz95/8CeJaDAKBggqhkjOPQQDAjBiMQswCQYDVQQGEwJERTEQ
MA4GA1UECAwHR2VybWFueTEQMA4GA1UEBwwHTGVpcHppZzESMBAGA1UEAwwJbG9j
YWwuZGV2MRswGQYJKoZIhvcNAQkBFgxoaUBsb2NhbC5kZXYwHhcNMjMwNTI4MTk0
NzA4WhcNMjYwNTI3MTk0NzA4WjBiMQswCQYDVQQGEwJERTEQMA4GA1UECAwHR2Vy
bWFueTEQMA4GA1UEBwwHTGVpcHppZzESMBAGA1UEAwwJbG9jYWwuZGV2MRswGQYJ
KoZIhvcNAQkBFgxoaUBsb2NhbC5kZXYwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNC
AATZR4F60X+iHjeD6kySZfXljNckDb22QYQ76Ts4GFYWkdDstU6yehxyER+MZWsm
UnTE/Gy3mnpSmMzoSBfoKRmHMAoGCCqGSM49BAMCA0gAMEUCIQChOTwbAYlx6zg0
yc3Oc+zrNY8Yd8oRUD+cG/wdz+gN/wIgP199zXAPXiYUFFd1CnIYmWJSglaOUbYj
ZP/ixZR9HQs=
-----END CERTIFICATE-----
5 changes: 5 additions & 0 deletions examples/tls/key.ecc
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
-----BEGIN EC PRIVATE KEY-----
MHcCAQEEIPwp3LAnLEyWe2lLz66Y3QCCJ/BEMJheTM0shZnnSw6toAoGCCqGSM49
AwEHoUQDQgAE2UeBetF/oh43g+pMkmX15YzXJA29tkGEO+k7OBhWFpHQ7LVOsnoc
chEfjGVrJlJ0xPxst5p6UpjM6EgX6CkZhw==
-----END EC PRIVATE KEY-----
2 changes: 1 addition & 1 deletion src/filter/boxed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use futures_util::TryFutureExt;
use super::{Filter, FilterBase, Internal, Tuple};
use crate::reject::Rejection;

/// A type representing a boxed `Filter` trait object.
/// A type representing a boxed [`Filter`](crate::Filter) trait object.
///
/// The filter inside is a dynamic trait object. The purpose of this type is
/// to ease returning `Filter`s from other functions.
Expand Down
4 changes: 2 additions & 2 deletions src/filters/any.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@ use std::task::{Context, Poll};

use crate::filter::{Filter, FilterBase, Internal};

/// A filter that matches any route.
/// A [`Filter`](crate::Filter) that matches any route.
///
/// This can be a useful building block to build new filters from,
/// since [`Filter`](crate::Filter) is otherwise a sealed trait.
/// since [`Filter`] is otherwise a sealed trait.
///
/// # Example
///
Expand Down
2 changes: 2 additions & 0 deletions src/filters/body.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,8 @@ pub fn content_length_limit(limit: u64) -> impl Filter<Extract = (), Error = Rej
/// If other filters have already extracted the body, this filter will reject
/// with a `500 Internal Server Error`.
///
/// For example usage, please take a look at [examples/stream.rs](https://github.com/seanmonstar/warp/blob/master/examples/stream.rs).
///
/// # Warning
///
/// This does not have a default size limit, it would be wise to use one to
Expand Down
4 changes: 2 additions & 2 deletions src/filters/cors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ use crate::reply::Reply;

use self::internal::{CorsFilter, IntoOrigin, Seconds};

/// Create a wrapping filter that exposes [CORS][] behavior for a wrapped
/// Create a wrapping [`Filter`](crate::Filter) that exposes [CORS][] behavior for a wrapped
/// filter.
///
/// [CORS]: https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS
Expand Down Expand Up @@ -56,7 +56,7 @@ pub fn cors() -> Builder {
}
}

/// A wrapping filter constructed via `warp::cors()`.
/// A wrapping [`Filter`](crate::Filter) constructed via `warp::cors()`.
#[derive(Clone, Debug)]
pub struct Cors {
config: Arc<Configured>,
Expand Down
2 changes: 1 addition & 1 deletion src/filters/fs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ use crate::reply::{Reply, Response};
/// filters, such as after validating in `POST` request, wanting to return a
/// specific file as the body.
///
/// For serving a directory, see [dir](dir).
/// For serving a directory, see [dir].
///
/// # Example
///
Expand Down
6 changes: 3 additions & 3 deletions src/filters/log.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use crate::route::Route;

use self::internal::WithLog;

/// Create a wrapping filter with the specified `name` as the `target`.
/// Create a wrapping [`Filter`](crate::Filter) with the specified `name` as the `target`.
///
/// This uses the default access logging format, and log records produced
/// will have their `target` set to `name`.
Expand Down Expand Up @@ -50,7 +50,7 @@ pub fn log(name: &'static str) -> Log<impl Fn(Info<'_>) + Copy> {
Log { func }
}

/// Create a wrapping filter that receives `warp::log::Info`.
/// Create a wrapping [`Filter`](crate::Filter) that receives `warp::log::Info`.
///
/// # Example
///
Expand All @@ -77,7 +77,7 @@ where
Log { func }
}

/// Decorates a [`Filter`](crate::Filter) to log requests and responses.
/// Decorates a [`Filter`] to log requests and responses.
#[derive(Clone, Copy, Debug)]
pub struct Log<F> {
func: F,
Expand Down
6 changes: 3 additions & 3 deletions src/filters/multipart.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! Multipart body filters
//!
//! Filters that extract a multipart body for a route.
//! [`Filter`](crate::Filter)s that extract a multipart body for a route.

use std::error::Error as StdError;
use std::fmt::{Display, Formatter};
Expand All @@ -22,7 +22,7 @@ use crate::reject::{self, Rejection};
// If not otherwise configured, default to 2MB.
const DEFAULT_FORM_DATA_MAX_LENGTH: u64 = 1024 * 1024 * 2;

/// A `Filter` to extract a `multipart/form-data` body from a request.
/// A [`Filter`](crate::Filter) to extract a `multipart/form-data` body from a request.
///
/// Create with the `warp::multipart::form()` function.
#[derive(Debug, Clone)]
Expand All @@ -44,7 +44,7 @@ pub struct Part {
part: PartInner<'static>,
}

/// Create a `Filter` to extract a `multipart/form-data` body from a request.
/// Create a [`Filter`](crate::Filter) to extract a `multipart/form-data` body from a request.
///
/// The extracted `FormData` type is a `Stream` of `Part`s, and each `Part`
/// in turn is a `Stream` of bytes.
Expand Down
6 changes: 3 additions & 3 deletions src/filters/path.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! Path Filters
//!
//! The filters here work on the "path" of requests.
//! The [`Filter`](crate::Filter)s here work on the "path" of requests.
//!
//! - [`path`](./fn.path.html) matches a specific segment, like `/foo`.
//! - [`param`](./fn.param.html) tries to parse a segment into a type, like `/:u16`.
Expand Down Expand Up @@ -137,7 +137,7 @@ use crate::filter::{filter_fn, one, Filter, FilterBase, Internal, One, Tuple};
use crate::reject::{self, Rejection};
use crate::route::{self, Route};

/// Create an exact match path segment `Filter`.
/// Create an exact match path segment [`Filter`](crate::Filter).
///
/// This will try to match exactly to the current request path segment.
///
Expand Down Expand Up @@ -189,7 +189,7 @@ where
*/
}

/// A `Filter` matching an exact path segment.
/// A [`Filter`](crate::Filter) matching an exact path segment.
///
/// Constructed from `path()` or `path!()`.
#[allow(missing_debug_implementations)]
Expand Down
12 changes: 6 additions & 6 deletions src/filters/reply.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,12 @@ use self::sealed::{WithDefaultHeader_, WithHeader_, WithHeaders_};
use crate::filter::{Filter, Map, WrapSealed};
use crate::reply::Reply;

/// Wrap a [`Filter`](crate::Filter) that adds a header to the reply.
/// Wrap a [`Filter`] that adds a header to the reply.
///
/// # Note
///
/// This **only** adds a header if the underlying filter is successful, and
/// returns a [`Reply`](Reply). If the underlying filter was rejected, the
/// returns a [`Reply`] If the underlying filter was rejected, the
/// header is not added.
///
/// # Example
Expand All @@ -57,12 +57,12 @@ where
WithHeader { name, value }
}

/// Wrap a [`Filter`](crate::Filter) that adds multiple headers to the reply.
/// Wrap a [`Filter`] that adds multiple headers to the reply.
///
/// # Note
///
/// This **only** adds a header if the underlying filter is successful, and
/// returns a [`Reply`](Reply). If the underlying filter was rejected, the
/// returns a [`Reply`] If the underlying filter was rejected, the
/// header is not added.
///
/// # Example
Expand All @@ -88,13 +88,13 @@ pub fn headers(headers: HeaderMap) -> WithHeaders {

// pub fn headers?

/// Wrap a [`Filter`](crate::Filter) that adds a header to the reply, if they
/// Wrap a [`Filter`] that adds a header to the reply, if they
/// aren't already set.
///
/// # Note
///
/// This **only** adds a header if the underlying filter is successful, and
/// returns a [`Reply`](Reply). If the underlying filter was rejected, the
/// returns a [`Reply`] If the underlying filter was rejected, the
/// header is not added.
///
/// # Example
Expand Down
4 changes: 3 additions & 1 deletion src/filters/sse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@
//! which specifies the expected behavior of Server Sent Events.
//!

#![allow(rustdoc::invalid_html_tags)]

use serde::Serialize;
use std::borrow::Cow;
use std::error::Error as StdError;
Expand Down Expand Up @@ -376,7 +378,7 @@ impl KeepAlive {

/// Wrap an event stream with keep-alive functionality.
///
/// See [`keep_alive`](keep_alive) for more.
/// See [`keep_alive`] for more.
pub fn stream<S>(
self,
event_stream: S,
Expand Down
2 changes: 1 addition & 1 deletion src/filters/trace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ pub fn named(name: &'static str) -> Trace<impl Fn(Info<'_>) -> Span + Copy> {
trace(move |_| tracing::debug_span!("context", "{}", name,))
}

/// Decorates a [`Filter`](crate::Filter) to create a [`tracing`] [span] for
/// Decorates a [`Filter`] to create a [`tracing`] [span] for
/// requests and responses.
///
/// [`tracing`]: https://crates.io/crates/tracing
Expand Down
18 changes: 14 additions & 4 deletions src/filters/ws.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ pub fn ws() -> impl Filter<Extract = One<Ws>, Error = Rejection> + Copy {
)
}

/// Extracted by the [`ws`](ws) filter, and used to finish an upgrade.
/// Extracted by the [`ws`] filter, and used to finish an upgrade.
pub struct Ws {
config: Option<WebSocketConfig>,
key: SecWebsocketKey,
Expand All @@ -92,11 +92,21 @@ impl Ws {

// config

/// Set the size of the internal message send queue.
pub fn max_send_queue(mut self, max: usize) -> Self {
/// Does nothing.
///
/// # Deprecated
///
/// Use `max_write_buffer_size()` instead.
#[deprecated = "use max_write_buffer_size instead"]
pub fn max_send_queue(self, _max: usize) -> Self {
self
}

/// The max size of the write buffer, in bytes.
pub fn max_write_buffer_size(mut self, max: usize) -> Self {
self.config
.get_or_insert_with(WebSocketConfig::default)
.max_send_queue = Some(max);
.max_write_buffer_size = max;
self
}

Expand Down

0 comments on commit a3f5e78

Please sign in to comment.