Falcon is a lightweight and simple HTTP server written in Go. Falcon can serve static files such as .html, .css, .js, images, videos, text files and more. Falcon is configurable via a YAML configuration file.
root parameter, if it wasnt defined Falcon uses public/. This prevents unauthorized access to private information.
Falcon provides two commands:
start # Starts the server at given address
new # Creates a new configuration file with given namefalcon start :8000 config.yml # Starts server at localhost:8000 with config.yml
falcon new config.yml # Creates sample config.yml💡 To stop the server, simply press CTRL+C or kill falcon process.
- Pre-requisites:
go
git- Clone this repository:
git clone https://github.com/zerfithel/falcon
cd falcon/src- Build falcon:
go build -o falcon *.go
sudo mv falcon /usr/bin- Create an environment for your server:**
sudo mkdir -p /srv/www/example.com/
cd /srv/www/example.com/
falcon new
mkdir public/ private/📁 Copy your public files into the public/ folder and private files into the private/ folder.
You can edit your config.yml as you like!
Falcon is configured via a YAML file, usually named config.yml.
To edit it, open it in your favorite text editor. The generated configuration file (via falcon new) contains:
routes→ defines which file responds to which HTTP requesterrors→ defines pages/messages for each HTTP error codehttps→ contains information about the private and public keys for TLS-enabled serversother→ defines other settings such as index files or root document directoryaccess→ defines access to whole server or specific fileplugins→ defines loading plugins and running hooks
💡 Tip: Always keep your private key safe and never share it publicly.
You should place publicly accessible files in directory defined by root parameter in other, if it wasn't defined Falcon will use public/ directory. This is an example of how your server file hierarchy can look like:
.
├── config.yml <- Your falcon configuration file
├── private/ <- Your private files
├── public/ <- Your public files (.html, .css, .js, images, videos etc.)
└── plugins/ <- Your plugins (.so)
Configuring Falcon is easy thanks to YAML simple syntax. I recommend using a text editor that will highlight YAML syntax error in real time to prevent errors and bugs.
- Generate a sample configuration file:
falcon new- Open it in your favorite text editor (I used nvim in this example):
nvim config.yml-
https: -
public_key- Your public HTTPS key for TLS-enabled server -
private_key- Your private HTTPS key for TLS-enabled server -
errors: -
error_code: -
message- Message to send for given HTTP error code -
page- Overridesmessage, sends given page at given error code -
routes: -
path- A request that will trigger the route -
page- A path to a file that will be sent back -
access: -
blacklist- Defines blocked IP addresses (IPv4/IPv6). If "ip -> error" syntax used, an given error will be thrown to that IP address. -
blacklist_error- Defines an error that will be thrown to all hosts that are blacklisted and have no error (in ip -> error syntax) given.
Error means an HTTP error. You can use "IGN" to ignore the connection and do nothing
-
whitelist- Same syntax as blacklist -
whitelist_error- An error to throw for all non-whitelisted hosts -
files: -
file- A path to a file -
deny/allow- Allow or deny given hosts -
error- An error to throw for blacklisted/non-whitelisted hosts (use "IGN" to ignore the connection) -
other: -
root- Defines a document root directory for the server -
index- Defines index files (separated by spaces, ' should be used for file names with a space. It will try to send first file and if it doesnt exists, it will send second etc. You can use wildcards likeindex.*ora*b*c.*htm*). -
plugins: -
path- Path to plugin (.so file) -
hook- Hook to run -
methods- Methods to NOT ignore
You can give paths to files (full path: '/srv/blacklist/blacklist1.txt' or paths from $PWD: './blacklist1.txt'). You can use FILE -> ERROR syntax also. If you add a file path instead of IP, falcon wont keep in RAM all of the IPs stored inside that text file, it will open it every time it receives a connection which might be slow, thats why if you have only a few banned/whitelisted IPs it is recommended to add these inside a YAML file instead of a standalone text file. You should separate IPs in files with new lines
To better understand the syntax of configuration file create a sample file with
falcon new-
main.go→ Handles command-line arguments.start: launches the server at the given address and loads the specified config filenew: creates a new sample configuration file
-
handler.go→ Handles HTTP requests from users (serves static files, displays error pages) -
server.go→ Contains code to initialize and run the server -
config.go→ Handles parsing and saving configuration file options -
plugins.go→ Loads plugins and runs hooks
✨ Falcon is simple, secure, and lightweight - perfect for serving static content quickly using Go!
Writing your own Falcon plugin is very easy.
- Example falcon plugin:
package main
import "net/http"
func PreRequest(w http.ResponseWriter, r *http.Request) {
println("HOOK PreRequest called for", r.Method, r.URL.Path) // log
}
func PostResponse(w http.ResponseWriter, r *http.Request) {
println("HOOK PostResponse called for", r.Method, r.URL.Path) // log
}- Compiling Go plugin:
go build -buildmode=shared -o plugins/plugin.so plugin.go- Add it to your config (example):
path: "plugins/plugin.so"
hook: "PostResponse"
methods: ["GET", "POST"]Falcon currently only supports loading .so (shared object) plugins. This means Windows .dll plugins wont work. I plan to add support for it in next updates. Stay tuned.