1 unstable release
0.1.0 | Nov 17, 2023 |
---|
#4 in #ha-proxy
283 downloads per month
Used in rs-proxy
69KB
1.5K
SLoC
proxy-header
This crate provides a decoder and encoder for the HAProxy PROXY protocol, which is used to preserve original client connection information when proxying TCP connections for protocols that do not support this higher up in the stack.
The PROXY protocol is supported by many load balancers and proxies, including HAProxy, Amazon ELB, Amazon ALB, and others.
This crate implements the entire specification, except parsing the AF_UNIX
address
type (the header is validated / parsed, but the address is not decoded or exposed in
the API).
Acknowledgements
This crate started as a fork of the proxy-protocol
crate, but has since been rewritten from scratch.
License
This crate is licensed under the MIT license. See the LICENSE
file for details.
lib.rs
:
PROXY protocol decoder and encoder
This crate provides a decoder and encoder for the PROXY protocol, which is used to preserve original client connection information when proxying TCP connections for protocols that do not support this higher up in the stack.
The PROXY protocol is supported by many load balancers and proxies, including HAProxy, Amazon ELB, Amazon ALB, and others.
This crate implements the entire specification, except parsing the AF_UNIX
address
type (the header is validated / parsed, but the address is not decoded or exposed in
the API).
Usage
Decoding
To decode a PROXY protocol header from an existing buffer, use ProxyHeader::parse
:
use proxy_header::{ProxyHeader, ParseConfig};
let buf = b"PROXY TCP6 2001:db8:1::1 2001:db8:2::1 52953 25\r\nHELO example.com\r\n";
let (header, len) = ProxyHeader::parse(buf, ParseConfig::default())?;
match header.proxied_address() {
Some(addr) => {
println!("Proxied connection from {} to {}", addr.source, addr.destination);
}
None => {
println!("Local connection (e.g. healthcheck)");
}
}
println!("Client sent: {:?}", &buf[len..]);
In addition to the address information, the PROXY protocol version 2 header can contain
additional information in the form of TLV (type-length-value) fields. These can be accessed
through the ProxyHeader::tlvs
iterator or through convenience accessors such as ProxyHeader::authority
.
See [Tlv
] for more information on the different types of TLV fields.
use proxy_header::Tlv;
for tlv in header.tlvs() {
match tlv? { // TLV can be malformed
Tlv::UniqueId(v) => {
println!("Unique connection ID: {:?}", v);
}
Tlv::Authority(v) => {
println!("Authority string (SNI): {:?}", v);
}
_ => {}
}
}
See also [io
] module for a stream wrapper that can automatically parse PROXY protocol.
Encoding
To encode a PROXY protocol header, use ProxyHeader::encode_v1
for version 1 headers and
ProxyHeader::encode_v2
for version 2 headers.
use proxy_header::{ProxyHeader, ProxiedAddress, Protocol};
let addrs = ProxiedAddress::stream(
"[2001:db8::1:1]:51234".parse().unwrap(),
"[2001:db8::2:1]:443".parse().unwrap()
);
let header = ProxyHeader::with_address(addrs);
let mut buf = [0u8; 1024];
let len = header.encode_to_slice_v2(&mut buf).unwrap();
Dependencies
~0–1.2MB
~20K SLoC