mirror of
https://github.com/DefectingCat/candy
synced 2025-07-15 08:41:35 +00:00
Compare commits
3 Commits
25ff344474
...
47d8482ba6
Author | SHA1 | Date | |
---|---|---|---|
47d8482ba6 | |||
d59b02fae2 | |||
fffcee1d50 |
15
CHANGELOG.md
15
CHANGELOG.md
@ -1,13 +1,20 @@
|
||||
# Changelog
|
||||
|
||||
## 0.2.1
|
||||
## 0.2.2 - 2025-07-03
|
||||
|
||||
Features:
|
||||
|
||||
- Support lua script
|
||||
- Add max body size limit
|
||||
|
||||
## 0.2.1 - 2025-06-24
|
||||
|
||||
Features:
|
||||
|
||||
- `auto-index` support
|
||||
- Stable rust version
|
||||
|
||||
## 0.2.0
|
||||
## 0.2.0 - 2025-06-17
|
||||
|
||||
Features:
|
||||
|
||||
@ -15,7 +22,7 @@ Features:
|
||||
- Refactor with axum
|
||||
- SSL support
|
||||
|
||||
## 0.1.1
|
||||
## 0.1.1 - 2024-07-02
|
||||
|
||||
Features:
|
||||
|
||||
@ -35,7 +42,7 @@ Fix:
|
||||
- Custom error page
|
||||
- Config tests
|
||||
|
||||
## 0.1.0
|
||||
## 0.1.0 - 2024-05-13
|
||||
|
||||
Features:
|
||||
|
||||
|
23
Cargo.lock
generated
23
Cargo.lock
generated
@ -396,7 +396,7 @@ checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a"
|
||||
|
||||
[[package]]
|
||||
name = "candy"
|
||||
version = "0.2.1"
|
||||
version = "0.2.2"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"axum",
|
||||
@ -1217,6 +1217,17 @@ dependencies = [
|
||||
"hashbrown 0.15.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "io-uring"
|
||||
version = "0.7.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b86e202f00093dcba4275d4636b93ef9dd75d025ae560d2521b45ea28ab49013"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"cfg-if",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ipnet"
|
||||
version = "2.11.0"
|
||||
@ -1797,9 +1808,9 @@ checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c"
|
||||
|
||||
[[package]]
|
||||
name = "reqwest"
|
||||
version = "0.12.20"
|
||||
version = "0.12.22"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "eabf4c97d9130e2bf606614eb937e86edac8292eaa6f422f995d7e8de1eb1813"
|
||||
checksum = "cbc931937e6ca3a06e3b6c0aa7841849b160a90351d6ab467a8b9b9959767531"
|
||||
dependencies = [
|
||||
"async-compression",
|
||||
"base64 0.22.1",
|
||||
@ -2258,17 +2269,19 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tokio"
|
||||
version = "1.45.1"
|
||||
version = "1.46.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "75ef51a33ef1da925cea3e4eb122833cb377c61439ca401b770f54902b806779"
|
||||
checksum = "1140bb80481756a8cbe10541f37433b459c5aa1e727b4c020fbfebdc25bf3ec4"
|
||||
dependencies = [
|
||||
"backtrace",
|
||||
"bytes",
|
||||
"io-uring",
|
||||
"libc",
|
||||
"mio",
|
||||
"parking_lot",
|
||||
"pin-project-lite",
|
||||
"signal-hook-registry",
|
||||
"slab",
|
||||
"socket2",
|
||||
"tokio-macros",
|
||||
"windows-sys 0.52.0",
|
||||
|
@ -2,14 +2,14 @@
|
||||
|
||||
[package]
|
||||
name = "candy"
|
||||
version = "0.2.1"
|
||||
version = "0.2.2"
|
||||
edition = "2024"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
# core
|
||||
tokio = { version = "1.45.1", features = ["full"] }
|
||||
tokio = { version = "1.46.0", features = ["full"] }
|
||||
tokio-util = "0.7.15"
|
||||
tokio-rustls = "0.26.2"
|
||||
hyper = { version = "1.6.0", features = ["full"] }
|
||||
@ -23,7 +23,7 @@ axum-extra = { version = "0.10.1", features = ["typed-header"] }
|
||||
axum-server = { version = "0.7.2", features = ["tls-rustls"] }
|
||||
tower = { version = "0.5.2", features = ["full"] }
|
||||
tower-http = { version = "0.6.6", features = ["full"] }
|
||||
reqwest = { version = "0.12.20", features = [
|
||||
reqwest = { version = "0.12.22", features = [
|
||||
# "rustls-tls",
|
||||
"native-tls-vendored",
|
||||
"zstd",
|
||||
|
15
README.md
15
README.md
@ -1,11 +1,26 @@
|
||||
# Candy
|
||||
|
||||
<img src="./assets/candy-transparent.png" width="200px">
|
||||
|
||||
A tiny web server built with rust.
|
||||
|
||||
[](https://deps.rs/repo/github/DefectingCat/candy)
|
||||

|
||||

|
||||
|
||||
## Features
|
||||
|
||||
- Simple and easy to use
|
||||
- Single binary
|
||||
- Supports SSL
|
||||
- HTTP 2 support
|
||||
- Supports lua script
|
||||
- List directory
|
||||
|
||||
## TODO
|
||||
|
||||
[TODO.md](./TODO.md)
|
||||
|
||||
## Changelog
|
||||
|
||||
[CHANGELOG.md](./CHANGELOG.md)
|
||||
|
BIN
assets/candy-transparent.png
Normal file
BIN
assets/candy-transparent.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 544 KiB |
BIN
assets/candy.png
Normal file
BIN
assets/candy.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.6 MiB |
@ -6,4 +6,78 @@ title: 配置文件
|
||||
|
||||
## 配置文件
|
||||
|
||||
Candy 遵循配置文件进行配置。
|
||||
Candy 遵循配置文件进行配置。配置文件的格式为 TOML。
|
||||
|
||||
### 虚拟主机
|
||||
|
||||
顶层配置为虚拟主机 `host`,可以配置多个虚拟主机。
|
||||
|
||||
```toml
|
||||
[[host]]
|
||||
ip = "0.0.0.0"
|
||||
port = 80
|
||||
# Connection timeout
|
||||
timeout = 15
|
||||
# 只用当 ssl = true 时,才会读取证书和密钥,并开启 SSL 支持
|
||||
# ssl = true
|
||||
# Self sign a certificate
|
||||
# sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ./html/selfsigned.key -out ./html/selfsigned.crt
|
||||
certificate = "./html/selfsigned.crt"
|
||||
certificate_key = "./html/selfsigned.key"
|
||||
```
|
||||
|
||||
#### 自定义 HTTP 相应头
|
||||
|
||||
每个虚拟主机都可以配置自定义相应头
|
||||
|
||||
TODO
|
||||
|
||||
### 路由
|
||||
|
||||
每个虚拟主机下都可以配置多个路由。配置字段为 `route`。
|
||||
|
||||
每个路由支持三种配置:
|
||||
|
||||
- 静态文件托管
|
||||
- 反向代理
|
||||
- Lua 脚本
|
||||
|
||||
#### 静态文件托管
|
||||
|
||||
```toml
|
||||
[[host.route]]
|
||||
# 路由地址
|
||||
location = "/"
|
||||
# 静态文件根目录
|
||||
root = "html"
|
||||
# 当使用静态文件根目录时,使用下面的字段作为主页
|
||||
index = ["index.html"]
|
||||
# 列出目录
|
||||
auto_index = true
|
||||
```
|
||||
|
||||
#### 反向代理
|
||||
|
||||
```toml
|
||||
[[host]]
|
||||
ip = "0.0.0.0"
|
||||
port = 8080
|
||||
[[host.route]]
|
||||
location = "/"
|
||||
proxy_pass = "http://localhost:3000/"
|
||||
# Timeout for connect to upstream
|
||||
proxy_timeout = 10
|
||||
# Client request max body size (bytes)
|
||||
max_body_size = 2048
|
||||
```
|
||||
|
||||
#### Lua 脚本
|
||||
|
||||
```toml
|
||||
[[host]]
|
||||
ip = "0.0.0.0"
|
||||
port = 8081
|
||||
[[host.route]]
|
||||
location = "/"
|
||||
lua_script = "html/index.lua"
|
||||
```
|
||||
|
@ -23,3 +23,11 @@ Options:
|
||||
-h, --help Print help
|
||||
-V, --version Print version
|
||||
```
|
||||
|
||||
只需要一个可执行文件和一个配置文件,就可以快速部署一个 HTTP 服务器。
|
||||
|
||||
```bash
|
||||
❯ ./target/release/candy -c config.toml
|
||||
```
|
||||
|
||||
`-c` 可以省略,当省略时,默认使用当前目录下的 `config.toml` 文件。
|
||||
|
@ -5,9 +5,10 @@ import { themes as prismThemes } from 'prism-react-renderer';
|
||||
const config: Config = {
|
||||
title: 'Candy',
|
||||
tagline: 'Tiny http web server',
|
||||
favicon: 'img/favicon.ico',
|
||||
favicon: 'img/candy-transparent.png',
|
||||
|
||||
future: {
|
||||
v4: true,
|
||||
experimental_faster: true,
|
||||
},
|
||||
|
||||
@ -66,8 +67,8 @@ const config: Config = {
|
||||
navbar: {
|
||||
title: 'RUA',
|
||||
logo: {
|
||||
alt: 'My Site Logo',
|
||||
src: 'img/logo.svg',
|
||||
alt: 'Candy Logo',
|
||||
src: 'img/candy-transparent.png',
|
||||
},
|
||||
items: [
|
||||
{
|
||||
|
@ -45,7 +45,7 @@
|
||||
},
|
||||
"theme.colorToggle.ariaLabel": {
|
||||
"message": "Switch between dark and light mode (currently {mode})",
|
||||
"description": "The ARIA label for the navbar color mode toggle"
|
||||
"description": "The ARIA label for the color mode toggle"
|
||||
},
|
||||
"theme.colorToggle.ariaLabel.mode.dark": {
|
||||
"message": "dark mode",
|
||||
@ -309,5 +309,17 @@
|
||||
"theme.tags.tagsPageTitle": {
|
||||
"message": "Tags",
|
||||
"description": "The title of the tag list page"
|
||||
},
|
||||
"theme.colorToggle.ariaLabel.mode.system": {
|
||||
"message": "system mode",
|
||||
"description": "The name for the system color mode"
|
||||
},
|
||||
"theme.navbar.mobileDropdown.collapseButton.expandAriaLabel": {
|
||||
"message": "Expand the dropdown",
|
||||
"description": "The ARIA label of the button to expand the mobile dropdown navbar item"
|
||||
},
|
||||
"theme.navbar.mobileDropdown.collapseButton.collapseAriaLabel": {
|
||||
"message": "Collapse the dropdown",
|
||||
"description": "The ARIA label of the button to collapse the mobile dropdown navbar item"
|
||||
}
|
||||
}
|
||||
|
@ -7,3 +7,79 @@ title: Config File
|
||||
## Config File
|
||||
|
||||
Candy follows the config file to configure.
|
||||
|
||||
### Virtual Host
|
||||
|
||||
The top level configuration is the virtual host `host`, and can configure multiple virtual hosts.
|
||||
|
||||
```toml
|
||||
[[host]]
|
||||
ip = "0.0.0.0"
|
||||
port = 80
|
||||
# Connection timeout
|
||||
timeout = 15
|
||||
# Only read certificate and key when ssl = true, and enable SSL support
|
||||
# ssl = true
|
||||
# Self sign a certificate
|
||||
# sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ./html/selfsigned.key -out ./html/selfsigned.crt
|
||||
certificate = "./html/selfsigned.crt"
|
||||
certificate_key = "./html/selfsigned.key"
|
||||
```
|
||||
|
||||
#### Custom HTTP Response Header
|
||||
|
||||
Each virtual host can configure custom response header.
|
||||
|
||||
TODO
|
||||
|
||||
### Route
|
||||
|
||||
Each virtual host can configure multiple routes. The configuration field is `route`.
|
||||
|
||||
Each route supports three configurations:
|
||||
|
||||
- Static file hosting
|
||||
- Reverse proxy
|
||||
- Lua script
|
||||
|
||||
#### Static File Hosting
|
||||
|
||||
```toml
|
||||
[[host.route]]
|
||||
# Route location
|
||||
location = "/"
|
||||
# Static file root
|
||||
# or proxy_pass
|
||||
# or redirect
|
||||
root = "html"
|
||||
# Only use for root field
|
||||
index = ["index.html"]
|
||||
# List directory
|
||||
auto_index = true
|
||||
```
|
||||
|
||||
#### Reverse Proxy
|
||||
|
||||
```toml
|
||||
[[host]]
|
||||
ip = "0.0.0.0"
|
||||
port = 8080
|
||||
[[host.route]]
|
||||
location = "/"
|
||||
proxy_pass = "http://localhost:3000/"
|
||||
# Timeout for connect to upstream
|
||||
proxy_timeout = 10
|
||||
# Client request max body size (bytes)
|
||||
max_body_size = 2048
|
||||
```
|
||||
|
||||
#### Lua Script
|
||||
|
||||
```toml
|
||||
[[host]]
|
||||
ip = "0.0.0.0"
|
||||
port = 8081
|
||||
[[host.route]]
|
||||
location = "/"
|
||||
lua_script = "html/index.lua"
|
||||
```
|
||||
|
@ -23,3 +23,11 @@ Options:
|
||||
-h, --help Print help
|
||||
-V, --version Print version
|
||||
```
|
||||
|
||||
Only one config file is supported, the default config file is `./config.toml`.
|
||||
|
||||
```bash
|
||||
❯ ./target/release/candy -c config.toml
|
||||
```
|
||||
|
||||
`-c` can be omitted, and when omitted, the default config file is `./config.toml` in the current directory.
|
||||
|
@ -45,7 +45,7 @@
|
||||
},
|
||||
"theme.colorToggle.ariaLabel": {
|
||||
"message": "切换浅色/暗黑模式(当前为{mode})",
|
||||
"description": "The ARIA label for the navbar color mode toggle"
|
||||
"description": "The ARIA label for the color mode toggle"
|
||||
},
|
||||
"theme.colorToggle.ariaLabel.mode.dark": {
|
||||
"message": "暗黑模式",
|
||||
@ -309,5 +309,17 @@
|
||||
"theme.tags.tagsPageTitle": {
|
||||
"message": "标签",
|
||||
"description": "The title of the tag list page"
|
||||
},
|
||||
"theme.colorToggle.ariaLabel.mode.system": {
|
||||
"message": "system mode",
|
||||
"description": "The name for the system color mode"
|
||||
},
|
||||
"theme.navbar.mobileDropdown.collapseButton.expandAriaLabel": {
|
||||
"message": "Expand the dropdown",
|
||||
"description": "The ARIA label of the button to expand the mobile dropdown navbar item"
|
||||
},
|
||||
"theme.navbar.mobileDropdown.collapseButton.collapseAriaLabel": {
|
||||
"message": "Collapse the dropdown",
|
||||
"description": "The ARIA label of the button to collapse the mobile dropdown navbar item"
|
||||
}
|
||||
}
|
||||
|
@ -6,4 +6,78 @@ title: 配置文件
|
||||
|
||||
## 配置文件
|
||||
|
||||
Candy 遵循配置文件进行配置。
|
||||
Candy 遵循配置文件进行配置。配置文件的格式为 TOML。
|
||||
|
||||
### 虚拟主机
|
||||
|
||||
顶层配置为虚拟主机 `host`,可以配置多个虚拟主机。
|
||||
|
||||
```toml
|
||||
[[host]]
|
||||
ip = "0.0.0.0"
|
||||
port = 80
|
||||
# Connection timeout
|
||||
timeout = 15
|
||||
# 只用当 ssl = true 时,才会读取证书和密钥,并开启 SSL 支持
|
||||
# ssl = true
|
||||
# Self sign a certificate
|
||||
# sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ./html/selfsigned.key -out ./html/selfsigned.crt
|
||||
certificate = "./html/selfsigned.crt"
|
||||
certificate_key = "./html/selfsigned.key"
|
||||
```
|
||||
|
||||
#### 自定义 HTTP 相应头
|
||||
|
||||
每个虚拟主机都可以配置自定义相应头
|
||||
|
||||
TODO
|
||||
|
||||
### 路由
|
||||
|
||||
每个虚拟主机下都可以配置多个路由。配置字段为 `route`。
|
||||
|
||||
每个路由支持三种配置:
|
||||
|
||||
- 静态文件托管
|
||||
- 反向代理
|
||||
- Lua 脚本
|
||||
|
||||
#### 静态文件托管
|
||||
|
||||
```toml
|
||||
[[host.route]]
|
||||
# 路由地址
|
||||
location = "/"
|
||||
# 静态文件根目录
|
||||
root = "html"
|
||||
# 当使用静态文件根目录时,使用下面的字段作为主页
|
||||
index = ["index.html"]
|
||||
# 列出目录
|
||||
auto_index = true
|
||||
```
|
||||
|
||||
#### 反向代理
|
||||
|
||||
```toml
|
||||
[[host]]
|
||||
ip = "0.0.0.0"
|
||||
port = 8080
|
||||
[[host.route]]
|
||||
location = "/"
|
||||
proxy_pass = "http://localhost:3000/"
|
||||
# Timeout for connect to upstream
|
||||
proxy_timeout = 10
|
||||
# Client request max body size (bytes)
|
||||
max_body_size = 2048
|
||||
```
|
||||
|
||||
#### Lua 脚本
|
||||
|
||||
```toml
|
||||
[[host]]
|
||||
ip = "0.0.0.0"
|
||||
port = 8081
|
||||
[[host.route]]
|
||||
location = "/"
|
||||
lua_script = "html/index.lua"
|
||||
```
|
||||
|
@ -23,3 +23,11 @@ Options:
|
||||
-h, --help Print help
|
||||
-V, --version Print version
|
||||
```
|
||||
|
||||
只需要一个可执行文件和一个配置文件,就可以快速部署一个 HTTP 服务器。
|
||||
|
||||
```bash
|
||||
❯ ./target/release/candy -c config.toml
|
||||
```
|
||||
|
||||
`-c` 可以省略,当省略时,默认使用当前目录下的 `config.toml` 文件。
|
||||
|
@ -19,22 +19,22 @@
|
||||
"tsc": "tsc"
|
||||
},
|
||||
"dependencies": {
|
||||
"@docusaurus/core": "3.6.3",
|
||||
"@docusaurus/faster": "^3.6.3",
|
||||
"@docusaurus/preset-classic": "3.6.3",
|
||||
"@docusaurus/core": "3.8.1",
|
||||
"@docusaurus/faster": "^3.8.1",
|
||||
"@docusaurus/preset-classic": "3.8.1",
|
||||
"@mdx-js/react": "^3.1.0",
|
||||
"clsx": "^2.1.1",
|
||||
"prism-react-renderer": "^2.4.0",
|
||||
"react": "^18.3.1",
|
||||
"react-dom": "^18.3.1"
|
||||
"prism-react-renderer": "^2.4.1",
|
||||
"react": "^19.1.0",
|
||||
"react-dom": "^19.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@docusaurus/module-type-aliases": "3.6.3",
|
||||
"@docusaurus/tsconfig": "3.6.3",
|
||||
"@docusaurus/types": "3.6.3",
|
||||
"prettier": "^3.4.2",
|
||||
"@docusaurus/module-type-aliases": "3.8.1",
|
||||
"@docusaurus/tsconfig": "3.8.1",
|
||||
"@docusaurus/types": "3.8.1",
|
||||
"prettier": "^3.6.2",
|
||||
"prettier-plugin-organize-imports": "^4.1.0",
|
||||
"typescript": "~5.7.2"
|
||||
"typescript": "~5.8.3"
|
||||
},
|
||||
"browserslist": {
|
||||
"production": [
|
||||
@ -51,5 +51,5 @@
|
||||
"engines": {
|
||||
"node": ">=18.0"
|
||||
},
|
||||
"packageManager": "pnpm@9.15.2"
|
||||
"packageManager": "pnpm@10.12.4"
|
||||
}
|
||||
|
3091
docs/pnpm-lock.yaml
generated
3091
docs/pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@ -14,30 +14,22 @@ const FeatureList: FeatureItem[] = [
|
||||
Svg: require('@site/static/img/undraw_docusaurus_mountain.svg').default,
|
||||
description: (
|
||||
<>
|
||||
Docusaurus was designed from the ground up to be easily installed and
|
||||
used to get your website up and running quickly.
|
||||
Single executable binary, with a TOML config file, quick to deploy a
|
||||
http server.
|
||||
</>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: 'Focus on What Matters',
|
||||
title: 'Performance',
|
||||
Svg: require('@site/static/img/undraw_docusaurus_tree.svg').default,
|
||||
description: (
|
||||
<>
|
||||
Docusaurus lets you focus on your docs, and we'll do the chores. Go
|
||||
ahead and move your docs into the <code>docs</code> directory.
|
||||
</>
|
||||
<>Multiple threads, asynchronous I/O, and multi-platform support.</>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: 'Powered by React',
|
||||
title: 'Powered by Rust',
|
||||
Svg: require('@site/static/img/undraw_docusaurus_react.svg').default,
|
||||
description: (
|
||||
<>
|
||||
Extend or customize your website layout by reusing React. Docusaurus can
|
||||
be extended while reusing the same header and footer.
|
||||
</>
|
||||
),
|
||||
description: <>Built with Rust, axum and tokio.</>,
|
||||
},
|
||||
];
|
||||
|
||||
|
@ -21,7 +21,7 @@ function HomepageHeader() {
|
||||
className="button button--secondary button--lg"
|
||||
to="/docs/intro"
|
||||
>
|
||||
Docusaurus Tutorial - 5min ⏱️
|
||||
Quick start - 5min ⏱️
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
@ -32,10 +32,7 @@ function HomepageHeader() {
|
||||
export default function Home(): JSX.Element {
|
||||
const { siteConfig } = useDocusaurusContext();
|
||||
return (
|
||||
<Layout
|
||||
title={`Hello from ${siteConfig.title}`}
|
||||
description="Description will go into a meta tag in <head />"
|
||||
>
|
||||
<Layout title={`${siteConfig.title}`} description="Candy, http web server">
|
||||
<HomepageHeader />
|
||||
<main>
|
||||
<HomepageFeatures />
|
||||
|
BIN
docs/static/img/candy-transparent.png
vendored
Normal file
BIN
docs/static/img/candy-transparent.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 544 KiB |
BIN
docs/static/img/candy.png
vendored
Normal file
BIN
docs/static/img/candy.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.6 MiB |
Reference in New Issue
Block a user