Jequi is a web server written in rust that focus on stability and flexibility. (It is not production ready yet but feel free to explore)
One of the main focus of Jequi is being very flexible and extensible, the way it does this is via plugins, plugins can add functionality to each request in a way that someone can write a plugin without needing to change the core of Jequi.
For example the jequi_proxy adds the functionality for jequi to be used as a proxy and jequi_go plugin adds functionality of executing go code for each request and jequi_go can execute code in the proxy phase of jequi_proxy without needing to change jequi_proxy code, also the api that allows the execution of go code can be used by other languages and it can be done just by developing a plugin for the desired language.
- Jequi
- Summary
- Features
- How to use Jequi
- Writing a plugin for Jequi
- Directory structure of this repository
- Configuration
- Configuration Options
- Api
- Api Documentation
- HTTP1 and HTTP2 support
- Proxy using jequi_proxy plugin
- Executing golang code using jequi_go plugin
- You can define upstreams for jequi_proxy using jequi_go
- Serving static files using jequi_serve_static plugin
- Logging and metrics plugin
- Allow configuration with multiple files
- Javascript plugin
- Websocket support for proxy
- Load balancer plugin
- Plugin that generates certificate
You can run on docker using the docker-compose.yml file as an example, also, there's an image available at ghcr.io/termack/jequi
or ghcr.io/termack/jequi-go
for an image that compiles go code
You must have Rust nightly setup, first compile the binary: cargo build
If you want to use the jequi_go plugin, compile the go shared library using: make go
Then run the compiled binary: target/debug/server
It will use the file conf.yaml
in your current directory, you can change the config file and then reload it while the server is still running with make reload
todo
├── api -> the jequi api, language plugins like `jequi_go` will call functions defined here, this api will call functions defined in `jequi`
├── jequi -> most functionality is here, it has all the objects and functions to allow jequi to function
├── plugins -> it has some proc macros for using plugins
│ ├── jequi_go -> the jequi_go plugin
│ │ ├── go -> the go code that will be executed is here
│ │ │ ├── handle -> **this is the code that has the functions that should be written by the user, feel free to play with it**
│ │ │ ├── jequi -> responsible for defining the interface that `/plugins/jequi_go` will call
│ │ │ └── jequi_go -> defines the go api that will call the jequi api (rust)
│ ├── jequi_proxy -> the jequi_proxy plugin
│ ├── jequi_serve_static -> the jequi_serve_static plugin
└── server -> execution starts here, it is responsi
Jequi uses yaml for its configuration, here's an example:
tls_active: true
proxy_address: "www.example1.com"
host:
jequi.com:
http2: true
uri:
/api:
go_library_path: "target/debug/jequi_go.so"
proxy_address: "www.example2.com"
static_files_path: "test/"
uri:
/api/v2:
go_library_path: "target/debug/jequi_go.so"
As you can see, jequi configuration allow some scopes, there's the default, host and uri. The configuration used is the most specific, so for example, a request to jequi.com/api/bla
will execute go code from target/debug/jequi_go.so
and then proxy the request to www.example2.com
and a request to jequi.com/hello
will serve a file from test/
.
scope: default
type: bool
Defines if tls is active for server.
scope: default
type: string
Defines the ip address that server will listen.
scope: default
type: string
Defines the port that server will listen.
scope: default, host
type: bool
Defines if the server accepts http2.
scope: default, host, uri
type: int
Defines the maximum chunk size for http responses.
From jequi_serve_static plugin
scope: default, host, uri
type: string
Sets the path to serve static files, if the path is a directory it will serve the files based on the request uri, if it is a file, it will serve the file always.
From jequi_proxy plugin
scope: default, host, uri
type: string
Define the upstream address that the server will proxy, the address can be an ip or domain and can have a port specified.
From jequi_go plugin
scope: default, host, uri
type: string
Define the path of the compiled go shared lib that will be used to execute the go functions.
Jequi has an api that allows for language plugins (like jequi_go for example) to communicate with it via FFI similiar to what openresty does with lua.
set_response_header(
*response,
header: string,
value: string,
)
Set a response header for the response.
set_response_status(
*response,
status: int,
)
Set the response status.
write_response_body(
*response,
content: string,
)
Write content into the response body buffer, if this function is called multiple times it will append content to the buffer.
get_request_header(
*request,
header: string,
) -> string
Returns the value of a request header, if the header doesn't exist it will return an empty string.
get_request_body(
*request,
) -> string
Returns the request body, if it wasn't read yet it will wait until it is read and return it as a string.
get_request_uri(
*request,
) -> string
Returns the request uri as a string.
get_request_method(
*request,
) -> string
Returns the request method as a string.
From jequi_proxy plugin
set_request_uri(
*request,
uri: string
)
Overwrites the request uri, so when the request is made to the proxy upstream it uses this new uri.