Compare commits
14 Commits
6775667f80
...
72523777c2
Author | SHA1 | Date |
---|---|---|
Dorian | 72523777c2 | |
Dorian | 83b4e44b5f | |
Dorian | 01063534ec | |
Dorian | 2cee5651e3 | |
Dorian | 780ab23310 | |
Dorian | f14963a2c4 | |
Dorian | 762186ea2f | |
Dorian | aca5a57460 | |
Dorian | 65898987a6 | |
Dorian | b991c30953 | |
Dorian | b5a2693119 | |
Dorian | e89e1a394e | |
Dorian | 31164bc3af | |
Dorian | f2e5c0e723 |
|
@ -36,13 +36,16 @@ steps:
|
||||||
registry: code.birch-tree.net
|
registry: code.birch-tree.net
|
||||||
repo: code.birch-tree.net/dorian/mirror-server
|
repo: code.birch-tree.net/dorian/mirror-server
|
||||||
tags:
|
tags:
|
||||||
- 0.3.0
|
- 0.3.1
|
||||||
- latest
|
- latest
|
||||||
cache_from:
|
cache_from:
|
||||||
- code.birch-tree.net/dorian/mirror-server:latest
|
- code.birch-tree.net/dorian/mirror-server:latest
|
||||||
- code.birch-tree.net/dorian/mirror-server:build
|
- code.birch-tree.net/dorian/mirror-server:build
|
||||||
depends_on:
|
depends_on:
|
||||||
- test
|
- test
|
||||||
|
when:
|
||||||
|
ref:
|
||||||
|
- refs/tags/*
|
||||||
|
|
||||||
- name: create-debian-package
|
- name: create-debian-package
|
||||||
image: code.birch-tree.net/dorian/mirror-server:build
|
image: code.birch-tree.net/dorian/mirror-server:build
|
||||||
|
@ -54,6 +57,9 @@ steps:
|
||||||
from_secret: gitea-release-password
|
from_secret: gitea-release-password
|
||||||
depends_on:
|
depends_on:
|
||||||
- test
|
- test
|
||||||
|
when:
|
||||||
|
ref:
|
||||||
|
- refs/tags/*
|
||||||
|
|
||||||
image_pull_secrets:
|
image_pull_secrets:
|
||||||
- docker-config
|
- docker-config
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "mirror-server"
|
name = "mirror-server"
|
||||||
version = "0.3.0"
|
version = "0.3.1"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
authors = ["Dorian Pula <dorian.pula@amber-penguin-software.ca>"]
|
authors = ["Dorian Pula <dorian.pula@amber-penguin-software.ca>"]
|
||||||
description = "A simple server for mirror HTTP requests for testing."
|
description = "A simple server for mirror HTTP requests for testing."
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
FROM rust:1.76 AS BUILD
|
FROM rust:1.76-buster AS BUILD
|
||||||
|
|
||||||
ENV APP_NAME=mirror-server
|
ENV APP_NAME=mirror-server
|
||||||
ENV APP_HOME=/srv/${APP_NAME}
|
ENV APP_HOME=/srv/${APP_NAME}
|
||||||
|
@ -19,7 +19,8 @@ RUN cargo build \
|
||||||
&& rm src/*.rs
|
&& rm src/*.rs
|
||||||
|
|
||||||
# Bring in the source
|
# Bring in the source
|
||||||
COPY ["src", "./src/"]
|
COPY ["./src/*", "./src/"]
|
||||||
|
COPY ["README.md", "LICENSE", "./"]
|
||||||
|
|
||||||
# Build the example API.
|
# Build the example API.
|
||||||
RUN cargo build --release
|
RUN cargo build --release
|
||||||
|
@ -31,8 +32,5 @@ ENV APP_NAME=mirror-server
|
||||||
ENV APP_HOME=/srv/${APP_NAME}
|
ENV APP_HOME=/srv/${APP_NAME}
|
||||||
RUN apt update
|
RUN apt update
|
||||||
|
|
||||||
RUN mkdir -p ${APP_HOME}
|
|
||||||
WORKDIR ${APP_HOME}
|
|
||||||
|
|
||||||
COPY --from=BUILD ${APP_HOME}/target/release/${APP_NAME} /usr/local/bin/
|
COPY --from=BUILD ${APP_HOME}/target/release/${APP_NAME} /usr/local/bin/
|
||||||
CMD ${APP_NAME}
|
CMD ${APP_NAME}
|
76
README.md
76
README.md
|
@ -1,6 +1,7 @@
|
||||||
# mirror-server
|
# mirror-server
|
||||||
|
|
||||||
A simple server for mirroring HTTP requests for testing.
|
A simple server for mirroring HTTP requests for testing. It is optimized for
|
||||||
|
working with REST API JSON calls, and catching headers.
|
||||||
|
|
||||||
[![Build Status](https://ci.birch-tree.net/api/badges/dorian/mirror-server/status.svg)](https://ci.birch-tree.net/dorian/mirror-server)
|
[![Build Status](https://ci.birch-tree.net/api/badges/dorian/mirror-server/status.svg)](https://ci.birch-tree.net/dorian/mirror-server)
|
||||||
|
|
||||||
|
@ -13,25 +14,78 @@ A simple server for mirroring HTTP requests for testing.
|
||||||
* Create a DEB package:
|
* Create a DEB package:
|
||||||
* Install cargo-deb: `cargo install cargo-deb`
|
* Install cargo-deb: `cargo install cargo-deb`
|
||||||
* Create the DEB package: `cargo deb`
|
* Create the DEB package: `cargo deb`
|
||||||
* Faster builds using [cargo-watch](https://watchexec.github.io/#cargo-watch): `cargo watch -x run`
|
* Faster builds using [`cargo-watch`](https://watchexec.github.io/#cargo-watch): `cargo watch -x run`
|
||||||
|
* Installing the binary locally from source: `cargo install --path .`
|
||||||
|
|
||||||
## Install
|
## Install
|
||||||
|
|
||||||
|
`mirror-server` is installable either by a local Cargo install or a Debian
|
||||||
|
package. Additionally `mirror-server` can be run as a Docker container using
|
||||||
|
the latest (or tagged) release.
|
||||||
|
|
||||||
|
### Docker Image
|
||||||
|
|
||||||
|
Run via Docker using:
|
||||||
|
|
||||||
|
```console
|
||||||
|
$ docker run -p 8080:8080 code.birch-tree.net/dorian/mirror-server:latest
|
||||||
|
```
|
||||||
|
|
||||||
|
### Debian Package
|
||||||
|
|
||||||
Download the DEB file, and install it:
|
Download the DEB file, and install it:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
VERSION=0.3.0
|
VERSION=0.3.1
|
||||||
REPO_URL=https://code.birch-tree.net/api/packages/dorian/generic/mirror-server/
|
REPO_URL=https://code.birch-tree.net/api/packages/dorian/generic/mirror-server/
|
||||||
curl "${REPO_URL}/${VERSION}/mirror-server_${VERSION}_amd64.deb"
|
curl "${REPO_URL}/${VERSION}/mirror-server_${VERSION}_amd64.deb"
|
||||||
sudo dpkg -i "mirror-server-${VERSION}_amd64.deb"
|
sudo dpkg -i "mirror-server-${VERSION}_amd64.deb"
|
||||||
```
|
```
|
||||||
|
|
||||||
## TODO
|
Afterward you can run using `mirror-server`
|
||||||
|
|
||||||
* [x] Migrate actix to axum for easier maintainability.
|
## Usage
|
||||||
* [x] Add mirroring of JSON request.
|
|
||||||
* [x] Add logging to server.
|
You can get all the options that `mirror-server` supports by running it with
|
||||||
* [x] Create Docker image for mirror-server for easier distribution.
|
the help option `--help` or `-h`:
|
||||||
* [x] Add publishing of DEB and Docker image to DroneCI.
|
|
||||||
* [ ] Add documentation to the API.
|
```console
|
||||||
* [ ] Publish crate on <https://crates.io/>.
|
$ mirror-server --help
|
||||||
|
A simple server for mirror HTTP requests for testing.
|
||||||
|
|
||||||
|
Usage: mirror-server [OPTIONS]
|
||||||
|
|
||||||
|
Options:
|
||||||
|
-p, --port <PORT> Port to run on [default: 8080]
|
||||||
|
-i, --ips <IPS> Listen to IP mask [default: 0.0.0.0]
|
||||||
|
-h, --help Print help
|
||||||
|
-V, --version Print version
|
||||||
|
```
|
||||||
|
|
||||||
|
After starting the server, you can send requests to it. Using `curl` you
|
||||||
|
can send `mirror-server` JSON requests:
|
||||||
|
|
||||||
|
```console
|
||||||
|
$ curl -s -X PUT -D '{"hello": "world"}' -H 'Content-Type: application/json' \
|
||||||
|
http://localhost:8080/api/testing | jq .
|
||||||
|
```
|
||||||
|
|
||||||
|
And `mirror-server` responds to requests with JSON responses:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"method": "PUT",
|
||||||
|
"path": "/api/testing",
|
||||||
|
"host": "localhost:8180",
|
||||||
|
"headers": {
|
||||||
|
"accept": "*/*",
|
||||||
|
"content-length": "18",
|
||||||
|
"content-type": "application/json",
|
||||||
|
"host": "localhost:8080",
|
||||||
|
"user-agent": "curl/7.68.0"
|
||||||
|
},
|
||||||
|
"body": {
|
||||||
|
"hello": "world"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
30
src/main.rs
30
src/main.rs
|
@ -1,3 +1,5 @@
|
||||||
|
#![doc = include_str!("../README.md")]
|
||||||
|
|
||||||
use axum::{
|
use axum::{
|
||||||
extract::{Host, Json, OriginalUri},
|
extract::{Host, Json, OriginalUri},
|
||||||
http::{header::HeaderMap, Method},
|
http::{header::HeaderMap, Method},
|
||||||
|
@ -10,6 +12,11 @@ use std::collections::BTreeMap;
|
||||||
use tower_http::trace;
|
use tower_http::trace;
|
||||||
use tracing::{info, warn, Level};
|
use tracing::{info, warn, Level};
|
||||||
|
|
||||||
|
|
||||||
|
/// CLI arguments used by the [`Parser`].
|
||||||
|
///
|
||||||
|
/// Creates the usage and version information that is standard in a CLI
|
||||||
|
/// utility.
|
||||||
#[derive(Parser)]
|
#[derive(Parser)]
|
||||||
#[command(author, version, about, long_about = None)]
|
#[command(author, version, about, long_about = None)]
|
||||||
struct CliArgs {
|
struct CliArgs {
|
||||||
|
@ -22,16 +29,34 @@ struct CliArgs {
|
||||||
ips: String,
|
ips: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The response consisting of the echoed request to the mirror-server.
|
||||||
#[derive(Serialize, Deserialize, Debug, PartialEq)]
|
#[derive(Serialize, Deserialize, Debug, PartialEq)]
|
||||||
struct EchoResponse {
|
struct EchoResponse {
|
||||||
|
/// The [`Method`] used in the request.
|
||||||
method: String,
|
method: String,
|
||||||
|
/// The path used in the request.
|
||||||
path: String,
|
path: String,
|
||||||
|
/// The original schema, hostname and port of the request.
|
||||||
host: String,
|
host: String,
|
||||||
|
/// The headers in the request.
|
||||||
headers: BTreeMap<String, String>,
|
headers: BTreeMap<String, String>,
|
||||||
|
/// (Optional) The JSON body in the request.
|
||||||
#[serde(skip_serializing_if = "Option::is_none")]
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
body: Option<Value>,
|
body: Option<Value>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// [`Handler`](axum::handler) for responding with a break-down of the captured request.
|
||||||
|
///
|
||||||
|
/// Captures the request and responds with a JSON response of the elements of the request.
|
||||||
|
///
|
||||||
|
/// ## Arguments
|
||||||
|
/// * `method` - The HTTP [`Method`] used for the request. i.e. `GET`, `POST`, `PATCH`, etc.
|
||||||
|
/// * `original_uri` - The URI used for the request.
|
||||||
|
/// * `host` - The hostname of the request.
|
||||||
|
/// * `header_map` - A map with the headers used during the request.
|
||||||
|
/// * `body` - An optional JSON body, if it is past in to the request.
|
||||||
|
/// Requires a header of `Content-Type: application/json` and a body passed in the request.
|
||||||
|
///
|
||||||
async fn echo_request(
|
async fn echo_request(
|
||||||
method: Method,
|
method: Method,
|
||||||
original_uri: OriginalUri,
|
original_uri: OriginalUri,
|
||||||
|
@ -67,6 +92,10 @@ async fn echo_request(
|
||||||
Json(response)
|
Json(response)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Create a [`Router`] to handling capture all HTTP requests to the server.
|
||||||
|
///
|
||||||
|
/// Wires up a default catch-all route for the application. Also adds the tracing infrastructure
|
||||||
|
/// to capture requests.
|
||||||
fn app() -> Router {
|
fn app() -> Router {
|
||||||
Router::new().fallback(echo_request).layer(
|
Router::new().fallback(echo_request).layer(
|
||||||
trace::TraceLayer::new_for_http()
|
trace::TraceLayer::new_for_http()
|
||||||
|
@ -75,6 +104,7 @@ fn app() -> Router {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The main application starts the mirror-server application.
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn main() {
|
async fn main() {
|
||||||
let cli_args = CliArgs::parse();
|
let cli_args = CliArgs::parse();
|
||||||
|
|
Loading…
Reference in New Issue