172 lines
8.3 KiB
HTML
172 lines
8.3 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<!-- Implement strict Content Security Policy -->
|
|
<title>HTTP Messages - Documentation</title>
|
|
<!-- Load our CSS file -->
|
|
<link rel="stylesheet" href="./styles.css">
|
|
<!-- Include the webpack bundled JavaScript files -->
|
|
<script defer src="./client.bundle.js"></script>
|
|
<!-- Additional chunks will be loaded automatically -->
|
|
</head>
|
|
<body>
|
|
<!-- Navigation bar container - content will be injected by navbar.ts -->
|
|
<div id="navbarContainer" class="top-nav">
|
|
<!-- Navbar content will be injected here -->
|
|
</div>
|
|
|
|
<h1>HTTP Messages</h1>
|
|
|
|
<!-- Documentation Content -->
|
|
<div class="content">
|
|
<div class="info-box">
|
|
<p>A specification for sending/receiving HTTP messages (request/response) via a remote server. Header / Body etc are encrypted, either in the <code>content</code> (small messages) or via a blossom server (larger requests).</p>
|
|
</div>
|
|
|
|
<div class="diagram-container">
|
|
<img src="./http.png" alt="HTTP Messages Architecture Diagram">
|
|
<p class="diagram-caption">HTTP Messages Architecture Overview</p>
|
|
</div>
|
|
|
|
<section class="section">
|
|
<h2>Overview</h2>
|
|
<p>HTTP Messages enables a local client to make and receive HTTP requests (PUT, POST, GET, PATCH etc) from a remote computer. This approach provides enhanced privacy, anonymity, and resistance to censorship.</p>
|
|
|
|
<p>The system requires:</p>
|
|
<ul>
|
|
<li>A trusted machine to process the messages (can be a home PC or Raspberry Pi)</li>
|
|
<li>A relay (can be untrusted)</li>
|
|
<li>A blossom server (can be untrusted)</li>
|
|
</ul>
|
|
</section>
|
|
|
|
<section class="section">
|
|
<h2>How It Works</h2>
|
|
<p>HTTP Messages operates by converting standard HTTP requests into encrypted Nostr events (kind 21120) that can be safely transmitted through untrusted relays. The process ensures privacy and security while enabling communication with the regular internet.</p>
|
|
|
|
<div class="features-grid">
|
|
<div class="feature-card">
|
|
<h3>Privacy Protection</h3>
|
|
<p>All HTTP headers and body content are encrypted, protecting sensitive information from intermediaries.</p>
|
|
</div>
|
|
<div class="feature-card">
|
|
<h3>Censorship Resistance</h3>
|
|
<p>By routing through Nostr relays, the system can bypass traditional censorship mechanisms that block direct connections.</p>
|
|
</div>
|
|
<div class="feature-card">
|
|
<h3>Server Anonymity</h3>
|
|
<p>No domain needed or port forwarding required, keeping your server completely private.</p>
|
|
</div>
|
|
<div class="feature-card">
|
|
<h3>Flexible Architecture</h3>
|
|
<p>Works with small payloads (embedded in content) or large requests (via blossom server).</p>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<section class="section">
|
|
<h2>Architecture</h2>
|
|
<p>The HTTP Messages architecture consists of several components working together:</p>
|
|
|
|
<h3>Components</h3>
|
|
<ul>
|
|
<li><strong>Nostr Client</strong>: Converts HTTP requests into kind 21120 events and handles responses</li>
|
|
<li><strong>Nostr Relay</strong>: Transmits events between clients and servers (untrusted)</li>
|
|
<li><strong>Blossom Storage</strong>: Stores larger payloads that don't fit in event content (untrusted)</li>
|
|
<li><strong>Trusted Device</strong>: Processes encrypted requests, makes actual HTTP calls, and returns responses</li>
|
|
</ul>
|
|
|
|
<h3>Sequence Diagram</h3>
|
|
<ol>
|
|
<li>Client converts HTTP request into kind 21120 event</li>
|
|
<li>Client encrypts & pushes payload to Blossom (if large)</li>
|
|
<li>Client publishes event to Nostr relay</li>
|
|
<li>Trusted device fetches the event</li>
|
|
<li>Trusted device decrypts event</li>
|
|
<li>Trusted device fetches payload from Blossom (if large)</li>
|
|
<li>Trusted device makes the actual HTTP request</li>
|
|
<li>Trusted device gets HTTP response</li>
|
|
<li>Trusted device encrypts & pushes response payload to Blossom (if large)</li>
|
|
<li>Trusted device creates kind 21121 response event</li>
|
|
<li>Trusted device publishes response event to relay</li>
|
|
<li>Client fetches response event</li>
|
|
<li>Client decrypts event</li>
|
|
<li>Client fetches payload from Blossom (if large)</li>
|
|
<li>Client converts kind 21121 into HTTP response</li>
|
|
<li>Client deletes request blob (if exists)</li>
|
|
<li>Client deletes request event</li>
|
|
</ol>
|
|
<p>The remote server should periodically scan for expired RESPONSE events (and associated blossom blobs) and delete them.</p>
|
|
</section>
|
|
|
|
<section class="section">
|
|
<h2>Event Structure</h2>
|
|
<p>HTTP Messages uses several Nostr event kinds with specific structures:</p>
|
|
|
|
<h3>Server Advertisement Event (Kind 31120)</h3>
|
|
<p>Used to facilitate discovery of HTTP-over-Nostr servers:</p>
|
|
<pre>{
|
|
"kind": 31120,
|
|
"pubkey": "<pubkey of server operator>",
|
|
"content": "HTTP-over-Nostr server", // Optional markdown description of the http server(s)
|
|
"tags": [
|
|
["d", "<hex pubkey of server>"], // Server pubkey that will be listening for requests
|
|
["relay", "wss://relay.one"], // Relay where server is listening (can have multiple)
|
|
["relay", "wss://relay.two"],
|
|
["expiry", "<unix timestamp>"], // How long this server will be online
|
|
]
|
|
}</pre>
|
|
<p>Clients looking to use HTTP over Nostr can query for these kind 31120 events to discover available servers and may communicate with the server operator to get permission to use them.</p>
|
|
|
|
<h3>HTTP Request (Kind 21120)</h3>
|
|
<pre>{
|
|
"kind": 21120,
|
|
"pubkey": "<pubkey>",
|
|
"content": "$encryptedPayload",
|
|
"tags": [
|
|
["p", "<pubkey of remote server>"], // P tag entry, this is a REQUEST
|
|
["key","nip44Encrypt($decryptkey)"],
|
|
["r", "https://relay.one"],
|
|
["expiration",<unix timestamp>]
|
|
]
|
|
}</pre>
|
|
<p>NIP-44 is NOT used for the content encryption as the payload may be large, affecting bunker signing stability.</p>
|
|
|
|
<h3>HTTP Response (Kind 21121)</h3>
|
|
<pre>{
|
|
"kind": 21121,
|
|
"pubkey": "<pubkey>",
|
|
"content": "encrypt({'url':'blossom.one','hash':'xx'},$decryptkey)",
|
|
"tags": [
|
|
["key","nip44Encrypt($decryptkey)"],
|
|
["E", "<request event id>"], // E tag entry, this is a RESPONSE
|
|
["expiration",<unix timestamp>]
|
|
]
|
|
}</pre>
|
|
<p>A different kind is used for responses to help with filtering. There is no "p" tag as the "E" tag already identifies the request.</p>
|
|
</section>
|
|
|
|
<section class="section">
|
|
<h2>Considerations & Use Cases</h2>
|
|
<p>This approach only makes sense in cases where privacy and anonymity are important, or if censorship is a concern.</p>
|
|
|
|
<h3>Drawbacks</h3>
|
|
<ul>
|
|
<li><strong>Complexity</strong>: Many more moving parts than a direct request</li>
|
|
<li><strong>Speed</strong>: Each request/response requires multiple steps (encryption, signing, transmission, decryption, etc.)</li>
|
|
</ul>
|
|
|
|
<h3>Why Use It?</h3>
|
|
<ul>
|
|
<li>Enables a plethora of open source apps to be made available from inside private networks (localhost) but over Nostr</li>
|
|
<li>Maximum server privacy (no domain needed, or port forwarding)</li>
|
|
<li>Make regular API calls over Nostr</li>
|
|
<li>Enhanced privacy and anonymity</li>
|
|
<li>Resistance to censorship</li>
|
|
</ul>
|
|
</section>
|
|
</div>
|
|
</body>
|
|
</html> |