{"id":13770801,"url":"https://github.com/Alumniminium/atlas","last_synced_at":"2025-05-11T03:32:54.304Z","repository":{"id":58077499,"uuid":"529840663","full_name":"Alumniminium/atlas","owner":"Alumniminium","description":"C#/net8 Gemini/Spartan/Titan server with CGI, vhost and docker support - zero dependencies","archived":false,"fork":false,"pushed_at":"2024-04-08T07:36:21.000Z","size":2352,"stargazers_count":14,"open_issues_count":0,"forks_count":2,"subscribers_count":2,"default_branch":"master","last_synced_at":"2024-11-17T06:40:27.265Z","etag":null,"topics":["cgi","gemini","gemini-protocol","gemini-server","net8","netcore","spartan-protocol","spartan-server","titan-protocol","titan-server","vhost"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Alumniminium.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":"2022-08-28T11:22:00.000Z","updated_at":"2024-07-15T11:26:01.000Z","dependencies_parsed_at":"2024-04-08T08:39:54.554Z","dependency_job_id":null,"html_url":"https://github.com/Alumniminium/atlas","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/Alumniminium%2Fatlas","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Alumniminium%2Fatlas/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Alumniminium%2Fatlas/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Alumniminium%2Fatlas/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Alumniminium","download_url":"https://codeload.github.com/Alumniminium/atlas/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253514352,"owners_count":21920327,"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":["cgi","gemini","gemini-protocol","gemini-server","net8","netcore","spartan-protocol","spartan-server","titan-protocol","titan-server","vhost"],"created_at":"2024-08-03T17:00:42.267Z","updated_at":"2025-05-11T03:32:53.999Z","avatar_url":"https://github.com/Alumniminium.png","language":"C#","funding_links":[],"categories":["Servers"],"sub_categories":["Graphical"],"readme":"# Atlas\n\nthe launch rocket of the gemini capsule\n\n* C# / NET 8\n* zero dependencies\n* Linux and Windows - x86, x64 and ARM\n\n## Features\n\n* Docker Support\n* Automatic certificate generation\n* Analythics\n* Server-side animations on supported clients (eg. Lagrange) **DEMO: [gemini://her.st/](gemini://her.st/)**\n* Built-in special tokens (see below)\n* vhosts\n  * Per Location Configuration\n    * directory listing\n  * JSON config file\n* Configurable Default Mime Types\n* tsv Mimetype map\n* gemini:// with titan:// file uploads*\n* spartan:// file uploads and downloads*\n* CGI interface compatible with [jetforce](https://github.com/michael-lazar/jetforce)\n  * CGI streaming (for things like gemini://chat.mozz.us/)\n\n*Still WIP\n\n## Built-in Special Tokens\n\nToken | Replaced With |\n:---: | :--- |\n%%{sub}%% | Gemini: Subject Name of the Client Cert (without CN=) - if any - otherwise 'Anon'. For Spartan it always returns 'Spartan' |\n%%{host}%% | FQDN - eg: her.st |\n%%{path}%% | requested path - eg: /index.gmi |\n%%{scheme}%% | protocol of request - eg: spartan / gemini |\n%%{date}%% | YYYY-MM-DD - eg: 2024-03-30 |\n%%{time}%% | HH:mm:ss - eg: 21:04:25 |\n%%{datetime}%% | YYYY-MM-DD HH-mm-ss - eg: 2024-03-30 21:04:25 |\n%%{rendertime}%% | Milliseconds - eg: 0.59 |\n%%{ls}%% | Create Directory Index |\n\n### Example\n\nGemtext | Rendered |\n:--- | :--- |\nSub: %%{sub}%% | Sub: Alumniminium |\nHost: %%{host}%% | Host: localhost |\nPath: %%{path}%% | Path: /index.gmi |\nScheme: %%{scheme}%% | Scheme: gemini |\nDate: %%{date}%% | Date: 2024-04-01 |\nTime: %%{time}%% | Time: 11:32:41 |\nDatetime: %%{datetime}%% | Datetime: 2024-04-01 11:32:41  |\nRender Time: %%{rendertime}%% | Render Time: 4564.80 |\n%%{ls}%% | =\u003e gemini://localhost//index.gmi 2024-04-01 \\| 0.00mb \\| index.gmi | \n| | =\u003e gemini://localhost//localhost.pfx 2024-03-30 \\| 0.00mb \\| localhost.pfx |\n\n## Atlas Statistics\n\nYou can always access Atlas Stats on the following URL: gemini://yourserver.tld/atlas.stats\n\n![Stats Screenshot](/stats-1.jpg?raw=true \"Stats screenshot\")\n![Stats Screenshot](/stats-2.jpg?raw=true \"Stats screenshot\")\n\n## Roadmap (in no particular order)\n\n* FastCGI\n* Use single Docker volume\n* Caching\n* ~~certificate validation~~ **DONE IN v0.3 (April 1st 2024)**\n* rate limiting\n* proper networking with SocketAsyncEventArgs\n* Inline Server Sided Scripts using `%%{exec scriptname}%%`\n* Assign \"Owner\" Cert in Capsule config to allow editing of files via TITAN:// in-client\n\n### Sample configuration with all options\n\nA minimal config file will be autogenerated if none is found. this one is just an advanced example\n\n```json\n{\n  \"GeminiPort\": 1965,\n  \"SpartanPort\": 300,\n\n  \"SlowMode\": true, // animations, currently only for gemini\n  \"SlowModeMaxMilliSeconds\": 2000, // max time for animations in ms\n\n  \"Capsules\": {\n    \n    \"allsafe.net\": {\n      \"AbsoluteRootPath\": \"/srv/gemini/allsafe.net/\",\n      \"AbsoluteTlsCertPath\": \"/srv/gemini/allsafe.net/allsafe.net.pfx\",\n      \"FQDN\": \"allsafe.net\",\n      \"Index\": \"index.gmi\",\n\n      \"Locations\": \n      [\n        {\n          \"AbsoluteRootPath\": \"/srv/gemini/allsafe.net/\",\n          \"Index\": \"index.gmi\",\n        }\n      ]\n\n    },\n\n    \"evilcorp.net\": {\n      \"FQDN\": \"evilcorp.net\",\n      \"AbsoluteRootPath\": \"/srv/gemini/evilcorp.net/\",\n      \"AbsoluteTlsCertPath\": \"\",// will be automatically created and placed at AbsoluteRootPath/FQDN.pfx\n      \"Index\": \"index.gmi\",\n      \"MaxUploadSize\": 4194304, // global max upload size (bytes)\n      \n      \"Locations\": [\n        {\n          \"AbsoluteRootPath\": \"/srv/gemini/evilcorp.net/\",\n          \"Index\": \"index.gmi\",\n        },\n\n        {\n          \"AbsoluteRootPath\": \"/srv/gemini/evilcorp.net/cgi/\",\n          \"Index\": \"script.csx\",\n          \"CGI\": true,\n          \"RequireClientCert\": true,  // disables access for spartan protocol due to lack of support\n        },\n\n        {\n          \"AbsoluteRootPath\": \"/srv/gemini/evilcorp.net/textfiles/\",\n          \"Index\": \"index.gmi\",\n          \"DirectoryListing\": true, \n          \"AllowFileUploads\": true, // public Titan/Spartan  uploads in this location\n          \"MaxUploadSize\": 100000, // override max upload size (bytes)\n          \"DefaultMimeType\": \"text/plain\", // default mimetype for files without or unknown extension\n\n          \"AllowedMimeTypes\": {\n            \"text/*\": { // whitelist all text files\n              \"MaxSizeBytes\": 1048576 // override max upload size for text files\n            },\n          }\n        }\n      ]\n\n    }\n\n  }\n}\n```\n\n## CGI Interface\n\nThe CGI interface provides the following environment variables:\n\n Variable | Description | Default |\n---|---|---|\n DOTNET_CLI_HOME | Required for .NET assemblies to execute | ~/.dotnet |\n GATEWAY_INTERFACE | CGI Version | CGI/1.1 |\n SERVER_PROTOCOL | Either Gemini or Spartan | GEMINI / SPARTAN |\n SERVER_PORT | Gemini or Spartan Port according to config.json | 1965 / 300 |\n SERVER_SOFTWARE | atlas/version string | atlas/0.2b |\n URL | URL of the Request | gemini://evil.corp/cgi/binary?queryString=value#fragment\u0026token |\n SCRIPT_NAME | the CGI script name | binary |\n PATH_INFO | See CGI documentation | Hopefully correct |\n QUERY_STRING | Query from the URL | ?queryString=value#fragment\u0026token |\n SERVER_NAME | the FQDN of the vhost | evil.corp |\n REMOTE_HOST | The IP of the client sending the request | 127.0.0.1 |\n REMOTE_ADDR | as above | as above |\n TLS_VERSION | Gemini Only | 1.3 |\n REMOTE_USER | TLS Cert Subject without CN= | trbl |\n TLS_CLIENT_SUBJECT | as above | as above |\n TLS_CLIENT_VALID | Certificate is not expired | true |\n TLS_CLIENT_TRUSTED | Certificate issued by atlas | false |\n TLS_CLIENT_HASH | The Certificate Thumbprint | 0baf2asdb23i02.. |\n TLS_CLIENT_NOT_BEFORE | Certificate Valid From Time | 08/28/2022 18:26:30 |\n TLS_CLIENT_NOT_AFTER | Certificate Valid To Time | 08/28/3000 18:26:30 |\n TLS_CLIENT_SERIAL_NUMBER | The Certificate Serial Number | |\n AUTH_TYPE | CERTIFICATE or NONE | NONE |\n\n## sample CGI script\n\nCommenting **on** Articles\n[atlas-comments](https://github.com/Alumniminium/atlas-comments)\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FAlumniminium%2Fatlas","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FAlumniminium%2Fatlas","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FAlumniminium%2Fatlas/lists"}