{"id":13770604,"url":"https://github.com/marty1885/dremini","last_synced_at":"2025-04-14T15:22:39.299Z","repository":{"id":49317555,"uuid":"409219050","full_name":"marty1885/dremini","owner":"marty1885","description":"Highly parallel and concurrent Gemini server and client library for the Drogon web application framework","archived":false,"fork":false,"pushed_at":"2024-10-05T23:46:09.000Z","size":138,"stargazers_count":7,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-03-28T04:12:33.527Z","etag":null,"topics":["asynchronous","drogon","gemini","gemini-client","gemini-protocol","gemini-server","smol-internet","smolnet"],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/marty1885.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-09-22T13:38:18.000Z","updated_at":"2024-10-05T23:46:12.000Z","dependencies_parsed_at":"2023-01-29T19:15:33.989Z","dependency_job_id":"c0981598-6462-4c5f-9c56-2c5947572e5f","html_url":"https://github.com/marty1885/dremini","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marty1885%2Fdremini","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marty1885%2Fdremini/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marty1885%2Fdremini/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marty1885%2Fdremini/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/marty1885","download_url":"https://codeload.github.com/marty1885/dremini/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248904722,"owners_count":21180845,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["asynchronous","drogon","gemini","gemini-client","gemini-protocol","gemini-server","smol-internet","smolnet"],"created_at":"2024-08-03T17:00:39.781Z","updated_at":"2025-04-14T15:22:39.274Z","avatar_url":"https://github.com/marty1885.png","language":"C++","funding_links":[],"categories":["Programming"],"sub_categories":["Graphical"],"readme":"# Dremini\n\nHighly concurrent and multi-threaded gemini client and server library for the [Drogon web application framework](https://github.com/drogonframework/drogon)\n\n**This library is in early development. API may clange without notice**\n\n## Dependencies\n\n* [Drogon](https://github.com/drogonframework/drogon) \u003e= 1.7.3 (or 1.7.2 with MIME patch)\n\n## Usage\n\n### Client\n\nAsync-callback API\n\nThere's several ways to use the Gemini client. The most general one is by the async-callback API. The supplied callback function will be invoked once the cliend recived a response from the server.\n\n```c++\ndremini::sendRequest(\"gemini://gemini.circumlunar.space/\"\n    , [](ReqResult result, const HttpResponsePtr\u0026 resp) {\n        if(result != ReqResult::Ok)\n        {\n            LOG_ERROR \u003c\u003c \"Failed to send request\";\n            return;\n        }\n\n        LOG_INFO \u003c\u003c \"Body size: \" \u003c\u003c resp-\u003ebody().size();\n    });\n```\n\nC++ Coroutines\n\nIf C++ coroutines (requires MSVC 19.25, GCC 11 or better) is avaliable to you. You can also use the more stright forward coroutine API.\n\n```c++\ntry\n{\n    auto resp = co_await dremini::sendRequestCoro(\"gemini://gemini.circumlunar.space/\");\n    LOG_INFO \u003c\u003c \"Body size: \" \u003c\u003c resp-\u003ebody().size();\n} \ncatch(...)\n{\n    LOG_ERROR \u003c\u003c \"Failed to send request\";\n}\n```\n\n### Server\n\nThe `dremini::GeminiServer` plugin that parses and forwards Gemini requests as HTTP Get requests.\n\nThus, first enable the Gemini server plugin. And tell the server to serve gemini files (if you are also using it as a file server):\n\n```json\n// config.json\n{\n    \"app\":{\n        \"document_root\": \"./\",\n        \"file_types\": [\n            \"gmi\"\n        ],\n        \"use_implicit_page\": true,\n        \"implicit_page\": \"index.gmi\",\n        \"home_page\": \"index.gmi\",\n        \"mime\": {\n            \"text/gemini\": [\"gmi\", \"gemini\"]\n        }\n    },\n    \"plugins\": [\n        {\n            \"name\": \"dremini::GeminiServerPlugin\",\n            \"config\": {\n                \"listeners\": [\n                    {\n                        \"key\": \"key.pem\",\n                        \"cert\": \"cert.pem\",\n                        \"ip\": \"127.0.0.1\"\n                    }\n                ],\n                \"numThread\": 3\n            }\n        }\n    ]\n}\n\n```\n\nThen let's code up ca basic request handler:\n\n```c++\napp().registerHandler(\"/hi\", [](const HttpRequestPtr\u0026 req, std::function\u003cvoid(const HttpResponsePtr\u0026)\u003e\u0026\u0026 callback)\n{\n    auto resp = HttpResponse::newHttpResponse();\n    resp-\u003esetBody(\"# Hello Gemini\\nHello!\\n\");\n    resp-\u003esetContentTypeCodeAndCustomString(CT_CUSTOM, \"text/gemini\");\n    callback(resp);\n});\n```\n\nFinally, the handler can be triggered by using a Gemini client\n\n```\n\u003e gmni gemini://localhost/hi -j once\n# Hello Gemini\nHello\n\u003e\n```\n\n\n## Mapping from Gemini to HTTP\n\nDrogon is a HTTP framework. Dremini reuses a large portion of it's original functionality to provide easy Gemini server programming.\nWe try hard to keep to Gemini sementic in HTTP.\n\n### Status codes\n\nLike HTTP, Gemini uses status codes for servers to indicate the status of the response. Gemini status codes must have 2 digits.\nThus a range between 0 and 99. Dremini maps common HTTP status codes into Gemini ones automatically. And converts the rest to\nan apporiprate category. Here's a list of conversions\n\n|HTTP|Gemini|\n|----|------|\n|200 |20    |\n|400 |59    |\n|404 |51    |\n|429 |44    |\n|502 |43    |\n|504 |43    |\n\nIf the returned HTTP status is not listed above. The Gemini status is simply the HTTP status divied by 100. **Exception being 4\nxx and 5xx**. They 4xx is mapped as 50 and 5xx is mapped as 40. Since there's no HTTP status code lesser than 100 exists. Any status code in that range is treads as a Gemini native code. Which does not\ngo through any translation.\n\nHttpResponses from a Gemini client automaticallyi have a `gemini-status` header that stores the Gemini status code before mapping. And a `meta` header to store the meta.\n\n### Serving Gemini files\n\nDrogon by design is a HTTP server. Thus is has no idea about Gemini files and convension. The following config tells Drogon the following things. Which are required to properly serve gemini pages\n\n* Sets the page root folder to `/path/to/the/files`\n* Serve `*.gmi` files\n    * Add more types if needed\n* `*.gmi` and `*.gemini` files have the MIME type `text/gemini`\n* When asked to serve a directory, Try serving `index.gmi`\n* The homepage is `/index.gmi`\n\n```json\n{\n    \"app\":{\n        \"document_root\": \"/path/to/the/files\",\n        \"file_types\": [\n            \"gmi\",\n            \"gemini\"\n        ],\n        \"use_implicit_page\": true,\n        \"implicit_page\": \"index.gmi\",\n        \"home_page\": \"index.gmi\",\n        \"mime\": {\n            \"text/gemini\": [\"gmi\", \"gemini\"]\n        }\n    }\n}\n```\n\n### Gemini query\n\nGemini URLs supports a query parameter using the `?` symbol. For example, `gemini://localhost/search?Hello` has a query of \"Hello\". Dremini adds a `query` parameter to the HttpRequest when a query is detected.\n\n### Detecting Gemini requests\n\nDremini adds a `protocol` header to the proxyed HTTP request to singnal it's comming from a Gemini request. Whom's value is always \"gemini\"\n\n### Translating Gemini into HTML for HTTP requests\n\nDermini supports translating Gemini into HTML automatically! Add `\"translate_to_html\": true` into plugin config. This makes Dremini translate `text/gemini` contents into HTML when a regular browser requests content\n\n## Limitations\n\nDremini library does not verify server and client certificates yet. Nor client certs are supported.\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmarty1885%2Fdremini","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmarty1885%2Fdremini","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmarty1885%2Fdremini/lists"}