684 lines
1.2 MiB
HTML
684 lines
1.2 MiB
HTML
|
<!-- Saved from local source at 2023-11-08T00:39:45Z using monolith v2.7.0 -->
|
|||
|
<!DOCTYPE html><html xmlns="http://www.w3.org/1999/xhtml" lang="" xml:lang=""><head>
|
|||
|
<meta charset="utf-8">
|
|||
|
<meta name="generator" content="pandoc">
|
|||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">
|
|||
|
<title>Molerat Protocol Specification</title>
|
|||
|
<style>
|
|||
|
code{white-space: pre-wrap;}
|
|||
|
span.smallcaps{font-variant: small-caps;}
|
|||
|
div.columns{display: flex; gap: min(4vw, 1.5em);}
|
|||
|
div.column{flex: auto; overflow-x: auto;}
|
|||
|
div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;}
|
|||
|
/* The extra [class] is a hack that increases specificity enough to
|
|||
|
override a similar rule in reveal.js */
|
|||
|
ul.task-list[class]{list-style: none;}
|
|||
|
ul.task-list li input[type="checkbox"] {
|
|||
|
font-size: inherit;
|
|||
|
width: 0.8em;
|
|||
|
margin: 0 0.8em 0.2em -1.6em;
|
|||
|
vertical-align: middle;
|
|||
|
}
|
|||
|
.display.math{display: block; text-align: center; margin: 0.5rem auto;}
|
|||
|
/* CSS for syntax highlighting */
|
|||
|
pre > code.sourceCode { white-space: pre; position: relative; }
|
|||
|
pre > code.sourceCode > span { line-height: 1.25; }
|
|||
|
pre > code.sourceCode > span:empty { height: 1.2em; }
|
|||
|
.sourceCode { overflow: visible; }
|
|||
|
code.sourceCode > span { color: inherit; text-decoration: inherit; }
|
|||
|
div.sourceCode { margin: 1em 0; }
|
|||
|
pre.sourceCode { margin: 0; }
|
|||
|
@media screen {
|
|||
|
div.sourceCode { overflow: auto; }
|
|||
|
}
|
|||
|
@media print {
|
|||
|
pre > code.sourceCode { white-space: pre-wrap; }
|
|||
|
pre > code.sourceCode > span { text-indent: -5em; padding-left: 5em; }
|
|||
|
}
|
|||
|
pre.numberSource code
|
|||
|
{ counter-reset: source-line 0; }
|
|||
|
pre.numberSource code > span
|
|||
|
{ position: relative; left: -4em; counter-increment: source-line; }
|
|||
|
pre.numberSource code > span > a:first-child::before
|
|||
|
{ content: counter(source-line);
|
|||
|
position: relative; left: -1em; text-align: right; vertical-align: baseline;
|
|||
|
border: none; display: inline-block;
|
|||
|
-webkit-touch-callout: none; -webkit-user-select: none;
|
|||
|
-khtml-user-select: none; -moz-user-select: none;
|
|||
|
-ms-user-select: none; user-select: none;
|
|||
|
padding: 0 4px; width: 4em;
|
|||
|
background-color: #ffffff;
|
|||
|
color: #a0a0a0;
|
|||
|
}
|
|||
|
pre.numberSource { margin-left: 3em; border-left: 1px solid #a0a0a0; padding-left: 4px; }
|
|||
|
div.sourceCode
|
|||
|
{ color: #1f1c1b; background-color: #f5f5f5; }
|
|||
|
@media screen {
|
|||
|
pre > code.sourceCode > span > a:first-child::before { text-decoration: underline; }
|
|||
|
}
|
|||
|
code span { color: #1f1c1b; } /* Normal */
|
|||
|
code span.al { color: #bf0303; background-color: #f7e6e6; font-weight: bold; } /* Alert */
|
|||
|
code span.an { color: #ca60ca; } /* Annotation */
|
|||
|
code span.at { color: #0057ae; } /* Attribute */
|
|||
|
code span.bn { color: #b08000; } /* BaseN */
|
|||
|
code span.bu { color: #644a9b; font-weight: bold; } /* BuiltIn */
|
|||
|
code span.cf { color: #1f1c1b; font-weight: bold; } /* ControlFlow */
|
|||
|
code span.ch { color: #924c9d; } /* Char */
|
|||
|
code span.cn { color: #aa5500; } /* Constant */
|
|||
|
code span.co { color: #898887; } /* Comment */
|
|||
|
code span.cv { color: #0095ff; } /* CommentVar */
|
|||
|
code span.do { color: #607880; } /* Documentation */
|
|||
|
code span.dt { color: #0057ae; } /* DataType */
|
|||
|
code span.dv { color: #b08000; } /* DecVal */
|
|||
|
code span.er { color: #bf0303; text-decoration: underline; } /* Error */
|
|||
|
code span.ex { color: #0095ff; font-weight: bold; } /* Extension */
|
|||
|
code span.fl { color: #b08000; } /* Float */
|
|||
|
code span.fu { color: #644a9b; } /* Function */
|
|||
|
code span.im { color: #ff5500; } /* Import */
|
|||
|
code span.in { color: #b08000; } /* Information */
|
|||
|
code span.kw { color: #1f1c1b; font-weight: bold; } /* Keyword */
|
|||
|
code span.op { color: #1f1c1b; } /* Operator */
|
|||
|
code span.ot { color: #006e28; } /* Other */
|
|||
|
code span.pp { color: #006e28; } /* Preprocessor */
|
|||
|
code span.re { color: #0057ae; background-color: #e0e9f8; } /* RegionMarker */
|
|||
|
code span.sc { color: #3daee9; } /* SpecialChar */
|
|||
|
code span.ss { color: #ff5500; } /* SpecialString */
|
|||
|
code span.st { color: #bf0303; } /* String */
|
|||
|
code span.va { color: #0057ae; } /* Variable */
|
|||
|
code span.vs { color: #bf0303; } /* VerbatimString */
|
|||
|
code span.wa { color: #bf0303; } /* Warning */
|
|||
|
</style>
|
|||
|
<link rel="stylesheet" href="data:text/css;base64,aHRtbCB7Cglmb250LWZhbWlseTogIkxhdG8iLCBzYW5zLXNlcmlmOwoJY29sb3I6ICMxYTFhMWE7CgliYWNrZ3JvdW5kLWNvbG9yOiAjZmRmZGZkOwp9CmJvZHkgewoJbWFyZ2luOiAwIGF1dG87CgltYXgtd2lkdGg6IDM2ZW07CglwYWRkaW5nLWxlZnQ6IDUwcHg7CglwYWRkaW5nLXJpZ2h0OiA1MHB4OwoJcGFkZGluZy10b3A6IDUwcHg7CglwYWRkaW5nLWJvdHRvbTogNTBweDsKCWh5cGhlbnM6IGF1dG87CglvdmVyZmxvdy13cmFwOiBicmVhay13b3JkOwoJdGV4dC1yZW5kZXJpbmc6IG9wdGltaXplTGVnaWJpbGl0eTsKCWZvbnQta2VybmluZzogbm9ybWFsOwp9CkBtZWRpYSAobWF4LXdpZHRoOiA2MDBweCkgewoJYm9keSB7CgkJZm9udC1zaXplOiAwLjllbTsKCQlwYWRkaW5nOiAxMnB4OwoJfQoJaDEgewoJCWZvbnQtc2l6ZTogMS44ZW07Cgl9Cn0KQG1lZGlhIHByaW50IHsKCWh0bWwgewoJCWJhY2tncm91bmQtY29sb3I6IHdoaXRlOwoJfQoJYm9keSB7CgkJYmFja2dyb3VuZC1jb2xvcjogdHJhbnNwYXJlbnQ7CgkJY29sb3I6IGJsYWNrOwoJCWZvbnQtc2l6ZTogMTJwdDsKCX0KCXAsIGgyLCBoMyB7CgkJb3JwaGFuczogMzsKCQl3aWRvd3M6IDM7Cgl9CgloMiwgaDMsIGg0IHsKCQlwYWdlLWJyZWFrLWFmdGVyOiBhdm9pZDsKCX0KfQpwIHsKCW1hcmdpbjogMWVtIDA7Cn0KYSB7Cgljb2xvcjogIzFhMWExYTsKfQphOnZpc2l0ZWQgewoJY29sb3I6ICMxYTFhMWE7Cn0KaW1nIHsKCW1heC13aWR0aDogMTAwJTsKfQpzdmcgewoJaGVpZ2h0OiBhdXRvOwoJbWF4LXdpZHRoOiAxMDAlOwp9CmgxLCBoMiwgaDMsIGg0LCBoNSwgaDYgewoJbWFyZ2luLXRvcDogMS40ZW07Cn0KaDUsIGg2IHsKCWZvbnQtc2l6ZTogMWVtOwoJZm9udC1zdHlsZTogaXRhbGljOwp9Cmg2IHsKCWZvbnQtd2VpZ2h0OiBub3JtYWw7Cn0Kb2wsIHVsIHsKCXBhZGRpbmctbGVmdDogMS43ZW07CgltYXJnaW4tdG9wOiAxZW07Cn0KbGkgPiBvbCwgbGkgPiB1bCB7CgltYXJnaW4tdG9wOiAwOwp9CmJsb2NrcXVvdGUgewoJbWFyZ2luOiAxZW0gMCAxZW0gMS43ZW07CglwYWRkaW5nLWxlZnQ6IDFlbTsKCWJvcmRlci1sZWZ0OiAycHggc29saWQgI2U2ZTZlNjsKCWNvbG9yOiAjNjA2MDYwOwp9CmNvZGUgewoJZm9udC1mYW1pbHk6ICJKZXRCcmFpbnNNb25vIE5lcmQgRm9udCBNb25vIiwgbW9ub3NwYWNlOwoJZm9udC1zaXplOiA4NSU7CgltYXJnaW46IDA7CgloeXBoZW5zOiBtYW51YWw7Cn0KcHJlIHsKCW1hcmdpbjogMWVtIDA7CglvdmVyZmxvdzogYXV0bzsKfQpwcmUgY29kZSB7CglwYWRkaW5nOiAwOwoJb3ZlcmZsb3c6IHZpc2libGU7CglvdmVybG93LXdyYXA6IG5vcm1hbDsKfQouc291cmNlQ29kZSB7CgliYWNrZ3JvdW5kLWNvbG9yOiB0cmFuc3BhcmVudDsKCW92ZXJmbG93OiB2aXNpYmxlOwp9CmhyIHsKCWJhY2tncm91bmQtY29sb3I6ICMxYTFhMWE7Cglib3JkZXI6IG5vbmU7CgloZWlnaHQ6IDFweDsKCW1hcmdpbjogMWVtIDA7Cn0KdGFibGUgewoJbWFyZ2luOiAxZW0gMDsKCWJvcmRlci1jb2xsYXBzZTogY29sbGFwc2U7Cgl3aWR0aDogMTAwJTsKCW92ZXJmbG93LXg6IGF1dG87CglkaXNwbGF5OiBibG9jazsKCWZvbnQtdmFyaWFudC1udW1lcmljOiBsaW5pbmctbnVtcyB0YWJ1bGFyLW51bXM7Cn0KdGFibGUgY2FwdGlvbiB7CgltYXJnaW4tYm90dG9tOiAwLjc1ZW07Cn0KdGJvZHkgewoJbWFyZ2luLXRvcDogMC41ZW07Cglib3JkZXItdG9wOiAxcHggc29saWQgIzFhMWExYTsKCWJvcmRlci1ib3R0b206IDFweCBzb2xpZCAjMWExYTFhOwp9CnRoIHsKCWJvcmRlci10b3A6IDFweCBzb2xpZCAjMWExYTFhOwoJcGFkZGluZzogMC4yNWVtIDAuNWVtIDAuMjVlbSAwLjVlbTsKfQp0ZCB7CglwYWRkaW5nOiAwLjEyNWVtIDAuNWVtIDAuMjVlbSAwLjVlbTsKfQpoZWFkZXIgewoJbWFyZ2luLWJvdHRvbTogNGVtOwoJdGV4dC1hbGlnbjogY2VudGVyOwp9CiNUT0MgbGkgewoJbGlzdC1zdHlsZTogbm9uZTsKfQojVE9DIHVsIHsKCXBhZGRpbmctbGVmdDogMS4zZW07Cn0KI1RPQyA+IHVsIHsKCXBhZGRpbmctbGVmdDogMDsKfQojVE9DIGE6bm90KDpob3ZlcikgewoJdGV4dC1kZWNvcmF0aW9uOiBub25lOwp9CmNvZGV7d2hpdGUtc3BhY2U6IHByZS13cmFwO30Kc3Bhbi5zbWFsbGNhcHN7Zm9udC12YXJpYW50OiBzbWFsbC1jYXBzO30KZGl2LmNvbHVtbnN7ZGlzcGxheTogZmxleDsgZ2FwOiBtaW4oNHZ3LCAxLjVlbSk7fQpkaXYuY29sdW1ue2ZsZXg6IGF1dG87IG92ZXJmbG93LXg6IGF1dG87fQpkaXYuaGFuZ2luZy1pbmRlbnR7bWFyZ2luLWxlZnQ6IDEuNWVtOyB0ZXh0LWluZGVudDogLTEuNWVtO30KLyogVGhlIGV4dHJhIFtjbGFzc10gaXMgYSBoYWNrIHRoYXQgaW5jcmVhc2VzIHNwZWNpZmljaXR5IGVub3VnaCB0bwoJICAgb3ZlcnJpZGUgYSBzaW1pbGFyIHJ1bGUgaW4gcmV2ZWFsLmpzICovCnVsLnRhc2stbGlzdFtjbGFzc117bGlzdC1zdHlsZTogbm9uZTt9CnVsLnRhc2stbGlzdCBsaSBpbnB1dFt0eXBlPSJjaGVja2JveCJdIHsKCWZvbnQtc2l6ZTogaW5oZXJpdDsKCXdpZHRoOiAwLjhlbTsKCW1hcmdpbjogMCAwLjhlbSAwLjJlbSAtMS42ZW07Cgl2ZXJ0aWNhbC1hbGlnbjogbWlkZGxlOwp9Ci5kaXNwbGF5Lm1hdGh7ZGlzcGxheTogYmxvY2s7IHRleHQtYWxpZ246IGNlbnRlcjsgbWFyZ2luOiAwLjVyZW0gYXV0bzt9Ci8qIENTUyBmb3Igc3ludGF4IGhpZ2hsaWdodGluZyAqLwpwcmUgPiBjb2RlLnNvdXJjZUNvZGUgeyB3aGl0ZS1zcGFjZTogcHJlOyBwb3NpdGlvbjogcmVsYXRpdmU7IH0KcHJlID4gY29kZS5zb3VyY2VDb2RlID4gc3BhbiB7IGxpbmUtaGVpZ2h0OiAxLjI1OyB9CnByZSA+IGNvZGUuc291cmNlQ29kZSA+IHNwYW46ZW1wdHkgeyBoZWlnaHQ6IDEuMmVtOyB9Ci5zb3VyY2VDb2RlIHsgb3ZlcmZsb3c6IHZpc2libGU7IH0KY29kZS5zb3VyY2VDb2RlID4gc3BhbiB7IGNvbG9yOiBpbmhlcml0OyB0ZXh0LWRlY29yYXRpb246IGluaGVyaXQ7IH0KZGl2LnNvdXJjZUNvZGUgeyBtYXJnaW46IDFlbSAwOyB9CnByZS5zb3VyY2V
|
|||
|
<!--[if lt IE 9]>
|
|||
|
<script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv-printshiv.min.js"></script>
|
|||
|
<![endif]-->
|
|||
|
</head>
|
|||
|
<body>
|
|||
|
<header id="title-block-header">
|
|||
|
<h1 class="title">Molerat Protocol Specification</h1>
|
|||
|
</header>
|
|||
|
<nav id="TOC" role="doc-toc">
|
|||
|
<ul>
|
|||
|
<li><a href="#molerat-v0.1.0-alpha" id="toc-molerat-v0.1.0-alpha"><span class="toc-section-number">1</span> molerat v0.1.0-alpha</a>
|
|||
|
<ul>
|
|||
|
<li><a href="#the-name" id="toc-the-name"><span class="toc-section-number">1.0.1</span> The Name</a></li>
|
|||
|
<li><a href="#inspiration" id="toc-inspiration"><span class="toc-section-number">1.0.2</span> Inspiration</a></li>
|
|||
|
<li><a href="#mascot" id="toc-mascot"><span class="toc-section-number">1.0.3</span> Mascot</a></li>
|
|||
|
<li><a href="#overview" id="toc-overview"><span class="toc-section-number">1.1</span> Overview</a></li>
|
|||
|
<li><a href="#molerat-uri-scheme" id="toc-molerat-uri-scheme"><span class="toc-section-number">1.2</span> Molerat URI Scheme</a></li>
|
|||
|
<li><a href="#requests" id="toc-requests"><span class="toc-section-number">1.3</span> Requests</a>
|
|||
|
<ul>
|
|||
|
<li><a href="#get" id="toc-get"><span class="toc-section-number">1.3.1</span> Get</a></li>
|
|||
|
<li><a href="#put" id="toc-put"><span class="toc-section-number">1.3.2</span> Put</a></li>
|
|||
|
<li><a href="#del" id="toc-del"><span class="toc-section-number">1.3.3</span> Del</a></li>
|
|||
|
<li><a href="#all-three" id="toc-all-three"><span class="toc-section-number">1.3.4</span> All three</a></li>
|
|||
|
</ul></li>
|
|||
|
<li><a href="#responses" id="toc-responses"><span class="toc-section-number">1.4</span> Responses</a></li>
|
|||
|
<li><a href="#status-codes" id="toc-status-codes"><span class="toc-section-number">1.5</span> Status Codes</a>
|
|||
|
<ul>
|
|||
|
<li><a href="#x-codes" id="toc-x-codes"><span class="toc-section-number">1.5.1</span> 1x Codes</a></li>
|
|||
|
<li><a href="#x-codes-1" id="toc-x-codes-1"><span class="toc-section-number">1.5.2</span> 2x Codes</a></li>
|
|||
|
<li><a href="#x-codes-2" id="toc-x-codes-2"><span class="toc-section-number">1.5.3</span> 3x Codes</a></li>
|
|||
|
<li><a href="#x-codes-3" id="toc-x-codes-3"><span class="toc-section-number">1.5.4</span> 4x Codes</a></li>
|
|||
|
<li><a href="#x-codes-4" id="toc-x-codes-4"><span class="toc-section-number">1.5.5</span> 5x Codes</a></li>
|
|||
|
</ul></li>
|
|||
|
<li><a href="#mime-types" id="toc-mime-types"><span class="toc-section-number">1.6</span> MIME Types</a></li>
|
|||
|
<li><a href="#tls" id="toc-tls"><span class="toc-section-number">1.7</span> TLS</a>
|
|||
|
<ul>
|
|||
|
<li><a href="#client" id="toc-client"><span class="toc-section-number">1.7.1</span> Client</a></li>
|
|||
|
<li><a href="#validation" id="toc-validation"><span class="toc-section-number">1.7.2</span> Validation</a></li>
|
|||
|
</ul></li>
|
|||
|
<li><a href="#molerat-text-mtxt" id="toc-molerat-text-mtxt"><span class="toc-section-number">1.8</span> Molerat Text (<code>mtxt</code>)</a>
|
|||
|
<ul>
|
|||
|
<li><a href="#headings" id="toc-headings"><span class="toc-section-number">1.8.1</span> Headings</a></li>
|
|||
|
<li><a href="#text" id="toc-text"><span class="toc-section-number">1.8.2</span> Text</a></li>
|
|||
|
<li><a href="#subtext-formatting" id="toc-subtext-formatting"><span class="toc-section-number">1.8.3</span> Subtext formatting</a></li>
|
|||
|
<li><a href="#links-and-inline-media" id="toc-links-and-inline-media"><span class="toc-section-number">1.8.4</span> Links and Inline Media</a></li>
|
|||
|
<li><a href="#lists" id="toc-lists"><span class="toc-section-number">1.8.5</span> Lists</a></li>
|
|||
|
<li><a href="#code-blocks" id="toc-code-blocks"><span class="toc-section-number">1.8.6</span> Code Blocks</a></li>
|
|||
|
<li><a href="#horizontal-breaks" id="toc-horizontal-breaks"><span class="toc-section-number">1.8.7</span> Horizontal Breaks</a></li>
|
|||
|
<li><a href="#input" id="toc-input"><span class="toc-section-number">1.8.8</span> Input</a></li>
|
|||
|
<li><a href="#submitting-input" id="toc-submitting-input"><span class="toc-section-number">1.8.9</span> Submitting Input</a></li>
|
|||
|
<li><a href="#input-form-flow" id="toc-input-form-flow"><span class="toc-section-number">1.8.10</span> Input Form Flow</a></li>
|
|||
|
</ul></li>
|
|||
|
</ul></li>
|
|||
|
</ul>
|
|||
|
</nav>
|
|||
|
<main>
|
|||
|
<h1 data-number="1" id="molerat-v0.1.0-alpha"><span class="header-section-number">1</span> molerat v0.1.0-alpha</h1>
|
|||
|
<p>Molerat is <em>yet another</em> protocol like Gemini or <code>http</code>/<code>html</code>/<code>css</code>. It features extended functionality over Gemini while keeping a low bar-of-entry.</p>
|
|||
|
<h3 data-number="1.0.1" id="the-name"><span class="header-section-number">1.0.1</span> The Name</h3>
|
|||
|
<p>In nature, naked mole-rats are unusually resistant to cancer. This reflects the philosophy of Molerat- to provide a useable platform, resistant to feature creep.</p>
|
|||
|
<p>Not only are naked mole-rats highly resistant to cancer, but they also have unusually long life-spans for rodents. This is interpreted as a good omen for the Molerat project- may it live a long and cancer-free life.</p>
|
|||
|
<h3 data-number="1.0.2" id="inspiration"><span class="header-section-number">1.0.2</span> Inspiration</h3>
|
|||
|
<p>Molerat is heavily inspired by <code>http</code> and Gemini choosing to adopt many principles from both. A core philosophy for Molerat is <em>don’t do it differently just because someone else is already doing it</em>. This is also known as <em>steal good features</em>.</p>
|
|||
|
<h3 data-number="1.0.3" id="mascot"><span class="header-section-number">1.0.3</span> Mascot</h3>
|
|||
|
<p>Molerat is represented by <em>Potat</em> the naked mole-rat.</p>
|
|||
|
<figure>
|
|||
|
<img src="data:image/png;base64,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
|
|||
|
<figcaption aria-hidden="true">Potat, the naked mole-rat.</figcaption>
|
|||
|
</figure>
|
|||
|
<h2 data-number="1.1" id="overview"><span class="header-section-number">1.1</span> Overview</h2>
|
|||
|
<p>molerat adopts the <code>TOFU TLS</code> <span class="sidenote-wrapper"><label for="sn-0" class="margin-toggle sidenote-number"></label><input type="checkbox" id="sn-0" class="margin-toggle"><span class="sidenote">TOFU TLS stands for <strong>t</strong>rust <strong>o</strong>n <strong>f</strong>irst <strong>u</strong>se <strong>t</strong>ransport <strong>l</strong>ayer <strong>s</strong>ecurity. It is a system of securing against MITM (<strong>m</strong>an <strong>i</strong>n <strong>t</strong>he <strong>m</strong>iddle) attacks where a malicious actor impersonates the server in order to serve altered content.<br>
|
|||
|
<br>
|
|||
|
</span></span> standard from Gemini. TOFU works by storing an id or key for a specific server. On future connections, the client will check to make sure the key still matches the original. If it does not it will produce an error and alert the user as the client may be connected to an impersonator instead.</p>
|
|||
|
<p>For data transfer, Molerat uses <em>request</em> and <em>response</em> headers to define different types of operations like getting, or putting data.</p>
|
|||
|
<p>For markup, Molerat uses a markdown-like syntax to define page content like links, text formats, and user-interaction.</p>
|
|||
|
<h2 data-number="1.2" id="molerat-uri-scheme"><span class="header-section-number">1.2</span> Molerat URI Scheme</h2>
|
|||
|
<p>Molerat mostly conforms to the base URI syntax defined in <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-6.2.3">RFC 3986</a>. Similar to Gemini, Molerat does not use the <code>userinfo</code> component of URIs.</p>
|
|||
|
<p>Molerat URIs use the scheme <em>“molerat”</em> and a default port of <code>2693</code>.</p>
|
|||
|
<h2 data-number="1.3" id="requests"><span class="header-section-number">1.3</span> Requests</h2>
|
|||
|
<p>Basic Molerat requests are built using the format</p>
|
|||
|
<pre class="plain"><code><kind> <url>
|
|||
|
<crlf>
|
|||
|
<crlf></code></pre>
|
|||
|
<p>Where</p>
|
|||
|
<ul>
|
|||
|
<li><code>kind</code> corresponds to the type of request being made.</li>
|
|||
|
<li><code>url</code> corresponds to the URL of the content being requested.</li>
|
|||
|
<li><code>crlf</code> corresponds to a <em>carriage-return line-feed</em>, or <code>\r\n</code>.</li>
|
|||
|
</ul>
|
|||
|
<p>Molerat supports three different request types. Those are;</p>
|
|||
|
<ul>
|
|||
|
<li><code>get</code></li>
|
|||
|
<li><code>put</code></li>
|
|||
|
<li><code>del</code></li>
|
|||
|
</ul>
|
|||
|
<h3 data-number="1.3.1" id="get"><span class="header-section-number">1.3.1</span> Get</h3>
|
|||
|
<p>In Molerat, <code>get</code> is used to request content from a server. The server need only respond with the content, no other action is necessary.</p>
|
|||
|
<p>Here is an example <code>get</code> request for the content at <code>molerat://example.com/</code>:</p>
|
|||
|
<pre class="plain"><code>get example.com/</code></pre>
|
|||
|
<p>To get the content at <code>molerat://example.com/resource</code></p>
|
|||
|
<pre class="plain"><code>get example.com/resource</code></pre>
|
|||
|
<p>To get the content at <code>molerat://example.com/path/to/resource?with=query#and-fragment</code></p>
|
|||
|
<pre class="plain"><code>get example.com/path/to/resource?with=query#and-fragment</code></pre>
|
|||
|
<p>Note that every request <strong>must</strong> end with a double <code>crlf</code>. They are not visible when rendered on this page, however to a standard Molerat request in <code>bash</code> one would have to include them like this:</p>
|
|||
|
<div class="sourceCode" id="cb5"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a><span class="bu">echo</span> <span class="st">'get example.com/resource\r\n\r\n'</span></span></code></pre></div>
|
|||
|
<h3 data-number="1.3.2" id="put"><span class="header-section-number">1.3.2</span> Put</h3>
|
|||
|
<p><code>put</code> is used to send content to a server. What is done with that content is up to the server, but it is generally expected to update a record, or create a new one with the data provided. The server may then respond with a new page for the client to display.</p>
|
|||
|
<p><code>put</code> also includes the data being sent as a list of <code><key>:<value></code> records. These records are delimited by a <code><tab><crlf></code> and are formatted as <code><key>:<value></code>. A <code><tab><crlf></code> following the final key is optional.</p>
|
|||
|
<p>Here is an example of a <code>put</code> request to submit a username/password for a login page:</p>
|
|||
|
<pre class="plain"><code>put example.com/login
|
|||
|
length:32
|
|||
|
hash:02f53083ac99d85db16d2226b370c8137e6d2f4f8a5a52dad84d12d6a9f6f471
|
|||
|
|
|||
|
username:potat
|
|||
|
password:molerat</code></pre>
|
|||
|
<p>As you can see, there are two separate sections to a form. These sections are delimited with a <code>\r\n\r\n</code> and they give the server information about the form being submitted. For more information on these header keys, see <a href="#responses">Section 3.4</a></p>
|
|||
|
<p>Multi line form values are also allowed as long as they do not contain a <code>tab</code> directly followed by a <code>crlf</code>:</p>
|
|||
|
<pre class="plain"><code>put example.com/submit/story
|
|||
|
length:64
|
|||
|
hash:336ef7e928bfa7de38f84917a976728daca6e67160e6aac7b9fa6ec16784151d
|
|||
|
|
|||
|
username:potat
|
|||
|
story:Once upon a time...
|
|||
|
There was a beautiful naked mole-rat named Potat. Potat loved things such as marshmallows and stargazing, he found every part of his life to be enjoyable.</code></pre>
|
|||
|
<p>Keys <strong>must</strong> not be empty. For example, this would be an invalid <code>put</code> request:</p>
|
|||
|
<pre class="plain"><code>put example.com/submit/story
|
|||
|
length:22
|
|||
|
hash:3a9d888ce6913876fdc2258fac9f31aacaa222fa4258f394a22a3f58d4586375
|
|||
|
|
|||
|
username:potat
|
|||
|
story:</code></pre>
|
|||
|
<p>Servers implementing the Molerat protocol should reject <code>put</code> requests with empty keys.</p>
|
|||
|
<p>Note that keys can, however, be solely whitespace. This counts as <em>not</em> being an empty key.</p>
|
|||
|
<p>Here is a valid <code>put</code> request printed in <code>bash</code>:</p>
|
|||
|
<div class="sourceCode" id="cb9"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb9-1"><a href="#cb9-1" aria-hidden="true" tabindex="-1"></a><span class="bu">echo</span> <span class="st">'put example.com/login\r\nlength:64\t\r\nhash:336ef7e928bfa7de38f84917a976728daca6e67160e6aac7b9fa6ec16784151d\r\n\r\nusername:potat\t\r\npassword:molerat'</span></span></code></pre></div>
|
|||
|
<h3 data-number="1.3.3" id="del"><span class="header-section-number">1.3.3</span> Del</h3>
|
|||
|
<p><code>del</code> is used to delete a resource. It is syntactically the same as a <code>get</code> request. A <code>del</code> request can be used to clear up the <code>put</code> request. Since otherwise it would have to be used to request deletion of a resource in a server.</p>
|
|||
|
<p>Here is an example of a <code>del</code> request:</p>
|
|||
|
<pre class="plain"><code>del example.com/item/potat</code></pre>
|
|||
|
<p><code>del</code> can use the same form headers and content as <code>put</code>, so it is possible to send authentication via login/password with a <code>del</code> request.</p>
|
|||
|
<h3 data-number="1.3.4" id="all-three"><span class="header-section-number">1.3.4</span> All three</h3>
|
|||
|
<p>Here is an example of a typical user session on a theoretical social media site using Molerat requests:</p>
|
|||
|
<ol type="1">
|
|||
|
<li><code>get</code> other user’s posts:</li>
|
|||
|
</ol>
|
|||
|
<pre class="plain"><code>get example.com/</code></pre>
|
|||
|
<ol start="2" type="1">
|
|||
|
<li><code>put</code> a post:</li>
|
|||
|
</ol>
|
|||
|
<pre class="plain"><code>put example.com/posts
|
|||
|
username:potat
|
|||
|
content:Hi! I'm the new mascot for the Molerat protocol!</code></pre>
|
|||
|
<ol start="3" type="1">
|
|||
|
<li><code>del</code> an older post:</li>
|
|||
|
</ol>
|
|||
|
<pre class="plain"><code>del example.com/posts/1</code></pre>
|
|||
|
<ol start="4" type="1">
|
|||
|
<li>View other posts:</li>
|
|||
|
</ol>
|
|||
|
<pre class="plain"><code>get example.com/posts</code></pre>
|
|||
|
<h2 data-number="1.4" id="responses"><span class="header-section-number">1.4</span> Responses</h2>
|
|||
|
<p>Molerat formats responses as</p>
|
|||
|
<pre class="plain"><code>status<crlf>
|
|||
|
message:<value><tab>
|
|||
|
<crlf>
|
|||
|
type:<value><tab>
|
|||
|
<crlf>
|
|||
|
length:<value><tab>
|
|||
|
<crlf>
|
|||
|
hash:<value>
|
|||
|
<crlf>
|
|||
|
<crlf>
|
|||
|
<content></code></pre>
|
|||
|
<p>Where</p>
|
|||
|
<ul>
|
|||
|
<li><code>status</code> corresponds to the status code of the request. See below for more information on available status codes.</li>
|
|||
|
<li><code>message</code> is an optional message from the server to the client. It can be used to send error messages or context-specific messages.</li>
|
|||
|
<li><code>type</code> corresponds to the MIME Type of the data being sent. <span class="sidenote-wrapper"><label for="sn-1" class="margin-toggle sidenote-number"></label><input type="checkbox" id="sn-1" class="margin-toggle"><span class="sidenote">The recognized list of MIME types is available at <a href="https://www.iana.org/assignments/media-types/media-types.xhtml">www.iana.org/assignments/media-types/media-types.xhtml</a>. A valid MIME definition is defined in <a href="https://datatracker.ietf.org/doc/html/rfc2046">RFC 2046</a>.<br>
|
|||
|
<br>
|
|||
|
</span></span></li>
|
|||
|
<li><code>length</code> is the decimal byte-length of of the content being sent.</li>
|
|||
|
<li><code>hash</code> is a unique identifier for that page. It is suggested to be a <code>sha256</code> hash. But the only requirement is that it be 1024 or fewer bytes.</li>
|
|||
|
<li><code>content</code> is the raw data for the client to display.</li>
|
|||
|
</ul>
|
|||
|
<p>In a response containing no content, <code>length</code> and <code>hash</code> should <strong>not</strong> be included. Additionally, the <code>type</code> component should not be included.</p>
|
|||
|
<p>Molerat responses are really just key-values with an optional content section at the end<span class="sidenote-wrapper"><label for="sn-2" class="margin-toggle sidenote-number"></label><input type="checkbox" id="sn-2" class="margin-toggle"><span class="sidenote">Note that the exception to this is the <code>status</code> field. Status is just the first line of the response indicating the server and response status.<br>
|
|||
|
<br>
|
|||
|
</span></span>. Here is another way to write the template above:</p>
|
|||
|
<pre class="plain"><code>status
|
|||
|
message:
|
|||
|
type:
|
|||
|
length:
|
|||
|
hash:
|
|||
|
|
|||
|
<content></code></pre>
|
|||
|
<p>Here is an example valid call and response for a <code>get</code> request:</p>
|
|||
|
<p>Request:</p>
|
|||
|
<pre class="plain"><code>get example.com/</code></pre>
|
|||
|
<p>Response:</p>
|
|||
|
<pre class="plain"><code>10
|
|||
|
message:Success
|
|||
|
type:text/plain
|
|||
|
length:18
|
|||
|
hash:c28de73edf48cbc93eafb11f7266fc2268b9c7c77f9df02e74e0561e6cea7595
|
|||
|
|
|||
|
Hello, from Potat.</code></pre>
|
|||
|
<p>Or, using escape codes:</p>
|
|||
|
<div class="sourceCode" id="cb19"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb19-1"><a href="#cb19-1" aria-hidden="true" tabindex="-1"></a><span class="co"># Request</span></span>
|
|||
|
<span id="cb19-2"><a href="#cb19-2" aria-hidden="true" tabindex="-1"></a><span class="bu">echo</span> <span class="st">'get example.com/\r\n\r\n'</span></span>
|
|||
|
<span id="cb19-3"><a href="#cb19-3" aria-hidden="true" tabindex="-1"></a></span>
|
|||
|
<span id="cb19-4"><a href="#cb19-4" aria-hidden="true" tabindex="-1"></a><span class="co"># Response</span></span>
|
|||
|
<span id="cb19-5"><a href="#cb19-5" aria-hidden="true" tabindex="-1"></a><span class="bu">echo</span> <span class="st">'10\r\nmessage:Success\t\r\ntype:text/plain\t\r\nlength:18\t\r\nhash:c28de73edf48cbc93eafb11f7266fc2268b9c7c77f9df02e74e0561e6cea7595\r\n\r\n'</span></span></code></pre></div>
|
|||
|
<p>Note that as with <code>put</code> requests, the final form delimiter <code><tab><crlf></code> is not necessary in a response.</p>
|
|||
|
<p>Molerat mandates a <code>hash</code> key to allow clients to optionally cache pages. It should not be used to reliably validate them, however. Instead, a client may read the <code>hash</code> key before allocating memory to load the content, and if it finds an identical one in it’s store, it may display that page instead. This can be used to ease-up on network strain for long documents, as Molerat does not support compression during transport.</p>
|
|||
|
<p>Clients are not required to keep a hash cache, and if they do, user options to control the hash should be available.</p>
|
|||
|
<h2 data-number="1.5" id="status-codes"><span class="header-section-number">1.5</span> Status Codes</h2>
|
|||
|
<p>Molerat specifies several types of responses status codes:</p>
|
|||
|
<ul>
|
|||
|
<li><code>1x</code> codes are used for success messages.</li>
|
|||
|
<li><code>2x</code> codes indicate redirection.</li>
|
|||
|
<li><code>3x</code> codes indicate client errors.</li>
|
|||
|
<li><code>4x</code> codes indicate server errors.</li>
|
|||
|
<li><code>5x</code> codes are used for TLS signatures.</li>
|
|||
|
</ul>
|
|||
|
<h3 data-number="1.5.1" id="x-codes"><span class="header-section-number">1.5.1</span> 1x Codes</h3>
|
|||
|
<p>1x codes are success messages. They indicate that the client request has succeeded.</p>
|
|||
|
<h4 data-number="1.5.1.1" id="section"><span class="header-section-number">1.5.1.1</span> 10</h4>
|
|||
|
<p>Success. Everything went OK and the new page is attached.</p>
|
|||
|
<h4 data-number="1.5.1.2" id="section-1"><span class="header-section-number">1.5.1.2</span> 11</h4>
|
|||
|
<p>Content unchanged. The request was a success, but the client should not update the page.</p>
|
|||
|
<h3 data-number="1.5.2" id="x-codes-1"><span class="header-section-number">1.5.2</span> 2x Codes</h3>
|
|||
|
<p>2x codes indicate redirection. The server may tell the client see another resource. The redirect location should be an encoded URL in the <code>message</code> component of the response. The server may optionally include content to be displayed while the redirection is taking place.</p>
|
|||
|
<h4 data-number="1.5.2.1" id="section-2"><span class="header-section-number">1.5.2.1</span> 20</h4>
|
|||
|
<p>Permanent redirect. The client should not make further requests to this resource.</p>
|
|||
|
<h4 data-number="1.5.2.2" id="section-3"><span class="header-section-number">1.5.2.2</span> 21</h4>
|
|||
|
<p>Temporary redirect. The client should temporarily see another source, but not cache the redirect.</p>
|
|||
|
<h3 data-number="1.5.3" id="x-codes-2"><span class="header-section-number">1.5.3</span> 3x Codes</h3>
|
|||
|
<p>3x codes are for client errors. These should be sent as a response using the <code>message</code> component to explain the error. Servers may optionally include content to display a richer error to the user. Otherwise, the client should display a generated error page.</p>
|
|||
|
<h4 data-number="1.5.3.1" id="section-4"><span class="header-section-number">1.5.3.1</span> 30</h4>
|
|||
|
<p>Malformed request. Due to an error with the client, the server was unable to parse the request being sent.</p>
|
|||
|
<h4 data-number="1.5.3.2" id="section-5"><span class="header-section-number">1.5.3.2</span> 31</h4>
|
|||
|
<p>Invalid request. The server was able to parse the request, but the data included is not valid in this context. This code should be used for authentication failures and <code>put</code> requests containing data that the server cannot accept.</p>
|
|||
|
<h4 data-number="1.5.3.3" id="section-6"><span class="header-section-number">1.5.3.3</span> 32</h4>
|
|||
|
<p>Not available. The requested resource does not exist or is not available to the client. This code can be used for both nonexistent resources, and for cases where the client does not have access to the resource.</p>
|
|||
|
<h3 data-number="1.5.4" id="x-codes-3"><span class="header-section-number">1.5.4</span> 4x Codes</h3>
|
|||
|
<p>4x codes indicate an unrecoverable failure on the server. If possible, the server should catch internal errors and respond with a 4x code.</p>
|
|||
|
<h4 data-number="1.5.4.1" id="section-7"><span class="header-section-number">1.5.4.1</span> 40</h4>
|
|||
|
<p>Internal error. The server cannot proceed as it has encountered an error it does not know how to handle.</p>
|
|||
|
<h4 data-number="1.5.4.2" id="section-8"><span class="header-section-number">1.5.4.2</span> 41</h4>
|
|||
|
<p>Not supported. The server does not support or allow access to this resource by the client.</p>
|
|||
|
<h4 data-number="1.5.4.3" id="section-9"><span class="header-section-number">1.5.4.3</span> 42</h4>
|
|||
|
<p>Slow down. The client is being rate limited. The <code>message</code> component should be a number corresponding to the seconds a client must wait before making another request to the server.</p>
|
|||
|
<h3 data-number="1.5.5" id="x-codes-4"><span class="header-section-number">1.5.5</span> 5x Codes</h3>
|
|||
|
<p>5x codes are used for when the server requires a client key to access a resource.</p>
|
|||
|
<h4 data-number="1.5.5.1" id="section-10"><span class="header-section-number">1.5.5.1</span> 50</h4>
|
|||
|
<p>Client certificate required. The server requires that the client provides a certificate to proceed. The client should retry the request using a certificate.</p>
|
|||
|
<h2 data-number="1.6" id="mime-types"><span class="header-section-number">1.6</span> MIME Types</h2>
|
|||
|
<p>In responses, the server may specify any valid MIME type. It is up to the client to determine how best to display or open the file. Molerat also supports parameters for MIME types like <code>charset</code>. As with Gemini, the default charset is <code>UTF-8</code> for text content.</p>
|
|||
|
<h2 data-number="1.7" id="tls"><span class="header-section-number">1.7</span> TLS</h2>
|
|||
|
<p>Molerat chooses to adopt many standards from Gemini for TLS. As with Gemini, use of TLS for Molerat requests and responses is required. Additionally, as with Gemini, use of the Server Name Indication extension is TLS is also required. This allows multiple domains to be hosted on a single server while remaining secure.</p>
|
|||
|
<p>Molerat expects that clients and servers use TLS version 1.2 or higher.</p>
|
|||
|
<h3 data-number="1.7.1" id="client"><span class="header-section-number">1.7.1</span> Client</h3>
|
|||
|
<p>Clients may use certificate to identify themselves to a server, but a Molerat client should not use a certificate by default.</p>
|
|||
|
<p>If a resource requires a certificate (via the <code>50</code> status code) then the client should allow the user to specify whether to use a short-lived certificate, or a long-lived one.</p>
|
|||
|
<h3 data-number="1.7.2" id="validation"><span class="header-section-number">1.7.2</span> Validation</h3>
|
|||
|
<p>Molerat recommends the same methods of server certificate validation as Gemini (TOFU). Clients may validate server certificates however they want, including not at all<span class="sidenote-wrapper"><label for="sn-3" class="margin-toggle sidenote-number"></label><input type="checkbox" id="sn-3" class="margin-toggle"><span class="sidenote">No matter how a client validates a server certificate, it should always strive to be transparent with the user on how it does so.<br>
|
|||
|
<br>
|
|||
|
</span></span>.</p>
|
|||
|
<p>Molerat is a simple protocol, so the need for CA certificates is overly-complex. Of course, a client and server may implement it, but clients should . Of course, a client and server may implement it, but clients should accept self-signed keys by default.</p>
|
|||
|
<h2 data-number="1.8" id="molerat-text-mtxt"><span class="header-section-number">1.8</span> Molerat Text (<code>mtxt</code>)</h2>
|
|||
|
<p>Molerat text, or <code>mtxt</code>is the format that Molerat uses to present pre formatted text.</p>
|
|||
|
<p>mtxt supports several features, but not all of them must be implemented by every client. A server serving mtxt should use a MIME Type of <code>text/molerat</code>. Like Gemini, Molerat supports an optional <code>lang</code> parameter in addition to <code>charset</code>. Clients may use this for any purpose such as displaying text in the correct direction, or auto-translating to a different language. As with Gemini, the <code>lang</code> parameter accepts comma separated language tags from the IANA Language Registry <span class="sidenote-wrapper"><label for="sn-4" class="margin-toggle sidenote-number"></label><input type="checkbox" id="sn-4" class="margin-toggle"><span class="sidenote"><a href="https://www.iana.org/assignments/language-subtag-registry/language-subtag-registry">www.iana.org/assignments/language-subtag-registry/language-subtag-registry</a><br>
|
|||
|
<br>
|
|||
|
</span></span></p>
|
|||
|
<pre><code>...
|
|||
|
type:text/molerat; lang=en
|
|||
|
...</code></pre>
|
|||
|
<blockquote>
|
|||
|
<p>Specifies a mtxt document that is in English.</p>
|
|||
|
</blockquote>
|
|||
|
<h3 data-number="1.8.1" id="headings"><span class="header-section-number">1.8.1</span> Headings</h3>
|
|||
|
<p>Molerat supports three levels of heading denoted by a hashtag (<code>#</code>) and then a space. The number of <code>#</code>s denotes the level of heading.</p>
|
|||
|
<div class="sourceCode" id="cb21"><pre class="sourceCode md"><code class="sourceCode markdown"><span id="cb21-1"><a href="#cb21-1" aria-hidden="true" tabindex="-1"></a><span class="fu"># Title Heading</span></span>
|
|||
|
<span id="cb21-2"><a href="#cb21-2" aria-hidden="true" tabindex="-1"></a></span>
|
|||
|
<span id="cb21-3"><a href="#cb21-3" aria-hidden="true" tabindex="-1"></a><span class="fu">## Subtitle Heading</span></span>
|
|||
|
<span id="cb21-4"><a href="#cb21-4" aria-hidden="true" tabindex="-1"></a></span>
|
|||
|
<span id="cb21-5"><a href="#cb21-5" aria-hidden="true" tabindex="-1"></a><span class="fu">### Sub-Subtitle Heading</span></span></code></pre></div>
|
|||
|
<p>Rendered in HTML, it would look like this:</p>
|
|||
|
<hr>
|
|||
|
<h1>
|
|||
|
Title Heading
|
|||
|
</h1>
|
|||
|
<h2>
|
|||
|
Subtitle Heading
|
|||
|
</h2><h2>
|
|||
|
</h2><h3>
|
|||
|
Sub-Subtitle Heading
|
|||
|
</h3><h3>
|
|||
|
<hr>
|
|||
|
</h3><h3 data-number="1.8.2" id="text"><span class="header-section-number">1.8.2</span> Text</h3>
|
|||
|
<p>Regular text is simply written on a standalone line. Line breaks are ignored unless there are two in a row. <code>mtxt</code> should not be manually line-wrapped when written, clients should instead choose how and where to wrap text.</p>
|
|||
|
<div class="sourceCode" id="cb22"><pre class="sourceCode md"><code class="sourceCode markdown"><span id="cb22-1"><a href="#cb22-1" aria-hidden="true" tabindex="-1"></a>This is a regular paragraph. The client will choose when to break the line, to better accommodate the user and their device.</span>
|
|||
|
<span id="cb22-2"><a href="#cb22-2" aria-hidden="true" tabindex="-1"></a></span>
|
|||
|
<span id="cb22-3"><a href="#cb22-3" aria-hidden="true" tabindex="-1"></a></span>
|
|||
|
<span id="cb22-4"><a href="#cb22-4" aria-hidden="true" tabindex="-1"></a>This line has a break,</span>
|
|||
|
<span id="cb22-5"><a href="#cb22-5" aria-hidden="true" tabindex="-1"></a>but it will not show up when rendered since it is only one break. </span>
|
|||
|
<span id="cb22-6"><a href="#cb22-6" aria-hidden="true" tabindex="-1"></a>People can use a single line break to make it easier to write</span>
|
|||
|
<span id="cb22-7"><a href="#cb22-7" aria-hidden="true" tabindex="-1"></a>mtxt without changing the end-result.</span>
|
|||
|
<span id="cb22-8"><a href="#cb22-8" aria-hidden="true" tabindex="-1"></a></span>
|
|||
|
<span id="cb22-9"><a href="#cb22-9" aria-hidden="true" tabindex="-1"></a></span>
|
|||
|
<span id="cb22-10"><a href="#cb22-10" aria-hidden="true" tabindex="-1"></a>This line has a manual break,</span>
|
|||
|
<span id="cb22-11"><a href="#cb22-11" aria-hidden="true" tabindex="-1"></a></span>
|
|||
|
<span id="cb22-12"><a href="#cb22-12" aria-hidden="true" tabindex="-1"></a>This line will show up on a new line after the previous.</span>
|
|||
|
<span id="cb22-13"><a href="#cb22-13" aria-hidden="true" tabindex="-1"></a></span>
|
|||
|
<span id="cb22-14"><a href="#cb22-14" aria-hidden="true" tabindex="-1"></a>People can use this to separate paragraphs, and other distinguished content.</span></code></pre></div>
|
|||
|
<p>This is how the previous text should look:</p>
|
|||
|
<hr>
|
|||
|
<p>This is a regular paragraph. The client will choose when to break the line, to better accommodate the user and their device.</p>
|
|||
|
<p>This line has a break, but it will not show up when rendered since it is only one break. People can use a single line break to make it easier to write mtxt without changing the end-result.</p>
|
|||
|
<p>This line has a manual break,</p>
|
|||
|
<p>This line will show up on a new line after the previous.</p>
|
|||
|
<p>People can use this to separate paragraphs, and other distinguished content.</p>
|
|||
|
<hr>
|
|||
|
<h3 data-number="1.8.3" id="subtext-formatting"><span class="header-section-number">1.8.3</span> Subtext formatting</h3>
|
|||
|
<p>Like Markdown, asterisks (<code>*</code>) can be used to format text inside a paragraph.</p>
|
|||
|
<div class="sourceCode" id="cb23"><pre class="sourceCode md"><code class="sourceCode markdown"><span id="cb23-1"><a href="#cb23-1" aria-hidden="true" tabindex="-1"></a>*This text is italic*</span>
|
|||
|
<span id="cb23-2"><a href="#cb23-2" aria-hidden="true" tabindex="-1"></a></span>
|
|||
|
<span id="cb23-3"><a href="#cb23-3" aria-hidden="true" tabindex="-1"></a>**This text is bold**</span>
|
|||
|
<span id="cb23-4"><a href="#cb23-4" aria-hidden="true" tabindex="-1"></a></span>
|
|||
|
<span id="cb23-5"><a href="#cb23-5" aria-hidden="true" tabindex="-1"></a>***This text is italic and bold***</span></code></pre></div>
|
|||
|
<hr>
|
|||
|
<p><em>This text is italic</em></p>
|
|||
|
<p><strong>This text is bold</strong></p>
|
|||
|
<p><strong><em>This text is italic and bold</em></strong></p>
|
|||
|
<hr>
|
|||
|
<p>Text surrounded by a single asterisk will be italic, double asterisks will be bold, and triple asterisks should be italic and bold. Asterisks should not style text if surrounded by whitespace.</p>
|
|||
|
<div class="sourceCode" id="cb24"><pre class="sourceCode md"><code class="sourceCode markdown"><span id="cb24-1"><a href="#cb24-1" aria-hidden="true" tabindex="-1"></a><span class="an">This word is italic:</span><span class="co"> *Potat*</span></span>
|
|||
|
<span id="cb24-2"><a href="#cb24-2" aria-hidden="true" tabindex="-1"></a></span>
|
|||
|
<span id="cb24-3"><a href="#cb24-3" aria-hidden="true" tabindex="-1"></a>This word is NOT italic: *Potat *</span>
|
|||
|
<span id="cb24-4"><a href="#cb24-4" aria-hidden="true" tabindex="-1"></a></span>
|
|||
|
<span id="cb24-5"><a href="#cb24-5" aria-hidden="true" tabindex="-1"></a>Neither is this one: * Potat*</span>
|
|||
|
<span id="cb24-6"><a href="#cb24-6" aria-hidden="true" tabindex="-1"></a></span>
|
|||
|
<span id="cb24-7"><a href="#cb24-7" aria-hidden="true" tabindex="-1"></a>And DEFINITELY not this one: * Potat *</span></code></pre></div>
|
|||
|
<hr>
|
|||
|
<p>This word is italic: <em>Potat</em></p>
|
|||
|
<p>This word is NOT italic: *Potat *</p>
|
|||
|
<p>Neither is this one: * Potat*</p>
|
|||
|
<p>And DEFINITELY not this one: * Potat *</p>
|
|||
|
<hr>
|
|||
|
<p>Asterisks can be escaped with a backslash (<code>\</code>) character.</p>
|
|||
|
<div class="sourceCode" id="cb25"><pre class="sourceCode md"><code class="sourceCode markdown"><span id="cb25-1"><a href="#cb25-1" aria-hidden="true" tabindex="-1"></a>*I should be italic, but I'm not<span class="sc">\*</span></span>
|
|||
|
<span id="cb25-2"><a href="#cb25-2" aria-hidden="true" tabindex="-1"></a></span>
|
|||
|
<span id="cb25-3"><a href="#cb25-3" aria-hidden="true" tabindex="-1"></a><span class="sc">\*</span>I have fallen to the same predicament*</span>
|
|||
|
<span id="cb25-4"><a href="#cb25-4" aria-hidden="true" tabindex="-1"></a></span>
|
|||
|
<span id="cb25-5"><a href="#cb25-5" aria-hidden="true" tabindex="-1"></a><span class="sc">\*</span>I have too...<span class="sc">\*</span></span></code></pre></div>
|
|||
|
<hr>
|
|||
|
<p>*I should be italic, but I’m not*</p>
|
|||
|
<p>*I have fallen to the same predicament*</p>
|
|||
|
<p>*I have too…*</p>
|
|||
|
<hr>
|
|||
|
<h3 data-number="1.8.4" id="links-and-inline-media"><span class="header-section-number">1.8.4</span> Links and Inline Media</h3>
|
|||
|
<p>Inline links can be specified via the <code>[[</code> and <code>]]</code> Characters. Links can link to any type of content like mtxt, images, audio, videos, and even to other pages on other protocols.</p>
|
|||
|
<p>The following is a link to another Molerat page:</p>
|
|||
|
<pre class="mtxt"><code>[[This links to example.com!]molerat://example.com]</code></pre>
|
|||
|
<p>It would be displayed like this:</p>
|
|||
|
<p><a href="molerat://example.com">This links to example.com!</a></p>
|
|||
|
<p>A link in mtxt consists of three parts:</p>
|
|||
|
<ul>
|
|||
|
<li>The display text.</li>
|
|||
|
<li>The URL.</li>
|
|||
|
<li>The media type.</li>
|
|||
|
</ul>
|
|||
|
<h4 data-number="1.8.4.1" id="display-text"><span class="header-section-number">1.8.4.1</span> Display Text</h4>
|
|||
|
<p>In a link, the text at the very center of the double braces (<code>[[</code> and <code>]]</code>) is the text that the client should display to the user. If no text is specified, then the client should display the URL.</p>
|
|||
|
<h4 data-number="1.8.4.2" id="the-url"><span class="header-section-number">1.8.4.2</span> The URL</h4>
|
|||
|
<p>The URL is a link to the resource that the client should fetch. It is located on the right-hand side of the double braces. If there is no protocol (or <code>scheme</code>) specified (like <code>http://</code>, <code>gemini://</code>, or <code>molerat://</code>), then the client should treat the URL as a relative link on the same website. <span class="sidenote-wrapper"><label for="sn-5" class="margin-toggle sidenote-number"></label><input type="checkbox" id="sn-5" class="margin-toggle"><span class="sidenote">i.e. if a URL is <code>/about</code>, and the user is on <code>molerat://example.com/login</code>, then the client should interpret the URL as <code>molerat://example.com/about</code>.<br>
|
|||
|
<br>
|
|||
|
</span></span></p>
|
|||
|
<h4 data-number="1.8.4.3" id="the-media-type"><span class="header-section-number">1.8.4.3</span> The Media Type</h4>
|
|||
|
<p>The media type goes on the left-hand side of the double braces and specifies the type of data that is being linked to. By default, it is <code>mtxt</code>, so it can be left blank for regular links to other webpages.</p>
|
|||
|
<p>If the link is to a media-type that is uncommon, or widely unsupported by the client, then the media type may be a MIME type.</p>
|
|||
|
<p>Molerat also supports several shorthand media types.</p>
|
|||
|
<ul>
|
|||
|
<li><code>!</code> - Denotes an image of types <code>image/png</code> or <code>image/jpeg</code>.</li>
|
|||
|
<li><code>.</code> - Denotes a video of type <code>video/mp4</code>.</li>
|
|||
|
<li><code>"</code> - Denotes an audio clip of types <code>audio/mp4</code>, <code>audio/mp3</code>, or <code>audio/wav</code>.</li>
|
|||
|
<li><code>#</code> - Is for <em>auto</em>. The client should guess how to display the content to the best of it’s abilities. Clients are not required to do anything for <code>auto</code> Media types, but they should offer the ability to open or download the linked media.</li>
|
|||
|
<li><code>-</code> - Can be used to force the client to treat the link as a text link.</li>
|
|||
|
</ul>
|
|||
|
<p>Here are some examples:</p>
|
|||
|
<pre class="mtxt"><code>[[see here for more info]molerat://example.com/info]</code></pre>
|
|||
|
<p>Links to <code>molerat://example.com/info</code> and has the text “see here for more info”. It looks like this:</p>
|
|||
|
<p><a href="molerat://example.com">see here for more info</a></p>
|
|||
|
<hr>
|
|||
|
<pre class="mtxt"><code>[[]molerat://example.com]</code></pre>
|
|||
|
<p>Links to <code>molerat://example.com</code> without any text. It looks like this:</p>
|
|||
|
<p><a href="molerat://example.com">molerat://example.com</a></p>
|
|||
|
<hr>
|
|||
|
<pre class="mtxt"><code>[![A naked mole-rat.]https://upload.wikimedia.org/wikipedia/commons/0/02/Nacktmull.jpg]</code></pre>
|
|||
|
<p>If the client supports it, this will embed an image into the text content. Otherwise it will appear as a link<span class="sidenote-wrapper"><label for="sn-6" class="margin-toggle sidenote-number"></label><input type="checkbox" id="sn-6" class="margin-toggle"><span class="sidenote">Clients without image support should provide some visual way to distinguish regular links and images.<br>
|
|||
|
<br>
|
|||
|
</span></span>. Images with display text should use it as an <em>alt text</em> for screen readers.</p>
|
|||
|
<p>It should look like this:</p>
|
|||
|
<figure>
|
|||
|
<img src="data:image/jpeg;base64,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
|
|||
|
<figcaption aria-hidden="true">A naked mole-rat.</figcaption>
|
|||
|
</figure>
|
|||
|
<hr>
|
|||
|
<pre class="mtxt"><code>[#[Mystery media.]molerat://example.com/media]</code></pre>
|
|||
|
<p>For links with the <code>#</code> media type, the client should use the <code>type</code> parameter from the server if the link uses the <code>molerat://</code> scheme. Otherwise, the client may do anything (or nothing at all) to discern the type of media.</p>
|
|||
|
<hr>
|
|||
|
<pre class="mtxt"><code>[-[An image of a naked mole-rat.]https://upload.wikimedia.org/wikipedia/commons/0/02/Nacktmull.jpg]</code></pre>
|
|||
|
<p>This link uses the <code>-</code> media type which means that the client should not attempt to display it as an inline image. Instead, it should look like this:</p>
|
|||
|
<p><a href="https://upload.wikimedia.org/wikipedia/commons/0/02/Nacktmull.jpg">An image of a naked mole-rat.</a></p>
|
|||
|
<h3 data-number="1.8.5" id="lists"><span class="header-section-number">1.8.5</span> Lists</h3>
|
|||
|
<p>Lists in mtxt can be ordered or unordered.</p>
|
|||
|
<h4 data-number="1.8.5.1" id="unordered-lists"><span class="header-section-number">1.8.5.1</span> Unordered Lists</h4>
|
|||
|
<p>Unordered lists are any sequence of characters preceded by a <code>-</code> (dash) and a space.</p>
|
|||
|
<div class="sourceCode" id="cb32"><pre class="sourceCode md"><code class="sourceCode markdown"><span id="cb32-1"><a href="#cb32-1" aria-hidden="true" tabindex="-1"></a><span class="ss">- </span>item one</span>
|
|||
|
<span id="cb32-2"><a href="#cb32-2" aria-hidden="true" tabindex="-1"></a><span class="ss">- </span>item two</span>
|
|||
|
<span id="cb32-3"><a href="#cb32-3" aria-hidden="true" tabindex="-1"></a><span class="ss">- </span>item three</span></code></pre></div>
|
|||
|
<p>Would look like</p>
|
|||
|
<hr>
|
|||
|
<ul>
|
|||
|
<li>item one</li>
|
|||
|
<li>item two</li>
|
|||
|
<li>item three</li>
|
|||
|
</ul>
|
|||
|
<hr>
|
|||
|
<p>In <code>mtxt</code>, lists do not nest.</p>
|
|||
|
<h4 data-number="1.8.5.2" id="ordered-lists"><span class="header-section-number">1.8.5.2</span> Ordered Lists</h4>
|
|||
|
<p>Ordered lists are any sequence of lines beginning with a sequential number followed by a period and a space.</p>
|
|||
|
<pre class="mtxt"><code>1. item one
|
|||
|
2. item two
|
|||
|
3. item three</code></pre>
|
|||
|
<p>Would look like</p>
|
|||
|
<hr>
|
|||
|
<ol type="1">
|
|||
|
<li>item one</li>
|
|||
|
<li>item two</li>
|
|||
|
<li>item three</li>
|
|||
|
</ol>
|
|||
|
<hr>
|
|||
|
<p><code>mtxt</code> lists can start at any number.</p>
|
|||
|
<pre class="mtxt"><code>5. item one
|
|||
|
6. item two
|
|||
|
7. item three</code></pre>
|
|||
|
<p>Would look like</p>
|
|||
|
<hr>
|
|||
|
<ol start="5" type="1">
|
|||
|
<li>item one</li>
|
|||
|
<li>item two</li>
|
|||
|
<li>item three</li>
|
|||
|
</ol>
|
|||
|
<hr>
|
|||
|
<p>The only restriction is that the numbers must be sequential going up. This would be an invalid list in <code>mtxt</code>:</p>
|
|||
|
<pre class="mtxt"><code>1. item one
|
|||
|
5. item two.
|
|||
|
10. item three.</code></pre>
|
|||
|
<p>That means that numbers going down would also be invalid, here is an example of that:</p>
|
|||
|
<pre class="mtxt"><code>3. item one
|
|||
|
2. item two
|
|||
|
1. item three</code></pre>
|
|||
|
<h3 data-number="1.8.6" id="code-blocks"><span class="header-section-number">1.8.6</span> Code Blocks</h3>
|
|||
|
<p><code>mtxt</code> supports fenced code blocks. Fenced code blocks inherit the same format as Markdown.</p>
|
|||
|
<pre class="mtxt"><code>```
|
|||
|
#include <stdio.h>
|
|||
|
|
|||
|
int main(void) {
|
|||
|
printf("hello, world!\n");
|
|||
|
}
|
|||
|
```</code></pre>
|
|||
|
<p>Fenced code blocks can be any text enclosed in triple backticks (`). Code blocks will have their whitespace preserved. They should also be displayed in a way that distinguishes them from the rest of the document flow such as a mono font, or with a different background color. Exact implementation is up to clients.</p>
|
|||
|
<p>For example, the above example could be displayed like this:</p>
|
|||
|
<pre class="plain"><code>#include <stdio.h>
|
|||
|
|
|||
|
int main(void) {
|
|||
|
printf("hello, world!\n");
|
|||
|
}</code></pre>
|
|||
|
<p><code>mtxt</code> also supports language specifiers for code blocks. After the opening triple backticks, a language can be specified which the client may use for language highlighting or any other purpose.</p>
|
|||
|
<p>For example, a code block specifying that its contents are in the <code>c</code> language would look like this:</p>
|
|||
|
<pre class="plain"><code>```c
|
|||
|
#include <stdio.h>
|
|||
|
|
|||
|
int main(void) {
|
|||
|
printf("hello, world!\n");
|
|||
|
}
|
|||
|
```</code></pre>
|
|||
|
<p>There is no formal list of supported languages for syntax highlighting, but as a general rule, using the file’s extension name should work. <code>c</code> code should use <code>c</code>, <code>c++</code> code should use <code>cpp</code>, and <code>JavaScript</code> code should use <code>js</code>.</p>
|
|||
|
<p>The above code may be syntax highlighted by the client to look something like this:</p>
|
|||
|
<div class="sourceCode" id="cb40"><pre class="sourceCode c"><code class="sourceCode c"><span id="cb40-1"><a href="#cb40-1" aria-hidden="true" tabindex="-1"></a><span class="pp">#include </span><span class="im"><stdio.h></span></span>
|
|||
|
<span id="cb40-2"><a href="#cb40-2" aria-hidden="true" tabindex="-1"></a></span>
|
|||
|
<span id="cb40-3"><a href="#cb40-3" aria-hidden="true" tabindex="-1"></a><span class="dt">int</span> main<span class="op">(</span><span class="dt">void</span><span class="op">)</span> <span class="op">{</span></span>
|
|||
|
<span id="cb40-4"><a href="#cb40-4" aria-hidden="true" tabindex="-1"></a> printf<span class="op">(</span><span class="st">"hello, world!</span><span class="sc">\n</span><span class="st">"</span><span class="op">);</span></span>
|
|||
|
<span id="cb40-5"><a href="#cb40-5" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
|
|||
|
<p>Clients may force-wrap code blocks if necessary, but should avoid doing so to preserve the original formatting.</p>
|
|||
|
<h4 data-number="1.8.6.1" id="inline-code"><span class="header-section-number">1.8.6.1</span> Inline Code</h4>
|
|||
|
<p>In addition to code blocks, <code>mtxt</code> also supports inline code snippets. Inline code follows the same way as Subtext Formatting (see <a href="#subtext-formatting">Section 3.8.3</a>)</p>
|
|||
|
<p>This is an example of inline code:</p>
|
|||
|
<div class="sourceCode" id="cb41"><pre class="sourceCode md"><code class="sourceCode markdown"><span id="cb41-1"><a href="#cb41-1" aria-hidden="true" tabindex="-1"></a>I am an example paragraph. I have inline <span class="in">`code`</span> which can be inside the regular text.</span></code></pre></div>
|
|||
|
<h3 data-number="1.8.7" id="horizontal-breaks"><span class="header-section-number">1.8.7</span> Horizontal Breaks</h3>
|
|||
|
<p>Three dashes (<code>-</code>) alone on a line will become a horizontal break.</p>
|
|||
|
<pre class="mtxt"><code>Closing paragraph.
|
|||
|
|
|||
|
---
|
|||
|
|
|||
|
New paragraph.</code></pre>
|
|||
|
<p>This would be rendered like this:</p>
|
|||
|
<p>Closing paragraph.</p>
|
|||
|
<hr>
|
|||
|
<p>New paragraph.</p>
|
|||
|
<p>A client may display a horizontal break however it likes, but it should be clear that it is a separator between content.</p>
|
|||
|
<h3 data-number="1.8.8" id="input"><span class="header-section-number">1.8.8</span> Input</h3>
|
|||
|
<p><code>mtxt</code> allows for text input. An input field looks like this:</p>
|
|||
|
<pre class="mtxt"><code>|Placeholder text..|[id text]</code></pre>
|
|||
|
<p>That would look like this:</p>
|
|||
|
<p><input placeholder="Placeholder text.." id="id" type="text"></p>
|
|||
|
<p>Input fields are made up of three parts:</p>
|
|||
|
<ul>
|
|||
|
<li>Placeholder Text - The optional placeholder text to be displayed as a prompt for the input field.</li>
|
|||
|
<li>ID - The id of the input that will be used when the form is submitted.</li>
|
|||
|
<li>Type - The optional type of the input field.</li>
|
|||
|
</ul>
|
|||
|
<h4 data-number="1.8.8.1" id="placeholder-text"><span class="header-section-number">1.8.8.1</span> Placeholder text</h4>
|
|||
|
<p>Placeholder text is optional. If specified, it will be shown as a prompt for the input. Placeholder text does <strong>not</strong> support subtext formatting.</p>
|
|||
|
<p>Here is an example of an input <em>with</em> placeholder text:</p>
|
|||
|
<pre class="mtxt"><code>|Name|[id text]</code></pre>
|
|||
|
<p>It would look like this:</p>
|
|||
|
<p><input placeholder="Name" id="id" type="text"></p>
|
|||
|
<hr>
|
|||
|
<p>Without a placeholder text:</p>
|
|||
|
<pre class="mtxt"><code>||[id text]</code></pre>
|
|||
|
<p><input id="id" type="text"></p>
|
|||
|
<h4 data-number="1.8.8.2" id="id"><span class="header-section-number">1.8.8.2</span> ID</h4>
|
|||
|
<p>The id is the only mandatory part of an input field. It is what the client will use to identify this input field in the submit request. If two inputs have the same ID on the same page, the client should use the most recent unsubmitted one.</p>
|
|||
|
<h4 data-number="1.8.8.3" id="type"><span class="header-section-number">1.8.8.3</span> Type</h4>
|
|||
|
<p>The type is a hint to the client as to what data this form wishes to accept. The client may choose to disregard this, so servers should not expect input to be validated already.</p>
|
|||
|
<p>These are the types that clients <em>should</em> support:</p>
|
|||
|
<ul>
|
|||
|
<li><code>text</code> - The default option. Any text data.</li>
|
|||
|
<li><code>number</code> - Any numeric digits.</li>
|
|||
|
<li><code>time</code> - Any time in the <code>hours:minutes [AM|PM]</code> format. Clients should convert times into 24-hour time before submitting a form, although this is optional.</li>
|
|||
|
<li><code>date</code> - Any date in the <code>year-month-day</code> format.</li>
|
|||
|
<li><code>private</code> - Any data that should be hidden while typed, such as a password.</li>
|
|||
|
</ul>
|
|||
|
<h3 data-number="1.8.9" id="submitting-input"><span class="header-section-number">1.8.9</span> Submitting Input</h3>
|
|||
|
<p>To submit input forms on a page, there is a special element:</p>
|
|||
|
<pre class="mtxt"><code>|Submit|(/login get)</code></pre>
|
|||
|
<p>Depending on the client, this can be rendered as a link or a button:</p>
|
|||
|
<p><a href="file:///login" type="submit">Submit</a></p>
|
|||
|
<button type="submit">
|
|||
|
Submit
|
|||
|
</button>
|
|||
|
<p>Submit elements use parentheses (<code>(</code> and <code>)</code> ) instead of braces (<code>[</code> and <code>]</code>) to specify that they do not accept input, they merely submit it.</p>
|
|||
|
<p>Submit elements submit every input that came before it on a page. But they ignore inputs that come after themselves.</p>
|
|||
|
<p>A submit element is made up of three parts:</p>
|
|||
|
<ul>
|
|||
|
<li>The Name - The display text to show.</li>
|
|||
|
<li>The URL - The URL to send the submit request to.</li>
|
|||
|
<li>The Method - The Molerat method to use for the request like <code>get</code>, <code>put</code>, or <code>del</code>.</li>
|
|||
|
</ul>
|
|||
|
<h3 data-number="1.8.10" id="input-form-flow"><span class="header-section-number">1.8.10</span> Input Form Flow</h3>
|
|||
|
<p>Here is an example of a login page in <code>mtxt</code>:</p>
|
|||
|
<pre class="mtxt"><code># Login
|
|||
|
|
|||
|
Please login to the site below:
|
|||
|
|
|||
|
|username|[username text]
|
|||
|
|password|[password private]
|
|||
|
|
|||
|
|Login|(/login get)</code></pre>
|
|||
|
<p>This would look like this:</p>
|
|||
|
<hr>
|
|||
|
<div>
|
|||
|
<h1>
|
|||
|
Login
|
|||
|
</h1>
|
|||
|
<p>
|
|||
|
Please login to the site below:
|
|||
|
</p>
|
|||
|
<form action="file:///login" method="get">
|
|||
|
<p><input placeholder="username" id="username" type="text"> <input placeholder="password" id="password" type="password"></p>
|
|||
|
<button type="submit">
|
|||
|
Login
|
|||
|
</button>
|
|||
|
</form>
|
|||
|
</div>
|
|||
|
<hr>
|
|||
|
</main>
|
|||
|
|
|||
|
|
|||
|
</body></html>
|