Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 0 additions & 12 deletions .aegir.js

This file was deleted.

11 changes: 11 additions & 0 deletions .cspell.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"import": [
"./node_modules/aegir/cspell.json"
],
"dictionaries": ["project"],
"dictionaryDefinitions": [{
"name": "project",
"path": "./.github/dictionary.txt",
"addWords": true
}]
}
15 changes: 14 additions & 1 deletion .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,17 @@ updates:
open-pull-requests-limit: 20
commit-message:
prefix: "deps"
prefix-development: "deps(dev)"
prefix-development: "chore"
groups:
libp2p-deps:
patterns:
- "*libp2p*"
- "*multiformats*"
- "*blockstore*"
- "*datastore*"
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "weekly"
commit-message:
prefix: chore
3 changes: 3 additions & 0 deletions .github/dictionary.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
undici
httponly
initializable
2 changes: 1 addition & 1 deletion .github/workflows/semantic-pull-request.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,4 @@ on:

jobs:
main:
uses: pl-strflt/.github/.github/workflows/reusable-semantic-pull-request.yml@v0.3
uses: ipdxco/unified-github-workflows/.github/workflows/reusable-semantic-pull-request.yml@v1
3 changes: 2 additions & 1 deletion .github/workflows/stale.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,12 @@ name: Close and mark stale issue
on:
schedule:
- cron: '0 0 * * *'
workflow_dispatch:

permissions:
issues: write
pull-requests: write

jobs:
stale:
uses: pl-strflt/.github/.github/workflows/reusable-stale-issue.yml@v0.3
uses: ipdxco/unified-github-workflows/.github/workflows/reusable-stale-issue.yml@v1
47 changes: 0 additions & 47 deletions .github/workflows/test-examples.yml

This file was deleted.

2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,5 @@ node_modules
package-lock.json
yarn.lock
.vscode
.tmp-compiled-docs
tsconfig-doc-check.aegir.json
87 changes: 46 additions & 41 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
# @libp2p/http-fetch
# @libp2p/http

[![libp2p.io](https://img.shields.io/badge/project-libp2p-yellow.svg?style=flat-square)](http://libp2p.io/)
[![Discuss](https://img.shields.io/discourse/https/discuss.libp2p.io/posts.svg?style=flat-square)](https://discuss.libp2p.io)
[![codecov](https://img.shields.io/codecov/c/github/libp2p/js-libp2p-http-fetch.svg?style=flat-square)](https://codecov.io/gh/libp2p/js-libp2p-http-fetch)
[![CI](https://img.shields.io/github/actions/workflow/status/libp2p/js-libp2p-http-fetch/js-test-and-release.yml?branch=main\&style=flat-square)](https://github.com/libp2p/js-libp2p-http-fetch/actions/workflows/js-test-and-release.yml?query=branch%3Amain)
[![codecov](https://img.shields.io/codecov/c/github/libp2p/js-libp2p-http.svg?style=flat-square)](https://codecov.io/gh/libp2p/js-libp2p-http)
[![CI](https://img.shields.io/github/actions/workflow/status/libp2p/js-libp2p-http/js-test-and-release.yml?branch=main\&style=flat-square)](https://github.com/libp2p/js-libp2p-http/actions/workflows/js-test-and-release.yml?query=branch%3Amain)

> Implementation of the WHATWG Fetch API on libp2p streams
> Accept HTTP requests over libp2p streams and/or use libp2p protocols over HTTP

# About

Expand All @@ -24,62 +24,67 @@ repo and examine the changes made.

-->

http implements the WHATWG [Fetch
api](https://fetch.spec.whatwg.org). It can be used as a drop in replacement
for the browser's fetch function. It supports http, https, and multiaddr
URIs. Use HTTP in p2p networks.

## Example

See the `examples/` for full examples of how to use the HTTP service.

```typescript
import { createLibp2p } from 'libp2p'
import { http } from '@libp2p/http-fetch'

const node = await createLibp2p({
// other options ...
services: {
http: http()
}
})

await node.start()

// Make an http request to a libp2p peer
let resp = await node.services.http.fetch('multiaddr:/dns4/localhost/tcp/1234')
// Or a traditional HTTP request
resp = await node.services.http.fetch('multiaddr:/dns4/example.com/tcp/443/tls/http')
// And of course, you can use the fetch API as you normally would
resp = await node.services.http.fetch('https://example.com')

// This gives you the accessibility of the fetch API with the flexibility of using a p2p network.
```
This module allows you to use HTTP requests as a transport for libp2p
protocols (libp2p over HTTP), and also libp2p streams as a transport for HTTP
requests (HTTP over libp2p).

It integrates with existing Node.js friendly HTTP frameworks such as
[express](https://expressjs.com/) and [Fastify](https://fastify.dev) as well
as [Request](https://developer.mozilla.org/en-US/docs/Web/API/Request)/
[Response](https://developer.mozilla.org/en-US/docs/Web/API/Response)-based
frameworks like [Hono](https://hono.dev/).

It even allows creating Node.js-style [http.Server](https://nodejs.org/api/http.html#class-httpserver)s
and [WebSocketServer](https://github.com/websockets/ws/blob/HEAD/doc/ws.md#class-websocketserver)s
in browsers to truly realize the power of the distributed web.

In addition to URL-based addressing, it can use a libp2p PeerId and/or
multiaddr(s) and lets libp2p take care of the routing, thus taking advantage
of features like multi-routes, NAT traversal and stream multiplexing over a
single connection.

# Packages

- [`examples/express-server-over-libp2p`](https://github.com/libp2p/js-libp2p-http/tree/main/examples/express-server-over-libp2p) How to serve an express app over libp2p streams
- [`examples/hono-server-over-libp2p`](https://github.com/libp2p/js-libp2p-http/tree/main/examples/hono-server-over-libp2p) undefined
- [`examples/libp2p-as-http-transport`](https://github.com/libp2p/js-libp2p-http/tree/main/examples/libp2p-as-http-transport) undefined
- [`examples/libp2p-over-http-server`](https://github.com/libp2p/js-libp2p-http/tree/main/examples/libp2p-over-http-server) undefined
- [`examples/peer-id-auth`](https://github.com/libp2p/js-libp2p-http/tree/main/examples/peer-id-auth) How to authenticate peers over HTTP
- [`examples/serving-websites-from-web-browsers`](https://github.com/libp2p/js-libp2p-http/tree/main/examples/serving-websites-from-web-browsers) How to serve websites from web browsers using libp2p
- [`examples/websockets-over-libp2p`](https://github.com/libp2p/js-libp2p-http/tree/main/examples/websockets-over-libp2p) How to serve WebSockets over libp2p streams
- [`packages/http`](https://github.com/libp2p/js-libp2p-http/tree/main/packages/http) Accept HTTP requests over libp2p streams or use libp2p protocols over HTTP
- [`packages/http-fetch`](https://github.com/libp2p/js-libp2p-http/tree/main/packages/http-fetch) libp2p-compatible implementation of the fetch API
- [`packages/http-peer-id-auth`](https://github.com/libp2p/js-libp2p-http/tree/main/packages/http-peer-id-auth) An implementation of Peer ID Authentication over HTTP
- [`packages/http-ping`](https://github.com/libp2p/js-libp2p-http/tree/main/packages/http-ping) An HTTP version of the ping protocol
- [`packages/http-server`](https://github.com/libp2p/js-libp2p-http/tree/main/packages/http-server) HTTP server components
- [`packages/http-utils`](https://github.com/libp2p/js-libp2p-http/tree/main/packages/http-utils) Shared utils and common code for HTTP modules
- [`packages/http-websocket`](https://github.com/libp2p/js-libp2p-http/tree/main/packages/http-websocket) libp2p-compatible implementation of the WebSocket API
- [`packages/interop`](https://github.com/libp2p/js-libp2p-http/tree/main/packages/interop) Interop tests for the @libp2p/http collection of modules

# Install

```console
$ npm i @libp2p/http-fetch
$ npm i @libp2p/http
```

## Browser `<script>` tag

Loading this module through a script tag will make its exports available as `Libp2pHttpFetch` in the global namespace.
Loading this module through a script tag will make its exports available as `Libp2pHttp` in the global namespace.

```html
<script src="https://unpkg.com/@libp2p/http-fetch/dist/index.min.js"></script>
<script src="https://unpkg.com/@libp2p/http/dist/index.min.js"></script>
```

# API Docs

- <https://libp2p.github.io/js-libp2p-http-fetch>
- <https://libp2p.github.io/js-libp2p-http>

# License

Licensed under either of

- Apache 2.0, ([LICENSE-APACHE](https://github.com/libp2p/js-libp2p-http-fetch/LICENSE-APACHE) / <http://www.apache.org/licenses/LICENSE-2.0>)
- MIT ([LICENSE-MIT](https://github.com/libp2p/js-libp2p-http-fetch/LICENSE-MIT) / <http://opensource.org/licenses/MIT>)
- Apache 2.0, ([LICENSE-APACHE](https://github.com/libp2p/js-libp2p-http/blob/main/LICENSE-APACHE) / <http://www.apache.org/licenses/LICENSE-2.0>)
- MIT ([LICENSE-MIT](https://github.com/libp2p/js-libp2p-http/blob/main/LICENSE-MIT) / <http://opensource.org/licenses/MIT>)

# Contribution

Expand Down
28 changes: 23 additions & 5 deletions examples/README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,26 @@
# Examples of using libp2p+http

TODO
## HTTP over libp2p

## two-js-peers
## hono-server-over-libp2p
## go-libp2p-http-proxy
## js-libp2p-client-and-node-server
These examples involve starting a libp2p node and having it provide the
networking layer for a HTTP server.

With this configuration you can use libp2p for peer routing, NAT traversal and
other features, but define your own web application server in the framework you
are most familiar with.

- [Express server over libp2p](./express-server-over-libp2p)
- [Hono server over libp2p](./hono-server-over-libp2p)
- [WebSockets over libp2p](./websockets-over-libp2p)
- [libp2p as a HTTP transport]('./libp2p-as-http-transport)

## libp2p over HTTP

These examples start a HTTP server and then pass incoming requests to libp2p.

- [libp2p over http.Server]('./libp2p-over-http-server)

## Other features

- [PeerID authentication]('./peer-id-auth)
- [Serving websites from browsers]('./serving-websites-from-browsers)
55 changes: 55 additions & 0 deletions examples/express-server-over-libp2p/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# Serving an Express app over libp2p

In this example we will start a libp2p node that listens for incoming streams
that use the `/http/1.1` protocol.

It will convert the incoming stream to a [http.IncomingMessage](https://nodejs.org/api/http.html#class-httpincomingmessage)
and hand it off to a Node.js [http.Server](https://nodejs.org/api/http.html#class-httpserver),
then write data passed to the corresponding [http.ServerResponse](https://nodejs.org/api/http.html#class-httpserverresponse)
back into the stream for the client to read.

## Step 1 - start the server

The script at [./src/server.js](./src/server.js) creates a basic [express](https://expressjs.com/)
app that has a simple "Hello world" route mounted on `/`.

It creates a `http.Server` to pass HTTP requests to the express app, and finally
a libp2p node to make incoming `Stream`s conform to the `net.Socket` API and
pass them to the `http.Server`.

Run the server with the following command:

```console
node src/server.js
Server listening on:
/ip4/127.0.0.1/tcp/1234/p2p/12D3KooWPUq3SjKGmVz4fhqMHZpZ185ZErfusp9x4QFgqwVCTxWt
/ip4/192.168.1.226/tcp/1234/p2p/12D3KooWPUq3SjKGmVz4fhqMHZpZ185ZErfusp9x4QFgqwVCTxWt
```

## Step 2 - run the client

The script at [./src/client.js](./src/client.js) starts a libp2p node with the
TCP transport, accepts a command line argument of a multiaddr and makes a HTTP
request to it over a libp2p stream.

Copy one of the multiaddrs the server is listening on and pass it as a CLI arg:

```console
node ./src/client.js /ip4/127.0.0.1/tcp/1234/p2p/12D3KooWPUq3SjKGmVz4fhqMHZpZ185ZErfusp9x4QFgqwVCTxWt
GET /ip4/127.0.0.1/tcp/55265/p2p/12D3KooWPUq3SjKGmVz4fhqMHZpZ185ZErfusp9x4QFgqwVCTxWt 200 OK
Hello World!
```

## Next steps

Experiment with the server - can you make it accept requests on other paths?

What about query parameters or custom headers?

> [!TIP]
> You can add `http-path` tuples to a multiaddr with:
> ```
> addr.encapsulate(`/http-path/${encodeURIComponent(foo?bar=baz)}`)
> ```

How about making a request with a body such as a `POST` request?
34 changes: 34 additions & 0 deletions examples/express-server-over-libp2p/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
{
"name": "@libp2p/http-example-express-server-over-libp2p",
"version": "1.0.0",
"description": "How to serve an express app over libp2p streams",
"eslintConfig": {
"extends": "ipfs",
"parserOptions": {
"project": true,
"sourceType": "module"
}
},
"scripts": {
"clean": "aegir clean",
"lint": "aegir lint",
"dep-check": "aegir dep-check",
"test": "test-node-example test/*"
},
"dependencies": {
"@chainsafe/libp2p-noise": "^16.1.3",
"@chainsafe/libp2p-yamux": "^7.0.1",
"@libp2p/http": "~0.0.0",
"@libp2p/http-server": "~0.0.0",
"@libp2p/tcp": "^10.1.13",
"@multiformats/multiaddr": "^12.4.0",
"express": "^5.1.0",
"libp2p": "^2.8.8"
},
"devDependencies": {
"aegir": "^47.0.16",
"test-ipfs-example": "^1.3.3"
},
"private": true,
"type": "module"
}
Loading