Merge pull request 'Improve the documentation and bug fixes' (#3) from improve-docs into main
continuous-integration/drone/push Build is passing Details

Reviewed-on: #3
This commit is contained in:
Dorian 2024-02-24 20:41:15 -05:00
commit 72523777c2
5 changed files with 106 additions and 18 deletions

View File

@ -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

View File

@ -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."

View File

@ -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}

View File

@ -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"
}
}
```

View File

@ -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();