Skip to content

zerfithel/falcon

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

6 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

✈️ Falcon - Simple Go HTTP Server

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.

⚠️ For security reasons, Falcon can only serve files from directory defined in configuration file under root parameter, if it wasnt defined Falcon uses public/. This prevents unauthorized access to private information.


🦅 How to use Falcon

Falcon provides two commands:

start # Starts the server at given address
new   # Creates a new configuration file with given name

Example usage:

falcon 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.


🛠️ How to install Falcon

  1. Pre-requisites:
go
git
  1. Clone this repository:
git clone https://github.com/zerfithel/falcon
cd falcon/src
  1. Build falcon:
go build -o falcon *.go
sudo mv falcon /usr/bin
  1. 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 configurable!

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 request
  • errors → defines pages/messages for each HTTP error code
  • https → contains information about the private and public keys for TLS-enabled servers
  • other → defines other settings such as index files or root document directory
  • access → defines access to whole server or specific file
  • plugins → 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)

🔧 How to configure Falcon

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.

  1. Generate a sample configuration file:
falcon new
  1. Open it in your favorite text editor (I used nvim in this example):
nvim config.yml

☰ Falcon configuration file options

  • 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 - Overrides message, 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 like index.* or a*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

📚 Project Documentation

  • main.go → Handles command-line arguments.

    • start: launches the server at the given address and loads the specified config file
    • new: 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 plugin

Writing your own Falcon plugin is very easy.

  1. 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
}
  1. Compiling Go plugin:
go build -buildmode=shared -o plugins/plugin.so plugin.go
  1. 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.

About

Lightweight HTTP server written in Go

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages