Browse Source

Documentation

main
Tanner Mckenney 3 years ago
parent
commit
dfecb31733
  1. 34
      README.md
  2. 6
      src/Request.php
  3. 32
      src/Response.php
  4. 38
      src/Server.php
  5. 15
      test/server.php

34
README.md

@ -1,3 +1,37 @@
# Titan II # Titan II
Gemini Protocol library for PHP. Gemini Protocol library for PHP.
## Basic Implentation
```
<?php
use TitanII\Request;
use TitanII\Response;
use TitanII\Server;
$server = new Server();
$server->setCert('cert.pem');
$server->setKey('key.rsa');
$server->setHandler(function (Request $request): Response {
$response = new Response();
$response->setCode(20);
$response->setMeta("text/plain");
$response->setContent("Hello World!");
return $response;
});
$server->start();
```
## Instructions
1. run `cd test/certs; openssl req -x509 -newkey rsa:4096 -keyout key.rsa -out cert.pem -days 3650 -nodes -subj "/CN=127.0.0.1"`
2. run `composer install`
3. run `cd ..; php server.php`
4. Open `gemini://127.0.0.1`

6
src/Request.php

@ -18,11 +18,17 @@ class Request {
*/ */
private string $url; private string $url;
/**
* @param string Incoming URL request.
*/
public function __construct(string $url) public function __construct(string $url)
{ {
$this->url = substr($url, 0, self::MAX_LENGTH); $this->url = substr($url, 0, self::MAX_LENGTH);
} }
/**
* Magic method.
*/
public function __toString(): string public function __toString(): string
{ {
return $this->url; return $this->url;

32
src/Response.php

@ -4,6 +4,8 @@ namespace TitanII;
/** /**
* Gemini Response * Gemini Response
*
* @see gemini://gemini.circumlunar.space/docs/specification.gmi
*/ */
class Response { class Response {
/** /**
@ -32,10 +34,15 @@ class Response {
*/ */
private string $content = ""; private string $content = "";
public function __construct() /**
{ * Set the Response code.
} *
* @param int Code.
*
* @return self Method chaining.
*
* @throws Exception If not a valid code.
*/
public function setCode(int $code): self public function setCode(int $code): self
{ {
if (!in_array($code, self::CODES)) { if (!in_array($code, self::CODES)) {
@ -47,18 +54,35 @@ class Response {
return $this; return $this;
} }
/**
* Set Meta Data
*
* @param string
*
* @return self Method chaining.
*/
public function setMeta(string $meta): self public function setMeta(string $meta): self
{ {
$this->meta = $meta; $this->meta = $meta;
return $this; return $this;
} }
/**
* Set the Response content.
*
* @param string
*
* @return self Method chaining.
*/
public function setContent(string $content): self public function setContent(string $content): self
{ {
$this->content = $content; $this->content = $content;
return $this; return $this;
} }
/**
* Magic Method
*/
public function __toString(): string public function __toString(): string
{ {
return $this->code . ' ' . $this->meta . "\r\n" . $this->content; return $this->code . ' ' . $this->meta . "\r\n" . $this->content;

38
src/Server.php

@ -53,6 +53,8 @@ class Server {
/** /**
* @param callable Handle incoming requests. * @param callable Handle incoming requests.
* *
* @return self Method chaining.
*
* Parameter 1 Callable is expected to handle the following: * Parameter 1 Callable is expected to handle the following:
* *
* @param Request * @param Request
@ -66,6 +68,11 @@ class Server {
return $this; return $this;
} }
/**
* Set the Certification file.
*
* @return self Method chaining.
*/
public function setCert(string $file): self public function setCert(string $file): self
{ {
stream_context_set_option($this->context, 'ssl', 'local_cert', $file); stream_context_set_option($this->context, 'ssl', 'local_cert', $file);
@ -73,6 +80,13 @@ class Server {
return $this; return $this;
} }
/**
* Optional. Set cert paassphrase.
*
* @param string
*
* @return self Method chaining.
*/
public function setCertPassphrase(string $passphrase): self public function setCertPassphrase(string $passphrase): self
{ {
stream_context_set_option($this->context, 'ssl', 'passphrase', $passphrase); stream_context_set_option($this->context, 'ssl', 'passphrase', $passphrase);
@ -80,6 +94,13 @@ class Server {
return $this; return $this;
} }
/**
* Set the Key file.
*
* @param string
*
* @return self Method chaining.
*/
public function setKey(string $key): self public function setKey(string $key): self
{ {
stream_context_set_option($this->context, 'ssl', 'local_pk', $key); stream_context_set_option($this->context, 'ssl', 'local_pk', $key);
@ -87,6 +108,14 @@ class Server {
return $this; return $this;
} }
/**
* Open the server socket.
*
* @param string IP Address
* @param int Port Number.
*
* @return bool True on success, false on failure.
*/
protected function openSocket(string $ip, int $port): bool protected function openSocket(string $ip, int $port): bool
{ {
$addr = "tcp://" . $ip . ':' . $port; $addr = "tcp://" . $ip . ':' . $port;
@ -102,6 +131,12 @@ class Server {
return true; return true;
} }
/**
* Start the server!
*
* @param string IP Address
* @param int Port Number.
*/
public function start(string $ip = '0', int $port = 1965): void public function start(string $ip = '0', int $port = 1965): void
{ {
$this->openSocket($ip, $port); $this->openSocket($ip, $port);
@ -128,6 +163,9 @@ class Server {
} }
} }
/**
* Stop the server!
*/
public function stop(): void public function stop(): void
{ {
$this->active = false; $this->active = false;

15
test/server.php

@ -8,17 +8,25 @@ use TitanII\Server;
use TitanII\Request; use TitanII\Request;
use TitanII\Response; use TitanII\Response;
// Make a new server
$server = new Server(); $server = new Server();
// Set the certs.
$server->setCert(__DIR__ . DIRECTORY_SEPARATOR . 'certs' . DIRECTORY_SEPARATOR . 'cert.pem'); $server->setCert(__DIR__ . DIRECTORY_SEPARATOR . 'certs' . DIRECTORY_SEPARATOR . 'cert.pem');
$server->setKey(__DIR__ . DIRECTORY_SEPARATOR . 'certs' . DIRECTORY_SEPARATOR . 'key.rsa'); $server->setKey(__DIR__ . DIRECTORY_SEPARATOR . 'certs' . DIRECTORY_SEPARATOR . 'key.rsa');
// Response Body (Gemini Text!)
$body = <<<GEMINI $body = <<<GEMINI
# This is a server test! # Titan II Lifts off!
Congrats! You passed! The tower is clear!
GEMINI; GEMINI;
/**
* Set a request handler.
*
* This function must take a `TitanII\Request` object, and return a `TitanII\Response` object.
*/
$server->setHandler(function (Request $request) use (&$body): Response { $server->setHandler(function (Request $request) use (&$body): Response {
$response = new Response(); $response = new Response();
@ -30,4 +38,7 @@ $server->setHandler(function (Request $request) use (&$body): Response {
return $response; return $response;
}); });
/**
* Boot the server!
*/
$server->start(); $server->start();
Loading…
Cancel
Save