A simple HTTP/1.1 webserver that runs on a PMMP server
MIT License
A verion for PocketMine-MP plugins to create a simple HTTP/1.1 web server.
PocketMap
. You can find the plugin here
composer require hebbinkpro/pmmp-webserver
For creating a web server,
you have to register the WebServer and create a new instance of WebServer
to start the server.
<?php
use Hebbinkpro\WebServer\WebServer;
use Hebbinkpro\WebServer\http\server\HttpServerInfo;
class YourPlugin extends \pocketmine\plugin\PluginBase {
protected function onEnable() : void{
// ...
$serverInfo = new HttpServerInfo("0.0.0.0", 80)
// Create a new server on the address and port
$webServer = new WebServer($this, $serverInfo);
// after starting the server, the site will be available at http://127.0.0.1:80
$webServer->start();
}
}
Note that if you want to access the server outside your localhost or local network, you may need to port-forward, otherwise it will not be available for the outside web!
Routes are used to let your web server be able to do things. By creating a Route
you can make your webserver listen to different paths and respond to them.
The router is used to register all your routes. the router will also handle all incoming requests and make sure they are handled by the correct Route
.
You can access the router of your WebServer
by calling:
$router = $webServer->getServerInfo()->getRouter();
A route is used to perform an action on an incoming web request.
use Hebbinkpro\WebServer\http\HttpMethod;
use Hebbinkpro\WebServer\http\message\HttpRequest;
use Hebbinkpro\WebServer\http\message\HttpResponse;
use Hebbinkpro\WebServer\route\Route;
{
// the method can be any value in the HttpMethod class.
// these methods represent HTTP request methods and makes the route listen to a specific type of request.
// if you want to listen to all requests, you can use HttpMethod::ANY (or "*").
$method = HttpMethod::GET;
// the specific path the route will listen to,
// you can find out more about the paths below
$path = "/";
// the action is the part that will execute once a client makes a request to the given method AND path.
// the HttpRequest inside the function is the request the client made to the web server
// the HttpResponse is the response the server will send back to the client after the function returns.
$action = function (HttpRequest $request, HttpResponse $response) {
// This will send the string "Hello World" back to the client.
$response->text("Hello World");
// the text function is one of the many simplified versions of the 'send' function
// by using the send function, you can input a string and set the HTTP content type
// the example below will send the string "<h1>Hello World</h1>" to the client and the client will see it as an HTML file.
$response->send("<h1>Hello World</h1>", "text/html");
// You can also send complete files using Response.
// this makes it really easy to send any kind of file
$response->sendFile("/path/to/your/file");
// but remember, you can only use ONE response action at any time
// each new response action will OVERWRITE the previous.
// So if you want to send multiple things in a single response,
// consider splitting it in multiple files, or sending everything in 1 response
}
// now we construct the Route with our given method, path and action.
$route = new Route($method, $path, $action);
}
The route action is the task performed when a new request is sent to the correct path. The syntax for an action is
function (HttpRequest $request, HttpResponse $response, mixed ...$params) {
// your code
}
$request
is the incoming request$response
is the response that will be returned to the client...$params
is an array with all given parameters.Route
. $route = new \Hebbinkpro\WebServer\route\Route($method, $action, ...$params);
You can add as many params as you want, if you only want 1 param, you can use new Route($method, $path, $action, $param1)
,
but if you want more than 1, you can add them behind the first
param. new Route($method, $path, $action, $param1, $param2, $param3)
.
Adding no parameters is also an option, new Route($method, $path, $action)
.
To use the ...$params
variable in the action, you can use it as an array, so $params[0]
will return the first parameter, and $params[1]
will give you the second, ect.
_Do not put any code that makes use of the main thread INSIDE the action function. Actions have to be ThreadSafe
, so
only things that DO NOT depend on the PocketMine thread will work. If you want to use classes that do not
extend pmmp\thread\ThreadSafe
, you can use serialize(...)
for the parameter and unserialize(...)
inside the action
function _
For the most common methods there are functions inside the Router
instance.
These functions make it so that you don't have to input an HTTP method for every new Route
you want to make
The available method function in Router
are:
Router->get($path, $action, ...$params)
Router->post($path, $action, ...$params)
Router->head($path, $action, ...$params)
Router->put($path, $action, ...$params)
Router->delete($path, $action, ...$params)
Hebbinkpro\WebServer\http\HttpMethod
), a route that listens to ALL HTTPRouter->all($path, $action, ...$params)
You can find more info about HTTP request methods here
The path and action arguments inside the router functions are the same as the once in Router
.
There are three types of routes you can use outside the default Route
implementations in the Router
:
Route
- A basic route that makes you able to create your own responses for a pathFileRoute
- A route that sends a file as responseRouterRoute
- A route that functions as a Router
, but only for the specified pathStaticRoute
- A route that makes you able to share the content of complete folders without making a Route
for each different path.\Hebbinkpro\WebServer\route\Route
.Route
to the Router
using$router->addRoute($route)
But there are also functions in Router
to easily add a FileRoute
, RouterRoute
or StaticRoute
.
$file = "path/to/your/file";
$default = "File not found";
// add the file route, $default is optional
$router->getFile($path, $file, $default);
use Hebbinkpro\WebServer\router\Router;
$childRouter = new Router();
// add here the stuff you want to the child router
// this is the same as for a default router
// ...
// add the router route with the path and the newly created child router
$router->route($path, $childRouter);
// define the folder you want to use for the static route by using its path
$folder = "/path/to/the/folder";
// add the static route with the path of the route and the folder path
$router->getStatic($path, $folder)
Route paths are the paths in the URL, these paths are very important because they contain the information about the page a client wants to see.
But to make sure the client sees the correct page, the path of this page needs to have a Route
.
This is why for every Route
you create, if it is using functions in the Router
or by creating a new Route
instance,
you HAVE to provide a VALID path, otherwise a client cannot find or request your page.
A path is nothing more than everything after the first /
up to the end or ?
in the uri after the address of a side.
Sometimes you want a Route
that listens to all requests that start with /foo
, so also to /foo/bar
or /foo/bar/etc
.
We can accomplish this by adding a /*
to the end of a path.
Sometimes you want to have a prefix, but also a suffix. To accomplish this, we introduce parameters.
A parameter is a part of the path which can be any kind of string, so a path /:var/a
will listen to /foo/a
but also in /bar/a
.
To make it even better, you can also request all variables inside an HttpRequest
using HttpRequest->getPathParams()
, this will return an array with the parameter name as key and the value set to the value in the path.
The query of a path is everything behind the ?
in a path, so /?foo=bar
. There can be multiple queries after the ?
by using the &
sign between two values.
A single query is represented as <name>=<value>
.
To request all queries you can use HttpURI->getQuery()
, or to request only a single value you can
use HttpURI->getQueryParam($name)
.
Since v1.0.0, the web server also supports SSL certificates which make it possible to run an HTTPS server for a more
secure connection than HTTP.
For enabling HTTPS on your webserver you have to add SslSettings
to the HttpServerInfo
BEFORE you start the web
server. This can be done in multiple ways.
cert
folder of your plugin data by$webServer->detectSSL()
.SslSettings
by calling $ssl = new SslSettings(...)
and add it toHttpServerInfo
: new HttpServerInfo(..., $ssl)
or by calling $serverInfo->setSSL($ssl)
.Router
on the main thread with the http server thread.