[][src]Crate sozu_lib

This library provides tools to build a HTTP proxy

It handles network polling, HTTP parsing, TLS in a fast single threaded event loop.

It is designed to receive configuration changes at runtime instead of reloading from a file regularly. The event loop runs in its own thread and receives commands through a message queue.

To create a HTTP proxy, you first need to create a HttpProxyConfiguration structure (there are configuration structures for the HTTPS and TCP proxies too).

This example is not tested
let config = proxy::HttpProxyConfiguration {
  front: "198.51.100.0:80".parse().unwrap(),
  ..Default::default()
};

Then create the required elements to communicate with the proxy thread, and launch the thread:

This example is not tested
let config = proxy::HttpProxyConfiguration {
  front: "198.51.100.0:80".parse().unwrap(),
  ..Default::default()
};

let (mut command, channel) = Channel::generate(1000, 10000).expect("should create a channel");

let jg            = thread::spawn(move || {
   network::http::start(config, channel);
});

The tx, rx channel here is a mio channel through which the proxy will receive its orders, and it will use the (sender,rec) one to send acknowledgements and various data.

Once the thread is launched, the proxy will start its event loop and handle events on the listening interface and port specified in the configuration object. Since no applications to proxy for were specified, it will receive the connections, parse the request, then send a default (but configurable) answer.

This example is not tested
let http_front = proxy::HttpFront {
  app_id:     String::from("test"),
  hostname:   String::from("example.com"),
  path_begin: String::from("/")
};
let http_backend = proxy::Backend {
  app_id:     String::from("test"),
  ip_address: String::from("192.0.2.1"),
  port:       8080
};

command.write_message(&proxy::ProxyRequest {
  id:    String::from("ID_ABCD"),
  order: proxy::ProxyRequestData::AddHttpFront(http_front)
));

command.write_message(&proxy::ProxyRequest {
  id:    String::from("ID_EFGH"),
  order: proxy::ProxyRequestData::AddBackend(http_backend)
));

println!("HTTP -> {:?}", command.read_message());
println!("HTTP -> {:?}", command.read_message());

An application is identified by its app_id, a string that will be shared between one or multiple "fronts", and one or multiple "backends".

A "front" is a way to recognize a request and match it to an app_id, depending on the hostname and the beginning of the URL path.

A backend corresponds to one backend server, indicated by its IP and port.

An application can have multiple backend servers, and they can be added or removed while the proxy is running. If a backend is removed from the configuration while the proxy is handling a request to that server, it will finish that request and stop sending new traffic to that server.

The fronts and backends are specified with messages sent through the communication channels with the proxy event loop. Once the configuration options are added to the proxy's state, it will send back an acknowledgement message.

Here is the complete example for reference:

This example is not tested
#[macro_use] extern crate log;
extern crate env_logger;
extern crate sozu_lib as sozu;
extern crate sozu_command_lib as sozu_command;
extern crate openssl;
extern crate mio;

use std::thread;
use std::sync::mpsc;
use sozu_command::messages;
use sozu_command::channel::Channel;
use sozu::network;

fn main() {
  env_logger::init().unwrap();
  info!("starting up");

  let config = proxy::HttpProxyConfiguration {
    front: "198.51.100.0:80".parse().unwrap(),
    ..Default::default()
  };

  let (mut command, channel) = Channel::generate(1000, 10000).expect("should create a channel");

  let jg            = thread::spawn(move || {
     network::http::start(config, channel);
  });

  let http_front = proxy::HttpFront {
    app_id:     String::from("test"),
    hostname:   String::from("example.com"),
    path_begin: String::from("/")
  };
  let http_backend = proxy::Backend {
    app_id:     String::from("test"),
    ip_address: String::from("192.0.2.1"),
    port:       8080
  };

  command.write_message(&proxy::ProxyRequest {
    id:    String::from("ID_ABCD"),
    order: proxy::ProxyRequestData::AddHttpFront(http_front)
  ));

  command.write_message(&proxy::ProxyRequest {
    id:    String::from("ID_EFGH"),
    order: proxy::ProxyRequestData::AddBackend(http_backend)
  ));

  println!("HTTP -> {:?}", command.read_message());
  println!("HTTP -> {:?}", command.write_message());

  let _ = jg.join();
  info!("good bye");
}

Modules

backends
buffer_queue
features
http
https_rustls
load_balancing
metrics
pool
protocol
retry
server
socket
tcp
trie
util

Macros

assert_size
count
decr
empty
gauge
gauge_add
incr
record_backend_metrics
take_while1_complete
take_while_complete
time
unwrap_msg

Structs

Backend
CloseResult
LogDuration
Readiness
SessionMetrics

Enums

AcceptError
BackendConnectAction
BackendConnectionStatus
BackendStatus
ConnectionError
Protocol
RequiredEvents
SessionResult
SocketType

Traits

ProxyConfiguration
ProxySession

Functions

display_unix_ready
unix_ready_to_string

Type Definitions

AppId