Browse Source

init psr-4 composer package

main
ghost 10 months ago
parent
commit
ae72a00361
  1. 43
      README.md
  2. 11
      composer.json
  3. 18
      composer.lock
  4. 26
      src/Request.php
  5. 44
      src/Response.php
  6. 77
      src/Server.php
  7. 2
      test/certs/.gitignore
  8. 44
      test/server.php

43
README.md

@ -1,40 +1,39 @@
# Titan II # Titan II
Gemini Protocol library for PHP. Gemini Protocol library for PHP 8
- [gemini://gemini.circumlunar.space/](gemini://gemini.circumlunar.space/) - [gemini://gemini.circumlunar.space/](gemini://gemini.circumlunar.space/)
- [https://gemini.circumlunar.space/](https://gemini.circumlunar.space/) - [https://gemini.circumlunar.space/](https://gemini.circumlunar.space/)
## Basic Implentation ## Install
1. `composer require yggverse/titan-ii`
2. `openssl req -x509 -newkey rsa:4096 -keyout key.rsa -out cert.pem -days 3650 -nodes -subj "/CN=127.0.0.1"`
3. `php server.php`
4. `gemini://127.0.0.1`
## Usage
``` ```
<?php <?php
use TitanII\Request; $server = new \YGGverse\TitanII\Server();
use TitanII\Response;
use TitanII\Server;
$server = new Server();
$server->setCert('cert.pem'); $server->setCert('cert.pem');
$server->setKey('key.rsa'); $server->setKey('key.rsa');
$server->setHandler(function (Request $request): Response { $server->setHandler(
$response = new Response(); function (\YGGverse\TitanII\Request $request): \YGGverse\TitanII\Response
{
$response = new \YGGverse\TitanII\Response();
$response->setCode(20); $response->setCode(20);
$response->setMeta("text/plain"); $response->setMeta('text/plain');
$response->setContent("Hello World!"); $response->setContent('Hello World!');
return $response; return $response;
}); }
);
$server->start(); $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`

11
composer.json

@ -1,9 +1,10 @@
{ {
"name": "tdmckenney0/titan-ii", "name": "yggverse/titan-ii",
"version": "0.1",
"description": "Gemini Protocol Library", "description": "Gemini Protocol Library",
"keywords": [ "gemini", "gemini-protocol", "ipv6" ],
"homepage": "https://github.com/YGGverse/titan-II",
"type": "library", "type": "library",
"license": "GPLv3", "license": "GPL-3.0-only",
"authors": [ "authors": [
{ {
"name": "Tanner Mckenney", "name": "Tanner Mckenney",
@ -12,6 +13,8 @@
], ],
"require": {}, "require": {},
"autoload": { "autoload": {
"classmap": ["src/"] "psr-4": {
"YGGverse\\TitanII\\": "src/"
}
} }
} }

18
composer.lock generated

@ -1,18 +0,0 @@
{
"_readme": [
"This file locks the dependencies of your project to a known state",
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "1d8aa09a1cb642af953e3d80b990a54a",
"packages": [],
"packages-dev": [],
"aliases": [],
"minimum-stability": "stable",
"stability-flags": [],
"prefer-stable": false,
"prefer-lowest": false,
"platform": [],
"platform-dev": [],
"plugin-api-version": "2.0.0"
}

26
src/Request.php

@ -1,6 +1,6 @@
<?php <?php
namespace TitanII; namespace YGGverse\TitanII;
/** /**
* Gemini Request * Gemini Request
@ -10,16 +10,16 @@ class Request {
* Maximum length in bytes of the URL request. * Maximum length in bytes of the URL request.
*/ */
const MAX_LENGTH = 1024; const MAX_LENGTH = 1024;
/** /**
* URL string. * URL string.
* *
* @var string * @var string
*/ */
private string $url; private string $url;
/** /**
* @param string Incoming URL request. * @param string Incoming URL request.
*/ */
public function __construct(string $url) public function __construct(string $url)
{ {
@ -27,7 +27,7 @@ class Request {
} }
/** /**
* Magic method. * Magic method.
*/ */
public function __toString(): string public function __toString(): string
{ {
@ -35,8 +35,8 @@ class Request {
} }
/** /**
* Get the Hostname. * Get the Hostname.
* *
* @return string|null * @return string|null
*/ */
public function getHost(): ?string public function getHost(): ?string
@ -45,8 +45,8 @@ class Request {
} }
/** /**
* Get the Path. * Get the Path.
* *
* @return string|null * @return string|null
*/ */
public function getPath(): ?string public function getPath(): ?string
@ -56,7 +56,7 @@ class Request {
/** /**
* Get the path, but as an array. * Get the path, but as an array.
* *
* @return array * @return array
*/ */
public function tokenizePath(): array public function tokenizePath(): array
@ -67,8 +67,8 @@ class Request {
} }
/** /**
* Get the Query. * Get the Query.
* *
* @return string|null * @return string|null
*/ */
public function getQuery(): ?string public function getQuery(): ?string

44
src/Response.php

@ -1,10 +1,10 @@
<?php <?php
namespace TitanII; namespace YGGverse\TitanII;
/** /**
* Gemini Response * Gemini Response
* *
* @see gemini://gemini.circumlunar.space/docs/specification.gmi * @see gemini://gemini.circumlunar.space/docs/specification.gmi
*/ */
class Response { class Response {
@ -15,33 +15,33 @@ class Response {
/** /**
* Response Code * Response Code
* *
* @var int * @var int
*/ */
private int $code = 20; private int $code = 20;
/** /**
* Meta Data * Meta Data
* *
* @var string * @var string
*/ */
private string $meta = "application/octet-stream"; private string $meta = "application/octet-stream";
/** /**
* Body Content. * Body Content.
* *
* @var string * @var string
*/ */
private string $content = ""; private string $content = "";
/** /**
* Set the Response code. * Set the Response code.
* *
* @param int Code. * @param int Code.
* *
* @return self Method chaining. * @return self Method chaining.
* *
* @throws Exception If not a valid code. * @throws Exception If not a valid code.
*/ */
public function setCode(int $code): self public function setCode(int $code): self
{ {
@ -56,7 +56,7 @@ class Response {
/** /**
* Get the Response Code * Get the Response Code
* *
* @return int * @return int
*/ */
public function getCode(): int public function getCode(): int
@ -66,9 +66,9 @@ class Response {
/** /**
* Set Meta Data * Set Meta Data
* *
* @param string * @param string
* *
* @return self Method chaining. * @return self Method chaining.
*/ */
public function setMeta(string $meta): self public function setMeta(string $meta): self
@ -79,7 +79,7 @@ class Response {
/** /**
* Get the Response Meta * Get the Response Meta
* *
* @return string * @return string
*/ */
public function getMeta(): string public function getMeta(): string
@ -88,10 +88,10 @@ class Response {
} }
/** /**
* Set the Response content. * Set the Response content.
* *
* @param string * @param string
* *
* @return self Method chaining. * @return self Method chaining.
*/ */
public function setContent(string $content): self public function setContent(string $content): self
@ -102,7 +102,7 @@ class Response {
/** /**
* Get the Response content * Get the Response content
* *
* @return string * @return string
*/ */
public function getContent(): string public function getContent(): string

77
src/Server.php

@ -1,40 +1,37 @@
<?php <?php
namespace TitanII; namespace YGGverse\TitanII;
use TitanII\Request;
use TitanII\Response;
/** /**
* Gemini Server * Gemini Server
* *
* @author Tanner Mckenney <tmckenney7@outlook.com> * @author Tanner Mckenney <tmckenney7@outlook.com>
*/ */
class Server { class Server {
/** /**
* Context created by stream_context_create(); * Context created by stream_context_create();
* *
* @var resource * @var resource
*/ */
private $context = null; private $context = null;
/** /**
* Socket created by stream_socket_server(); * Socket created by stream_socket_server();
* *
* @var resource * @var resource
*/ */
private $socket = null; private $socket = null;
/** /**
* Function that gets called to handle incoming requests. * Function that gets called to handle incoming requests.
* *
* @var callable * @var callable
*/ */
private $handler = null; private $handler = null;
/** /**
* Server active flag. * Server active flag.
* *
* @var bool * @var bool
*/ */
private bool $active = false; private bool $active = false;
@ -51,15 +48,15 @@ class Server {
} }
/** /**
* @param callable Handle incoming requests. * @param callable Handle incoming requests.
* *
* @return self Method chaining. * @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 \YGGverse\TitanII\Request
* *
* @return Response * @return \YGGverse\TitanII\Response
*/ */
public function setHandler(callable $handler): self public function setHandler(callable $handler): self
{ {
@ -69,9 +66,9 @@ class Server {
} }
/** /**
* Set the Certification file. * Set the Certification file.
* *
* @return self Method chaining. * @return self Method chaining.
*/ */
public function setCert(string $file): self public function setCert(string $file): self
{ {
@ -81,11 +78,11 @@ class Server {
} }
/** /**
* Optional. Set cert paassphrase. * Optional. Set cert paassphrase.
* *
* @param string * @param string
* *
* @return self Method chaining. * @return self Method chaining.
*/ */
public function setCertPassphrase(string $passphrase): self public function setCertPassphrase(string $passphrase): self
{ {
@ -96,10 +93,10 @@ class Server {
/** /**
* Set the Key file. * Set the Key file.
* *
* @param string * @param string
* *
* @return self Method chaining. * @return self Method chaining.
*/ */
public function setKey(string $key): self public function setKey(string $key): self
{ {
@ -109,12 +106,12 @@ class Server {
} }
/** /**
* Open the server socket. * Open the server socket.
* *
* @param string IP Address * @param string IP Address
* @param int Port Number. * @param int Port Number.
* *
* @return bool True on success, false on failure. * @return bool True on success, false on failure.
*/ */
protected function openSocket(string $ip, int $port): bool protected function openSocket(string $ip, int $port): bool
{ {
@ -133,15 +130,15 @@ class Server {
/** /**
* Start the server! * Start the server!
* *
* @param string IP Address * @param string IP Address
* @param int Port Number. * @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);
$this->active = true; $this->active = true;
while ($this->active) { while ($this->active) {
$incoming = stream_socket_accept($this->socket, -1, $peername); $incoming = stream_socket_accept($this->socket, -1, $peername);
@ -153,7 +150,7 @@ class Server {
stream_set_blocking($incoming, false); stream_set_blocking($incoming, false);
$request = new Request($body); $request = new \YGGverse\TitanII\Request($body);
$response = call_user_func($this->handler, $request); $response = call_user_func($this->handler, $request);

2
test/certs/.gitignore vendored

@ -1,2 +0,0 @@
*
!.gitignore

44
test/server.php

@ -1,44 +0,0 @@
<?php
namespace TitanII\Test;
require_once(__DIR__ . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . 'vendor' . DIRECTORY_SEPARATOR . 'autoload.php');
use TitanII\Server;
use TitanII\Request;
use TitanII\Response;
// Make a new server
$server = new Server();
// Set the certs.
$server->setCert(__DIR__ . DIRECTORY_SEPARATOR . 'certs' . DIRECTORY_SEPARATOR . 'cert.pem');
$server->setKey(__DIR__ . DIRECTORY_SEPARATOR . 'certs' . DIRECTORY_SEPARATOR . 'key.rsa');
// Response Body (Gemini Text!)
$body = <<<GEMINI
# Titan II Lifts off!
The tower is clear!
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 {
$response = new Response();
$response->setMeta('text/gemini');
$response->setContent($body);
echo $request;
return $response;
});
/**
* Boot the server!
*/
$server->start();
Loading…
Cancel
Save