A high-performance C++ server for DuckDuckGo bang command processing.
BangServer is an ultra-fast, multi-threaded C++ application designed to process DuckDuckGo bang commands with minimal latency. This project aims to provide the fastest possible lookup and redirection for bang commands.
Benchmarks:
CPU | Threads | Queries/second | Time per query (µs) |
---|---|---|---|
AMD EPYC 9754 | 256 | 831,665,000 | 0.0012 |
Intel i9-12900KF | 24 | 86,000,900 | 0.0116 |
Intel i9-12900KF | 8 | 42,907,400 | 0.0233 |
Intel i9-12900KF | 1 | 8,148,490 | 0.1227 |
The simplest way to run BangServer is using Docker:
# Run with default configuration
docker run -p 8080:8080 --security-opt seccomp=$(pwd)/io_uring_seccomp.json ghcr.io/rebelonion/bangserver:latest
# Run with proper hostname for OpenSearch support
docker run -p 8080:8080 --security-opt seccomp=$(pwd)/io_uring_seccomp.json -e BANG_HOST="your-server-hostname.com" ghcr.io/rebelonion/bangserver:latest
# Using with custom configuration
docker run -p 8080:8080 \
-v $(pwd)/config:/etc/bangserver:ro \
-e BANG_HOST="your-server-hostname.com" \
--security-opt seccomp=$(pwd)/io_uring_seccomp.json \
ghcr.io/rebelonion/bangserver:latest
Note: When running in Docker, you'll need to use the io_uring_seccomp.json profile or seccomp=unconfined to enable io_uring functionality.
For a more complete setup with Docker Compose:
services:
bangserver:
image: ghcr.io/rebelonion/bangserver:latest
ports:
- "8080:8080"
environment:
- BANG_PORT=8080
- BANG_HOST=your-server-hostname.com
- BANG_DEFAULT_SEARCH=https://duckduckgo.com/?q=
volumes:
- ./config:/etc/bangserver:ro
- ./io_uring_seccomp.json:/etc/seccomp/io_uring_seccomp.json:ro
security_opt:
- seccomp:/etc/seccomp/io_uring_seccomp.json
BangServer supports configuration through TOML files and environment variables.
You can configure server settings using a TOML file or environment variables.
Create a bangserver.toml
file in one of these locations:
- Current directory
- User's config directory (
~/.config/bangserver/
on Linux) - System-wide config directory (
/etc/bangserver/
on Linux)
Example bangserver.toml
:
# Server settings
[server]
port = 3000 # Port to listen on
backlog = 5 # Connection backlog
queue_depth = 256 # I/O queue depth for liburing
request_buffer_size = 4096 # Maximum request size
num_threads = 8 # Optional: number of threads to use (auto if not specified)
# Search settings
[search]
default_url = "https://www.google.com/search?q=" # Default search engine URL
# Bang providers configuration
[[providers]]
source = "https://duckduckgo.com/bang.js" # DuckDuckGo public API
format = "json"
required = true
[[providers]]
source = "bangs.json" # Custom bangs in JSON format (local file)
format = "json"
required = false
[[bangs]] # Bangs can be added in the server config as well
trigger = "custom"
url_template = "https://customsearch.com/?q={{{s}}}"
You can also set configuration with these environment variables:
BANG_PORT
- Server portBANG_HOST
- Hostname for OpenSearch XML (defaults to localhost if not set)BANG_BACKLOG
- Connection backlogBANG_DEFAULT_SEARCH
- Default search URLBANG_THREADS
- Number of worker threadsBANG_CONFIG_FILE
- Path to custom config file
Example:
BANG_PORT=8080 BANG_HOST="example.com" BANG_DEFAULT_SEARCH="https://duckduckgo.com/?q=" ./bangserver
When using Docker, you can configure the server in several ways:
- Creating a config directory with all your configuration files:
mkdir -p config
cp bangserver.example.toml config/bangserver.toml
cp bangs.example.json config/bangs.json
- Using environment variables alongside your config directory:
docker run -p 8080:8080 \
-v $(pwd)/config:/etc/bangserver:ro \
-e BANG_PORT=8080 \
-e BANG_HOST="example.com" \
-e BANG_DEFAULT_SEARCH="https://duckduckgo.com/?q=" \
--security-opt seccomp=$(pwd)/io_uring_seccomp.json \
ghcr.io/rebelonion/bangserver:latest
You can add custom bangs or override existing ones in either JSON or TOML format.
Bang definition file in JSON format:
[
{
"t": "example",
"u": "https://example.com/search?q={{{s}}}",
"d": "example.com",
"s": "Example Search"
},
{
"t": "custom",
"u": "https://customsearch.com/?q={{{s}}}"
}
]
Bang definition file in TOML format:
[[bangs]]
trigger = "example"
url_template = "https://example.com/search?q={{{s}}}"
domain = "example.com"
short_name = "Example Search"
category = "Research"
subcategory = "Reference"
[[bangs]]
trigger = "custom"
url_template = "https://customsearch.com/?q={{{s}}}"
- JSON:
t
(trigger),u
(URL template) - TOML:
trigger
,url_template
Use {{{s}}}
as placeholder for the search query in either format.
d
/domain
: Website domains
/short_name
: Display namec
/category
: Category (Entertainment, Multimedia, News, Online Services, Research, Shopping, Tech, Translation)sc
/subcategory
: Subcategoryr
/relevance
: Relevance ranking
If a custom bang has the same trigger as an existing bang, it will override the original.
# Debug build
cmake -B cmake-build-debug && cmake --build cmake-build-debug
# Release build (recommended for performance)
cmake -B cmake-build-release -DCMAKE_BUILD_TYPE=Release && cmake --build cmake-build-release
# Run the server
./cmake-build-release/bangserver
# Run benchmarks
./cmake-build-release/bangbenchmark -t <threads>
# More options can be found with --help
- Written in C++23
- Modular design with source/format separation
- Uses Abseil flat_hash_map for optimal lookups
- JSON parsing with simdjson
- TOML parsing with toml11
- Uses raw sockets and liburing for high-performance networking
- SIMD optimizations for performance
This project is licensed under the MIT License. See the LICENSE.md file for details.