# HTTP Messages

A specification for sending/receiving HTTP messages (request/response) via a remote server. Header / Body etc are encrypted, either in the `content` (small messages) or via a blossom server (larger requests).

![](./http.png)

## Overview

Enables a local client to make and receive http requests (PUT, POST, GET, PATCH etc) from a remote computer.  Requires:

* A trusted machine to process the messages (can be a home PC or Raspberry Pi)
* A relay (can be untrusted)
* A blossom server (can be untrusted)


## Architecture

```mermaid
architecture-beta
group user(internet)[Nostr Client]
group cloud(cloud)[Untrusted Servers]
group home(server)[Trusted Server]
service client(internet) in user
service blossom(database)[Blossom Storage] in cloud
service relay(logos:aws-ec2)[Relays] in cloud
service pc(logos:aws-elb) in home
service bbi[Big Bad Internet]

client:R -- L:blossom
client:B -- L:relay
pc:L -- R:blossom
pc:L -- R:relay
pc:B <--> T:bbi

```

## Sequence Diagram

```mermaid
sequenceDiagram
    autoNumber
    participant c as Nostr Client
    participant r as Nostr Relay
    participant b as Blossom Server
    participant s as HTTP Server

    Note over c: Convert <br>HTTP Request<br>into kind 21120
    c-->>b: Encrypt & push payload (if large)
    c->>r: Publish <br>Event
    r<<-->>s: Fetch event
    Note over s: Decrypt event
    s<<-->>b: Fetch payload <br>(if large)
    Note over s: Make HTTP REQUEST
    Note over s: Get HTTP RESPONSE
    s-->>b: Encrypt & push <br>payload (if large)
    Note over s: Create kind<br>21120 (Response)
    s->>r: Publish Event
    r<<-->>c: Fetch event
    Note over c: Decrypt event
    b<<-->>c: Fetch payload (if large)
    Note over c: Provide RESPONSE
    
    
```


## Event Structure

```jsonc
{
  "kind": 21120,
  "pubkey": "<pubkey>",
  "content": "nip44Encrypt({'url':'blossom.one','hash':'xx','decrypt':'password123'})",
  "tags": [
    ["E", "<request event id>"], // (RES) Request ID (mandatory)
    ["r", "https://relay.one"] // (REQ) Response Relay (optional)
  ],
  // other fields...
}
```

Explanations:

 * `kind:21120` - BIP39 word #1120 ([message](https://github.com/bitcoin/bips/blob/master/bip-0039/english.txt#L1120)), plus 20,000 to be treated as ephemeral (not stored by relays).
 * `"content"` - encrypted (NIP-44) JSON with location of blob and decryption key **OR** the content itself (if under a threshold)
 * `"E"` - ID of the request event.  Enables a response to be easily identified.
 * `"r"` - (optional) relay on which the response should be sent.  For Requests only.


## Considerations

This approach only makes sense in cases where privacy and anonymity are important, or if censorship is a concern.

There are a number of drawbacks to the approach:

 - Complexity.  Many more moving parts than a direct request.
 - Speed.  Each request/response now requires:
    - Encrypting the payload
    - Loading to blossom (if large)
    - Signing event
    - broadcasting event
    - remote server fetching event
    - remote server decrypting event
    - remote server fetching blossom blob (if large)
    - remote server decrypting blossom blob (if used)
    - making the actual request

And the same flow in reverse.

So why would you use it?  Several reasons:

- enables a plethora of open source apps to be made available from inside private networks (localhost) but over nostr 
- maximum server privacy (no domain needed, or port forwarding)
- Make regular API calls over Nostr