mirror of
https://github.com/icewind1991/warp-real-ip.git
synced 2026-08-02 08:14:49 +02:00
updates and warp 0.4
This commit is contained in:
parent
7b33c0d79d
commit
9a3991d243
9 changed files with 393 additions and 813 deletions
1
.envrc
Normal file
1
.envrc
Normal file
|
|
@ -0,0 +1 @@
|
|||
use flake
|
||||
17
.github/workflows/ci.yaml
vendored
Normal file
17
.github/workflows/ci.yaml
vendored
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
name: "CI"
|
||||
on:
|
||||
pull_request:
|
||||
push:
|
||||
|
||||
jobs:
|
||||
checks:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: cachix/install-nix-action@v26
|
||||
- uses: icewind1991/attic-action@v1
|
||||
with:
|
||||
name: ci
|
||||
instance: https://cache.icewind.me
|
||||
authToken: "${{ secrets.ATTIC_TOKEN }}"
|
||||
- run: nix flake check --keep-going
|
||||
33
.github/workflows/rust.yml
vendored
33
.github/workflows/rust.yml
vendored
|
|
@ -1,33 +0,0 @@
|
|||
on: [push, pull_request]
|
||||
|
||||
name: CI
|
||||
|
||||
jobs:
|
||||
check:
|
||||
name: Check
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
profile: minimal
|
||||
toolchain: stable
|
||||
override: true
|
||||
- uses: Swatinem/rust-cache@v1
|
||||
- uses: actions-rs/cargo@v1
|
||||
with:
|
||||
command: check
|
||||
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
name: Tests
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
toolchain: stable
|
||||
- uses: Swatinem/rust-cache@v1
|
||||
- uses: actions-rs/cargo@v1
|
||||
with:
|
||||
command: test
|
||||
5
.gitignore
vendored
5
.gitignore
vendored
|
|
@ -1 +1,4 @@
|
|||
/target
|
||||
.idea
|
||||
target
|
||||
result
|
||||
.direnv
|
||||
1010
Cargo.lock
generated
1010
Cargo.lock
generated
File diff suppressed because it is too large
Load diff
15
Cargo.toml
15
Cargo.toml
|
|
@ -1,19 +1,22 @@
|
|||
[package]
|
||||
name = "warp-real-ip"
|
||||
description = "Warp filter to get the \"real ip\" of the remote client"
|
||||
version = "0.2.0"
|
||||
version = "0.3.0"
|
||||
authors = ["Robin Appelman <robin@icewind.nl>"]
|
||||
edition = "2018"
|
||||
edition = "2024"
|
||||
keywords = ["warp"]
|
||||
categories = ["web-programming::http-server"]
|
||||
license = "MIT OR Apache-2.0"
|
||||
repository = "https://github.com/icewind1991/warp-real-ip"
|
||||
documentation = "https://docs.rs/warp-real-ip"
|
||||
rust-version = "1.85.0"
|
||||
|
||||
[dependencies]
|
||||
warp = { version = "0.3" }
|
||||
rfc7239 = "0.1"
|
||||
ipnetwork = "0.18"
|
||||
warp = { version = "0.4" }
|
||||
rfc7239 = "0.1.3"
|
||||
ipnetwork = "0.21"
|
||||
comma-separated = "0.1.0"
|
||||
|
||||
[dev-dependencies]
|
||||
tokio = { version = "1.0", features = ["macros"] }
|
||||
tokio = { version = "1.0", features = ["macros", "rt-multi-thread"] }
|
||||
warp = { version = "0.4", features = ["test"] }
|
||||
|
|
|
|||
107
flake.lock
generated
Normal file
107
flake.lock
generated
Normal file
|
|
@ -0,0 +1,107 @@
|
|||
{
|
||||
"nodes": {
|
||||
"crane": {
|
||||
"locked": {
|
||||
"lastModified": 1780099841,
|
||||
"narHash": "sha256-EVZd2RsbpreRUDSi9rBwPY+ZxoyMaiEBbZxxhljbaS4=",
|
||||
"owner": "ipetkov",
|
||||
"repo": "crane",
|
||||
"rev": "0532eb17955225173906d671fb36306bdeb1e2dc",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "ipetkov",
|
||||
"repo": "crane",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"flakelight": {
|
||||
"inputs": {
|
||||
"nixpkgs": [
|
||||
"nixpkgs"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1783953866,
|
||||
"narHash": "sha256-S2qmQTzeI270WnguYV6R0vXDgtekjjCB7HQI9QiqDGI=",
|
||||
"owner": "nix-community",
|
||||
"repo": "flakelight",
|
||||
"rev": "c9219d15f7d74ba690cba3b613f4ef2a08c16840",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nix-community",
|
||||
"repo": "flakelight",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"mill-scale": {
|
||||
"inputs": {
|
||||
"crane": "crane",
|
||||
"flakelight": [
|
||||
"flakelight"
|
||||
],
|
||||
"rust-overlay": "rust-overlay"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1780231986,
|
||||
"narHash": "sha256-OyafczPtzE0Xa2zl3j/KvV2+ZVYGhYQHt0MOVWtDXlY=",
|
||||
"ref": "refs/heads/main",
|
||||
"rev": "f5cbda29b945df03256bf63c22fa4cd5fa429e67",
|
||||
"revCount": 72,
|
||||
"type": "git",
|
||||
"url": "https://codeberg.org/icewind/mill-scale.git"
|
||||
},
|
||||
"original": {
|
||||
"type": "git",
|
||||
"url": "https://codeberg.org/icewind/mill-scale.git"
|
||||
}
|
||||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1783856661,
|
||||
"narHash": "sha256-ZGP04e+Q6WyQJGA9ZvI5CL6+heGQldbAG9U1T9NGvmU=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "569d578509928497eddc3fdbf94a799027050be4",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"id": "nixpkgs",
|
||||
"ref": "nixos-26.05",
|
||||
"type": "indirect"
|
||||
}
|
||||
},
|
||||
"root": {
|
||||
"inputs": {
|
||||
"flakelight": "flakelight",
|
||||
"mill-scale": "mill-scale",
|
||||
"nixpkgs": "nixpkgs"
|
||||
}
|
||||
},
|
||||
"rust-overlay": {
|
||||
"inputs": {
|
||||
"nixpkgs": [
|
||||
"mill-scale",
|
||||
"flakelight",
|
||||
"nixpkgs"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1780197589,
|
||||
"narHash": "sha256-FVCr2Ij/jKf59a4LW481eeOF6rJRreOBrVgW/aUBTrw=",
|
||||
"owner": "oxalica",
|
||||
"repo": "rust-overlay",
|
||||
"rev": "21632e942d89bf1cce4e5a63d7e58a215a0cbfcc",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "oxalica",
|
||||
"repo": "rust-overlay",
|
||||
"type": "github"
|
||||
}
|
||||
}
|
||||
},
|
||||
"root": "root",
|
||||
"version": 7
|
||||
}
|
||||
14
flake.nix
Normal file
14
flake.nix
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
{
|
||||
inputs = {
|
||||
nixpkgs.url = "nixpkgs/nixos-26.05";
|
||||
flakelight = {
|
||||
url = "github:nix-community/flakelight";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
mill-scale = {
|
||||
url = "git+https://codeberg.org/icewind/mill-scale.git";
|
||||
inputs.flakelight.follows = "flakelight";
|
||||
};
|
||||
};
|
||||
outputs = {mill-scale, ...}: mill-scale ./. {};
|
||||
}
|
||||
104
src/lib.rs
104
src/lib.rs
|
|
@ -1,3 +1,4 @@
|
|||
use comma_separated::CommaSeparatedIterator;
|
||||
use ipnetwork::IpNetwork;
|
||||
use rfc7239::{parse, Forwarded, NodeIdentifier, NodeName};
|
||||
use std::borrow::Cow;
|
||||
|
|
@ -117,106 +118,12 @@ pub fn get_forwarded_for() -> impl Filter<Extract = (Vec<IpAddr>,), Error = Infa
|
|||
.unify()
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
enum CommaSeparatedIteratorState {
|
||||
/// Start of string or after a ',' (including whitespace)
|
||||
Default,
|
||||
/// Inside a double quote
|
||||
Quoted,
|
||||
/// After escape character inside quote
|
||||
QuotedPair,
|
||||
/// Non quoted part
|
||||
Token,
|
||||
/// After closing double quote
|
||||
PostAmbleForQuoted,
|
||||
}
|
||||
|
||||
struct CommaSeparatedIterator<'a> {
|
||||
/// target
|
||||
target: &'a str,
|
||||
/// iterator
|
||||
char_indices: std::str::CharIndices<'a>,
|
||||
/// current scanner state
|
||||
state: CommaSeparatedIteratorState,
|
||||
/// start position of the last token found
|
||||
s: usize,
|
||||
}
|
||||
|
||||
impl<'a> CommaSeparatedIterator<'a> {
|
||||
pub fn new(target: &'a str) -> Self {
|
||||
Self {
|
||||
target,
|
||||
char_indices: target.char_indices(),
|
||||
state: CommaSeparatedIteratorState::Default,
|
||||
s: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Iterator for CommaSeparatedIterator<'a> {
|
||||
type Item = &'a str;
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
for (i, c) in &mut self.char_indices {
|
||||
let (next, next_state) = match (self.state, c) {
|
||||
(CommaSeparatedIteratorState::Default, '"') => {
|
||||
self.s = i;
|
||||
(None, CommaSeparatedIteratorState::Quoted)
|
||||
}
|
||||
(CommaSeparatedIteratorState::Default, ' ' | '\t') => {
|
||||
(None, CommaSeparatedIteratorState::Default)
|
||||
}
|
||||
(CommaSeparatedIteratorState::Default, ',') => (
|
||||
Some(Some(&self.target[i..i])),
|
||||
CommaSeparatedIteratorState::Default,
|
||||
),
|
||||
(CommaSeparatedIteratorState::Default, _) => {
|
||||
self.s = i;
|
||||
(None, CommaSeparatedIteratorState::Token)
|
||||
}
|
||||
(CommaSeparatedIteratorState::Quoted, '"') => (
|
||||
Some(Some(&self.target[self.s..i + 1])),
|
||||
CommaSeparatedIteratorState::PostAmbleForQuoted,
|
||||
),
|
||||
(CommaSeparatedIteratorState::Quoted, '\\') => {
|
||||
(None, CommaSeparatedIteratorState::QuotedPair)
|
||||
}
|
||||
(CommaSeparatedIteratorState::QuotedPair, _) => {
|
||||
(None, CommaSeparatedIteratorState::Quoted)
|
||||
}
|
||||
(CommaSeparatedIteratorState::Token, ',') => (
|
||||
Some(Some(&self.target[self.s..i])),
|
||||
CommaSeparatedIteratorState::Default,
|
||||
),
|
||||
(CommaSeparatedIteratorState::PostAmbleForQuoted, ',') => {
|
||||
(None, CommaSeparatedIteratorState::Default)
|
||||
}
|
||||
(current_state, _) => (None, current_state),
|
||||
};
|
||||
self.state = next_state;
|
||||
if let Some(next) = next {
|
||||
return next;
|
||||
}
|
||||
}
|
||||
match self.state {
|
||||
CommaSeparatedIteratorState::Default
|
||||
| CommaSeparatedIteratorState::PostAmbleForQuoted => None,
|
||||
CommaSeparatedIteratorState::Quoted
|
||||
| CommaSeparatedIteratorState::QuotedPair
|
||||
| CommaSeparatedIteratorState::Token => {
|
||||
self.state = CommaSeparatedIteratorState::Default;
|
||||
Some(&self.target[self.s..])
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
enum EscapeState {
|
||||
Normal,
|
||||
Escaped,
|
||||
}
|
||||
|
||||
fn maybe_quoted(x: &str) -> Cow<str> {
|
||||
fn maybe_quoted(x: &str) -> Cow<'_, str> {
|
||||
let mut i = x.chars();
|
||||
if i.next() == Some('"') {
|
||||
let mut s = String::with_capacity(x.len());
|
||||
|
|
@ -278,8 +185,10 @@ mod tests {
|
|||
#[test]
|
||||
fn test_comma_separated_iterator() {
|
||||
assert_eq!(
|
||||
vec!["abc", "def", "ghi", "jkl ", "mno", "pqr"],
|
||||
CommaSeparatedIterator::new("abc,def, ghi,\tjkl , mno,\tpqr").collect::<Vec<&str>>()
|
||||
vec!["abc", "def", "ghi", "jkl", "mno", "pqr"],
|
||||
CommaSeparatedIterator::new("abc,def, ghi,\tjkl , mno,\tpqr")
|
||||
.map(str::trim)
|
||||
.collect::<Vec<&str>>()
|
||||
);
|
||||
assert_eq!(
|
||||
vec![
|
||||
|
|
@ -294,6 +203,7 @@ mod tests {
|
|||
CommaSeparatedIterator::new(
|
||||
"abc,\"def\", \"ghi\",\t\"jkl\" , \"mno\",\tpqr, \"abc, def\""
|
||||
)
|
||||
.map(str::trim)
|
||||
.collect::<Vec<&str>>()
|
||||
);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue