Skip to content
This repository was archived by the owner on Jun 21, 2020. It is now read-only.

Write docs #19

Merged
merged 18 commits into from
Apr 25, 2019
6 changes: 0 additions & 6 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
<<<<<<< HEAD
# Generated by Cargo
# will have compiled files and executables
/target/
Expand All @@ -9,8 +8,3 @@ Cargo.lock

# These are backup files generated by rustfmt
**/*.rs.bk
=======
/target
**/*.rs.bk
Cargo.lock
>>>>>>> Initial commit
3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,8 @@ members = ["http-service-hyper", "http-service-mock"]
bytes = "0.4.12"
http = "0.1.17"

[dev-dependencies]
http-service-hyper = { path = "http-service-hyper", version = "0.1.1" }

[dependencies.futures-preview]
version = "0.3.0-alpha.14"
117 changes: 110 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,116 @@
# http-service
<h1 align="center">http-service</h1>
<div align="center">
<strong>
Types and traits to help you implement your own HTTP server
</strong>
</div>

[![build status][1]][2]
<br />

Types and traits giving an interface between low-level http server implementations
and services that use them. The interface is based on the `std::futures` API.
<div align="center">
<!-- Crates version -->
<a href="https://crates.io/crates/http-service">
<img src="https://img.shields.io/crates/v/http-service.svg?style=flat-square"
alt="Crates.io version" />
</a>
<!-- Build Status -->
<a href="https://travis-ci.org/rust-net-web/http-service">
<img src="https://img.shields.io/travis/rust-net-web/http-service.svg?style=flat-square"
alt="Build Status" />
</a>
<!-- Downloads -->
<a href="https://crates.io/crates/http-service">
<img src="https://img.shields.io/crates/d/http-service.svg?style=flat-square"
alt="Download" />
</a>
<!-- docs.rs docs -->
<a href="https://docs.rs/http-service/0.1.5/http_service">
<img src="https://img.shields.io/badge/docs-latest-blue.svg?style=flat-square"
alt="docs.rs docs" />
</a>
</div>

<div align="center">
<h3>
<a href="https://docs.rs/http-service/0.1.5/http_service/">
API Docs
</a>
<span> | </span>
<a href="https://discordapp.com/channels/442252698964721669/474974025454452766">
Chat
</a>
</h3>
</div>

<div align="center">
<sub>Built with ⛵ by <a href="https://github.com/rustasync">The Rust Async Ecosystem WG</a>
</div>

## About
The crate `http-service` provides the necessary types and traits to implement your own HTTP Server. It uses `hyper` for the lower level TCP abstraction.

You can use the workspace member [`http-service-hyper`](https://crates.io/crates/http-service-hyper) to run your HTTP Server via `http_service_hyper::serve(HTTP_SERVICE, ADDRESS);`

This crate uses the latest [Futures](https://github.com/rust-lang-nursery/futures-rs) preview, and therefore needs to be run on Rust Nightly.

## Examples

**Cargo.toml**
```
[dependencies]
http-service = "0.1.5"
futures-preview = "0.3.0-alpha.14"

[dependencies.http-service-hyper]
version = "0.1.1"
```

**main.rs**
```rust
#![feature(futures_api, async_await, await_macro, existential_type)]

use futures::future::{self, FutureObj};
use http_service::{HttpService, Response};
use std::net::{IpAddr, Ipv4Addr, SocketAddr};

struct Server {
message: Vec<u8>,
}

impl Server {
fn create(message: Vec<u8>) -> Server {
Server { message }
}

pub fn run(s: Server) {
let a = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 8080);
http_service_hyper::run(s, a);
}
}

impl HttpService for Server {
type Connection = ();
type ConnectionFuture = future::Ready<Result<(), std::io::Error>>;
type Fut = FutureObj<'static, Result<http_service::Response, std::io::Error>>;

fn connect(&self) -> Self::ConnectionFuture {
future::ok(())
}

fn respond(&self, _conn: &mut (), _req: http_service::Request) -> Self::Fut {
let message = self.message.clone();
FutureObj::new(Box::new(async move {
Ok(Response::new(http_service::Body::from(message)))
}))
}
}

fn main() {
let s = Server::create(String::from("Hello, World").into_bytes());
Server::run(s);
}
```

## License

[MIT](./LICENSE-MIT) OR [Apache-2.0](./LICENSE-APACHE)

[1]: https://img.shields.io/travis/rust-net-web/http-service.svg?style=flat-square
[2]: https://travis-ci.org/rust-net-web/http-service
42 changes: 42 additions & 0 deletions examples/simple_response.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#![feature(futures_api, async_await, await_macro, existential_type)]

use futures::future::{self, FutureObj};
use http_service::{HttpService, Response};
use std::net::{IpAddr, Ipv4Addr, SocketAddr};

struct Server {
message: Vec<u8>,
}

impl Server {
fn create(message: Vec<u8>) -> Server {
Server { message }
}

pub fn run(s: Server) {
let a = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 8080);
http_service_hyper::run(s, a);
}
}

impl HttpService for Server {
type Connection = ();
type ConnectionFuture = future::Ready<Result<(), std::io::Error>>;
type Fut = FutureObj<'static, Result<http_service::Response, std::io::Error>>;

fn connect(&self) -> Self::ConnectionFuture {
future::ok(())
}

fn respond(&self, _conn: &mut (), _req: http_service::Request) -> Self::Fut {
let message = self.message.clone();
FutureObj::new(Box::new(async move {
Ok(Response::new(http_service::Body::from(message)))
}))
}
}

fn main() {
let s = Server::create(String::from("Hello, World").into_bytes());
Server::run(s);
}
2 changes: 1 addition & 1 deletion http-service-hyper/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ version = "0.1.1"

[dependencies]
http = "0.1"
http-service = "0.1.5"
http-service = { version = "0.1.5", path = ".." }
hyper = "0.12.27"

[dependencies.futures-preview]
Expand Down
52 changes: 52 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,57 @@
//! Types and traits giving an interface between low-level http server implementations
//! and services that use them. The interface is based on the `std::futures` API.
//!
//! ## Example
//! ```no_run, rust, ignore
//! #![feature(futures_api, async_await, await_macro, existential_type)]
//!
//! use futures::{
//! future::{self, FutureObj},
//! };
//! use http_service::{HttpService, Response};
//! use std::net::{IpAddr, Ipv4Addr, SocketAddr};
//!
//! struct Server {
//! message: Vec<u8>,
//! }
//!
//! impl Server {
//! fn create(message: Vec<u8>) -> Server {
//! Server {
//! message,
//! }
//! }
//!
//! pub fn run(s: Server) {
//! let a = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 8080);
//! http_service_hyper::run(s, a);
//! }
//! }
//!
//! impl HttpService for Server {
//! type Connection = ();
//! type ConnectionFuture = future::Ready<Result<(), std::io::Error>>;
//! type Fut = FutureObj<'static, Result<http_service::Response, std::io::Error>>;
//!
//! fn connect(&self) -> Self::ConnectionFuture {
//! future::ok(())
//! }
//!
//! fn respond(&self, _conn: &mut (), _req: http_service::Request) -> Self::Fut {
//! let message = self.message.clone();
//! FutureObj::new(Box::new(
//! async move {
//! Ok(Response::new(http_service::Body::from(message)))
//! }
//! ))
//! }
//! }
//!
//! fn main() {
//! let s = Server::create(String::from("Hello, World").into_bytes());
//! Server::run(s);
//! }
//! ```

#![forbid(future_incompatible, rust_2018_idioms)]
#![deny(missing_debug_implementations, nonstandard_style)]
Expand Down