Skip to content

Commit 51cef91

Browse files
committed
Add AddOrigin middleware
AddOrigin adds a constant origin to all requests.
0 parents  commit 51cef91

File tree

9 files changed

+199
-0
lines changed

9 files changed

+199
-0
lines changed

.gitignore

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
2+
/target/
3+
**/*.rs.bk
4+
Cargo.lock

Cargo.toml

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
[package]
2+
name = "tower-http"
3+
version = "0.1.0"
4+
authors = ["Carl Lerche <me@carllerche.com>"]
5+
6+
[workspace]
7+
members = [
8+
"tower-add-origin",
9+
]
10+
11+
[dependencies]
12+
tower-add-origin = { path = "tower-add-origin" }

LICENSE

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
Copyright (c) 2018 tower-http authors.
2+
3+
Permission is hereby granted, free of charge, to any
4+
person obtaining a copy of this software and associated
5+
documentation files (the "Software"), to deal in the
6+
Software without restriction, including without
7+
limitation the rights to use, copy, modify, merge,
8+
publish, distribute, sublicense, and/or sell copies of
9+
the Software, and to permit persons to whom the Software
10+
is furnished to do so, subject to the following
11+
conditions:
12+
13+
The above copyright notice and this permission notice
14+
shall be included in all copies or substantial portions
15+
of the Software.
16+
17+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
18+
ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
19+
TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
20+
PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
21+
SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
22+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
23+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
24+
IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
25+
DEALINGS IN THE SOFTWARE.

README.md

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# Tower HTTP
2+
3+
Tower utilities for HTTP clients and servers
4+
5+
[![Build Status](https://travis-ci.org/tower-rs/tower-http.svg?branch=master)](https://travis-ci.org/tower-rs/tower-http)
6+
7+
More information about this crate can be found in the [crate documentation][dox]
8+
9+
[dox]: https://tower-rs.github.io/tower-http/tower_http
10+
11+
**This library is not production ready. Do not try to use it in a production
12+
environment or you will regret it!** This crate is still under active
13+
development and there has not yet been any focus on documentation (because you
14+
shouldn't be using it yet!).
15+

src/lib.rs

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
extern crate tower_add_origin;
2+
3+
pub use tower_add_origin::AddOrigin;

tower-add-origin/Cargo.toml

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
[package]
2+
name = "tower-add-origin"
3+
version = "0.1.0"
4+
authors = ["Carl Lerche <me@carllerche.com>"]
5+
6+
[dependencies]
7+
futures = "0.1"
8+
http = "0.1"
9+
tower = { git = "https://github.com/tower-rs/tower" }
10+
11+
[dev-dependencies]
12+
tower-mock = { git = "https://github.com/tower-rs/tower" }

tower-add-origin/README.md

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Add Origin
2+
3+
HTTP specific Tower middleware that adds a constant origin to all requests.

tower-add-origin/src/lib.rs

+85
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
extern crate futures;
2+
extern crate http;
3+
extern crate tower;
4+
5+
use futures::Poll;
6+
use http::Request;
7+
use http::uri::{Authority, Scheme};
8+
use tower::Service;
9+
10+
/// Wraps an HTTP service, injecting authority and scheme on every request.
11+
pub struct AddOrigin<T> {
12+
inner: T,
13+
scheme: Scheme,
14+
authority: Authority,
15+
}
16+
17+
impl<T> AddOrigin<T> {
18+
/// Create a new `AddOrigin`
19+
pub fn new(inner: T, scheme: Scheme, authority: Authority) -> Self {
20+
AddOrigin {
21+
inner,
22+
authority,
23+
scheme,
24+
}
25+
}
26+
27+
/// Return a reference to the HTTP scheme that is added to all requests.
28+
pub fn scheme(&self) -> &Scheme {
29+
&self.scheme
30+
}
31+
32+
/// Return a reference to the HTTP authority that is added to all requests.
33+
pub fn authority(&self) -> &Authority {
34+
&self.authority
35+
}
36+
37+
/// Returns a reference to the inner service.
38+
pub fn get_ref(&self) -> &T {
39+
&self.inner
40+
}
41+
42+
/// Returns a mutable reference to the inner service.
43+
pub fn get_mut(&mut self) -> &mut T {
44+
&mut self.inner
45+
}
46+
47+
/// Consumes `self`, returning the inner service.
48+
pub fn into_inner(self) -> T {
49+
self.inner
50+
}
51+
}
52+
53+
impl<T, B> Service for AddOrigin<T>
54+
where T: Service<Request = Request<B>>,
55+
{
56+
type Request = Request<B>;
57+
type Response = T::Response;
58+
type Error = T::Error;
59+
type Future = T::Future;
60+
61+
fn poll_ready(&mut self) -> Poll<(), Self::Error> {
62+
self.inner.poll_ready()
63+
}
64+
65+
fn call(&mut self, req: Self::Request) -> Self::Future {
66+
// Split the request into the head and the body.
67+
let (mut head, body) = req.into_parts();
68+
69+
// Split the request URI into parts.
70+
let mut uri: http::uri::Parts = head.uri.into();
71+
72+
// Update the URI parts, setting hte scheme and authority
73+
uri.scheme = Some(self.scheme.clone());
74+
uri.authority = Some(self.authority.clone());
75+
76+
// Update the the request URI
77+
head.uri = http::Uri::from_parts(uri)
78+
.expect("valid uri");
79+
80+
let request = Request::from_parts(head, body);
81+
82+
// Call the inner service
83+
self.inner.call(request)
84+
}
85+
}

tower-add-origin/tests/add_origin.rs

+40
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
extern crate http;
2+
extern crate tower;
3+
extern crate tower_add_origin;
4+
extern crate tower_mock;
5+
6+
use http::{Request, Response};
7+
use http::uri::*;
8+
use tower::Service;
9+
use tower_add_origin::*;
10+
use tower_mock::*;
11+
12+
#[test]
13+
fn adds_origin_to_requests() {
14+
let scheme = Scheme::HTTP;
15+
let authority: Authority = "www.example.com".parse().unwrap();
16+
17+
let (mock, mut handle) = Mock::<_, _, ()>::new();
18+
let mut add_origin = AddOrigin::new(mock, scheme.clone(), authority.clone());
19+
20+
let request = Request::get("/")
21+
.body(())
22+
.unwrap();
23+
24+
let _response = add_origin.call(request);
25+
26+
// Get the request
27+
let request = handle.next_request().unwrap();
28+
let (request, send_response) = request.into_parts();
29+
30+
// Assert that the origin is set
31+
assert_eq!(request.uri().scheme_part().unwrap(), &scheme);
32+
assert_eq!(request.uri().authority_part().unwrap(), &authority);
33+
34+
// Make everything happy:
35+
let response = Response::builder()
36+
.status(204)
37+
.body(());
38+
39+
send_response.respond(response);
40+
}

0 commit comments

Comments
 (0)