Compare commits
15 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
3c05e27c50 | ||
![]() |
7f007c23f2 | ||
![]() |
c76deb6eab | ||
![]() |
cfdbca31ff | ||
![]() |
aff18aabac | ||
![]() |
b83a30591a | ||
![]() |
5b14e7b5bd | ||
![]() |
471c01455f | ||
![]() |
f0fc381076 | ||
![]() |
91a6049575 | ||
![]() |
2f101752fd | ||
![]() |
d4e8455e95 | ||
![]() |
071895b67e | ||
![]() |
513326387a | ||
![]() |
9beecead2f |
4
Makefile
4
Makefile
@@ -12,7 +12,7 @@ echo:
|
||||
|
||||
USER_GH=eyedeekay
|
||||
packagename=eephttpd
|
||||
VERSION=0.0.8
|
||||
VERSION=0.0.97
|
||||
|
||||
tag:
|
||||
gothub release -s $(GITHUB_TOKEN) -u $(USER_GH) -r $(packagename) -t v$(VERSION) -d "I2P Tunnel Management tool for Go applications"
|
||||
@@ -101,7 +101,7 @@ usage:
|
||||
@echo "--------" >> USAGE.md
|
||||
@echo "" >> USAGE.md
|
||||
@echo "a running instance of eephttpd with the example index file is availble on" >> USAGE.md
|
||||
@echo '[http://566niximlxdzpanmn4qouucvua3k7neniwss47li5r6ugoertzuq.b32.i2p](http://566niximlxdzpanmn4qouucvua3k7neniwss47li5r6ugoertzuq.b32.i2p)' >> USAGE.md
|
||||
@echo '[http://tvndxxkxcstbtqfxg7iigco6bj22ff2y6jxikmk7wqkyadkhrd4a.b32.i2p](http://tvndxxkxcstbtqfxg7iigco6bj22ff2y6jxikmk7wqkyadkhrd4a.b32.i2p)' >> USAGE.md
|
||||
@echo "" >> USAGE.md
|
||||
@cat USAGE.md
|
||||
|
||||
|
42
README.md
42
README.md
@@ -1,23 +1,31 @@
|
||||
# eephttpd
|
||||
|
||||
So, basically everything I put on i2p is a bunch of static files. Until now, I
|
||||
tried to host them using darkhttpd(a fork of lighttpd from Alpine which
|
||||
functions as a static Web Server) and by adding tunnel configuration information
|
||||
to tunnels.conf for i2pd. This is easier than manipulating a web interface, but
|
||||
still tedious and kind of error-prone. So instead, this serves simple static
|
||||
sites directly to i2p via the SAM API.
|
||||
So much for a simple static file server.
|
||||
|
||||
to build:
|
||||
eepHttpd is a web hosting tool for content in I2P, I2P sites, and
|
||||
I2P torrents. On it's own, it's basically a static directory server
|
||||
with limited scripting abilities written in pure-Go.
|
||||
|
||||
git clone https://github.com/eyedeekay/eephttpd && cd eephttpd
|
||||
go get -u "github.com/eyedeekay/sam-forwarder"
|
||||
go get -u "github.com/eyedeekay/sam-forwarder/config"
|
||||
go build
|
||||
However, it responds differently to different kinds of interaction.
|
||||
|
||||
to run:
|
||||
1. If a Git client attempts to access it, then they will be able to clone
|
||||
the entire site, up from the document root(So **Use this for things**
|
||||
**You want to *SHARE ANONYMOUSLY* with a large audience**, not for
|
||||
things you want to keep secret.) This allows people to clone the site
|
||||
in order to mirror it.
|
||||
2. When any file is changed in the docroot, eephttpd generates a
|
||||
multi-file torrent of the site and places it in the docroot under the file
|
||||
name `$SITEHOSTNAME.torrent`. This allows people to mirror the site's exact
|
||||
content, and participate in keeping the site's content up.
|
||||
2. When a browser with I2P in Private Browsing connects to it, it creates
|
||||
a magnet link and replies with it as an `X-I2P-TORRENTLOCATION` header. In
|
||||
this way, the browser can help the user download the whole web site using
|
||||
Bittorrent and substitute HTTP resources for Bittorrent resources when
|
||||
they are ready.
|
||||
4. If a Torrent client attempts to access the `/a` URL, it is forwarded
|
||||
to an Open Torrent Tracker. **Every single eephttpd site is also an open**
|
||||
**torrent tracker.** Moreover, every single eephttpd site treats itself as
|
||||
the primary tracker for the whole-site torrent it generates. **This is**
|
||||
**intended to encourage the distribution of *open trackers* on I2P.**
|
||||
|
||||
./eephttpd
|
||||
|
||||
will serve the files from ./www, and store i2p keys in the working directory.
|
||||
|
||||
## [Usage](USAGE.md)
|
||||
So... more to come on why this is cool.
|
||||
|
100
eephttpd.go
100
eephttpd.go
@@ -3,18 +3,32 @@ package eephttpd
|
||||
import (
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
|
||||
"github.com/eyedeekay/mktorrent"
|
||||
"github.com/eyedeekay/sam-forwarder/config"
|
||||
"github.com/eyedeekay/sam-forwarder/interface"
|
||||
"github.com/eyedeekay/sam-forwarder/tcp"
|
||||
"github.com/eyedeekay/samtracker"
|
||||
"github.com/j-muller/go-torrent-parser"
|
||||
"github.com/radovskyb/watcher"
|
||||
"github.com/sosedoff/gitkit"
|
||||
"gitlab.com/golang-commonmark/markdown"
|
||||
|
||||
)
|
||||
|
||||
//EepHttpd is a structure which automatically configured the forwarding of
|
||||
//a local service to i2p over the SAM API.
|
||||
type EepHttpd struct {
|
||||
*samforwarder.SAMForwarder
|
||||
*samtracker.SamTracker
|
||||
//tracker
|
||||
*gitkit.Server
|
||||
*watcher.Watcher
|
||||
ServeDir string
|
||||
up bool
|
||||
magnet string
|
||||
mark *markdown.Markdown
|
||||
}
|
||||
|
||||
@@ -26,7 +40,7 @@ func (f *EepHttpd) GetType() string {
|
||||
|
||||
func (f *EepHttpd) ServeParent() {
|
||||
log.Println("Starting eepsite server", f.Base32())
|
||||
if err = f.SAMForwarder.Serve(); err != nil {
|
||||
if err = f.SamTracker.Serve(); err != nil {
|
||||
f.Cleanup()
|
||||
}
|
||||
}
|
||||
@@ -34,6 +48,7 @@ func (f *EepHttpd) ServeParent() {
|
||||
//Serve starts the SAM connection and and forwards the local host:port to i2p
|
||||
func (f *EepHttpd) Serve() error {
|
||||
go f.ServeParent()
|
||||
f.MakeTorrent()
|
||||
if f.Up() {
|
||||
log.Println("Starting web server", f.Target())
|
||||
if err := http.ListenAndServe(f.Target(), f); err != nil {
|
||||
@@ -49,41 +64,112 @@ func (f *EepHttpd) Up() bool {
|
||||
|
||||
//Close shuts the whole thing down.
|
||||
func (f *EepHttpd) Close() error {
|
||||
return f.SAMForwarder.Close()
|
||||
return f.SamTracker.Close()
|
||||
}
|
||||
|
||||
func (s *EepHttpd) Load() (samtunnel.SAMTunnel, error) {
|
||||
if !s.up {
|
||||
log.Println("Started putting tunnel up")
|
||||
}
|
||||
f, e := s.SAMForwarder.Load()
|
||||
f, e := s.SamTracker.Load()
|
||||
if e != nil {
|
||||
return nil, e
|
||||
}
|
||||
s.SAMForwarder = f.(*samforwarder.SAMForwarder)
|
||||
s.SamTracker = f.(*samtracker.SamTracker)
|
||||
|
||||
s.mark = markdown.New(markdown.XHTMLOutput(true))
|
||||
s.up = true
|
||||
s.Watcher = watcher.New()
|
||||
s.Watcher.SetMaxEvents(1)
|
||||
s.Watcher.AddRecursive(s.ServeDir)
|
||||
go func() {
|
||||
for {
|
||||
select {
|
||||
case event := <-s.Watcher.Event:
|
||||
log.Printf("File event %v\n", event)
|
||||
err := s.MakeTorrent()
|
||||
if err != nil {
|
||||
log.Printf("File Watcher Error %e", err)
|
||||
}
|
||||
case err := <-s.Watcher.Error:
|
||||
log.Printf("File Watcher Error %e", err)
|
||||
case <-s.Watcher.Closed:
|
||||
return
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
go func() {
|
||||
s.Watcher.Wait()
|
||||
s.Watcher.TriggerEvent(watcher.Create, nil)
|
||||
s.Watcher.TriggerEvent(watcher.Remove, nil)
|
||||
}()
|
||||
|
||||
log.Println("Finished putting tunnel up")
|
||||
return s, nil
|
||||
}
|
||||
|
||||
func (e *EepHttpd) HostName() string {
|
||||
return e.Base32()
|
||||
}
|
||||
|
||||
func (e *EepHttpd) MakeTorrent() error {
|
||||
log.Println("Generating a torrent for the site.")
|
||||
t, err := mktorrent.MakeTorrent(e.ServeDir, e.Base32(), "http://"+e.HostName()+"/", "http://"+e.HostName()+"/a", "http://w7tpbzncbcocrqtwwm3nezhnnsw4ozadvi2hmvzdhrqzfxfum7wa.b32.i2p/a")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
f, err := os.Create(filepath.Join(e.ServeDir, e.Base32()) + ".torrent")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
t.Save(f)
|
||||
f.Close()
|
||||
|
||||
torrent, err := gotorrentparser.ParseFromFile(filepath.Join(e.ServeDir, e.Base32()) + ".torrent")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
e.magnet = "magnet:?xt=urn:btih:" + torrent.InfoHash + "=" + "http://" + e.Base32() + "/announce"
|
||||
log.Println("Magnet link", e.magnet)
|
||||
return nil
|
||||
}
|
||||
|
||||
//NewEepHttpd makes a new SAM forwarder with default options, accepts host:port arguments
|
||||
func NewEepHttpd(host, port string) (*EepHttpd, error) {
|
||||
return NewEepHttpdFromOptions(SetHost(host), SetPort(port))
|
||||
}
|
||||
|
||||
func Never(gitkit.Credential, *gitkit.Request) (bool, error) {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
//NewEepHttpdFromOptions makes a new SAM forwarder with default options, accepts host:port arguments
|
||||
func NewEepHttpdFromOptions(opts ...func(*EepHttpd) error) (*EepHttpd, error) {
|
||||
var s EepHttpd
|
||||
s.SAMForwarder = &samforwarder.SAMForwarder{}
|
||||
s.SamTracker = &samtracker.SamTracker{
|
||||
SAMForwarder: &samforwarder.SAMForwarder{
|
||||
Conf: &i2ptunconf.Conf{},
|
||||
},
|
||||
}
|
||||
s.Server = &gitkit.Server{}
|
||||
log.Println("Initializing eephttpd")
|
||||
for _, o := range opts {
|
||||
if err := o(&s); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
s.SAMForwarder.Config().SaveFile = true
|
||||
s.SamTracker.Config().SaveFile = true
|
||||
pp, _ := strconv.Atoi(s.SamTracker.Config().TargetPort)
|
||||
s.SamTracker.InitTarget(s.SamTracker.Config().TargetHost+":"+strconv.Itoa(pp + 1))
|
||||
// s.tracker.SamTracker = s.SamTracker
|
||||
l, e := s.Load()
|
||||
s.Server = gitkit.New(gitkit.Config{
|
||||
Dir: s.ServeDir,
|
||||
AutoCreate: true,
|
||||
Auth: true, // Turned off by default
|
||||
})
|
||||
s.Server.AuthFunc = Never
|
||||
//log.Println("Options loaded", s.Print())
|
||||
if e != nil {
|
||||
return nil, e
|
||||
|
32
go.mod
32
go.mod
@@ -3,35 +3,53 @@ module github.com/eyedeekay/eephttpd
|
||||
go 1.12
|
||||
|
||||
require (
|
||||
github.com/PeteGabriel/torgo v0.0.0-20200509093753-d38b3aa2685a
|
||||
github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d // indirect
|
||||
github.com/andybalholm/cascadia v1.1.0 // indirect
|
||||
github.com/cheggaaa/pb v1.0.29
|
||||
github.com/creack/pty v1.1.9 // indirect
|
||||
github.com/cryptix/go v1.5.0 // indirect
|
||||
github.com/d5/tengo v1.24.3
|
||||
github.com/d5/tengo v1.24.8
|
||||
github.com/eyedeekay/mktorrent v0.0.0-20210201004350-82eef738c99e
|
||||
github.com/eyedeekay/outproxy v0.0.0-20190913044809-33f1668ccb7d // indirect
|
||||
github.com/eyedeekay/sam-forwarder v0.0.0-20190928041036-d2f767dbe008
|
||||
github.com/eyedeekay/sam3 v0.0.0-20190730185140-f8d54526ea25
|
||||
github.com/eyedeekay/sam-forwarder v0.32.1
|
||||
github.com/eyedeekay/sam3 v0.32.32
|
||||
github.com/eyedeekay/samtracker v0.0.0-20210201174310-55c3321622e1
|
||||
github.com/google/go-cmp v0.3.1 // indirect
|
||||
github.com/gorilla/sessions v1.2.0 // indirect
|
||||
github.com/gotoolkits/goTorrent v0.0.0-20170904145641-be7ba52afe97
|
||||
github.com/gotoolkits/gorequest v0.2.15 // indirect
|
||||
github.com/j-muller/go-torrent-parser v0.0.0-20170523202311-f719c960746c
|
||||
github.com/jackpal/bencode-go v1.0.0 // indirect
|
||||
github.com/juju/errors v0.0.0-20190930114154-d42613fe1ab9 // indirect
|
||||
github.com/juju/testing v0.0.0-20191001232224-ce9dec17d28b // indirect
|
||||
github.com/julienschmidt/httprouter v1.3.0 // indirect
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.2 // indirect
|
||||
github.com/kr/pty v1.1.8 // indirect
|
||||
github.com/miolini/datacounter v0.0.0-20190724021726-aa48df3a02c1 // indirect
|
||||
github.com/moul/http2curl v1.0.0 // indirect
|
||||
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f // indirect
|
||||
github.com/oxtoacart/bpool v0.0.0-20190530202638-03653db5a59c // indirect
|
||||
github.com/petegabriel/torgo v0.0.0-20200509093753-d38b3aa2685a // indirect
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/prometheus/common v0.7.0 // indirect
|
||||
github.com/prometheus/procfs v0.0.5 // indirect
|
||||
github.com/radovskyb/watcher v1.0.7
|
||||
github.com/satori/go.uuid v1.2.0 // indirect
|
||||
github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749 // indirect
|
||||
github.com/sosedoff/gitkit v0.2.0
|
||||
github.com/spf13/pflag v1.0.5 // indirect
|
||||
github.com/stretchr/objx v0.2.0 // indirect
|
||||
gitlab.com/golang-commonmark/markdown v0.0.0-20181102083822-772775880e1f
|
||||
github.com/varyoo/mktorrent v0.0.0-20180208215256-4561e0bf1bc2
|
||||
github.com/zeebo/bencode v1.0.0 // indirect
|
||||
gitlab.com/golang-commonmark/linkify v0.0.0-20200225224916-64bca66f6ad3 // indirect
|
||||
gitlab.com/golang-commonmark/markdown v0.0.0-20191127184510-91b5b3c99c19
|
||||
go.uber.org/multierr v1.2.0 // indirect
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550 // indirect
|
||||
golang.org/x/net v0.0.0-20191011234655-491137f69257 // indirect
|
||||
golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad // indirect
|
||||
golang.org/x/net v0.0.0-20210119194325-5f4716e94777 // indirect
|
||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e // indirect
|
||||
golang.org/x/sys v0.0.0-20191010194322-b09406accb47 // indirect
|
||||
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c // indirect
|
||||
golang.org/x/text v0.3.5 // indirect
|
||||
golang.org/x/time v0.0.0-20190921001708-c4c64cad1fd0 // indirect
|
||||
golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a // indirect
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898 // indirect
|
||||
|
59
serve.go
59
serve.go
@@ -1,6 +1,7 @@
|
||||
package eephttpd
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
@@ -12,8 +13,47 @@ import (
|
||||
"github.com/d5/tengo/script"
|
||||
)
|
||||
|
||||
func (f *EepHttpd) ProxyRequest(req *http.Request) *http.Request {
|
||||
body, err := ioutil.ReadAll(req.Body)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
// you can reassign the body if you need to parse it as multipart
|
||||
// req.Body = ioutil.NopCloser(bytes.NewReader(body))
|
||||
|
||||
// create a new url from the raw RequestURI sent by the client
|
||||
url := fmt.Sprintf("%s://%s:%s/%s", "http", f.SamTracker.Config().TargetHost, f.SamTracker.Config().TargetPort, "a")
|
||||
log.Println("handling http tracker request", url)
|
||||
proxyReq, err := http.NewRequest(req.Method, url, bytes.NewReader(body))
|
||||
|
||||
// We may want to filter some headers, otherwise we could just use a shallow copy
|
||||
//
|
||||
proxyReq.Header = req.Header
|
||||
return proxyReq
|
||||
}
|
||||
|
||||
func (f *EepHttpd) ServeHTTP(rw http.ResponseWriter, rq *http.Request) {
|
||||
rp := f.checkURL(rq)
|
||||
log.Println("rp", rp)
|
||||
rw.Header().Set("X-I2P-TORRENTLOCATION", f.magnet)
|
||||
if rp == "a" {
|
||||
client := http.Client{}
|
||||
req := f.ProxyRequest(rq)
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
resp.Body.Close()
|
||||
body, err := ioutil.ReadAll(resp.Body)
|
||||
fmt.Fprintf(rw, string(body))
|
||||
return
|
||||
}
|
||||
if strings.HasPrefix(rq.Header.Get("User-Agent"), "git") {
|
||||
log.Println(rq.Header.Get("User-Agent"))
|
||||
f.HandleFile(rw, rq)
|
||||
return
|
||||
}
|
||||
if strings.HasSuffix(rp, ".md") {
|
||||
f.HandleMarkdown(rw, rq)
|
||||
return
|
||||
@@ -38,6 +78,12 @@ func FileExists(filename string) bool {
|
||||
|
||||
func (f *EepHttpd) checkURL(rq *http.Request) string {
|
||||
p := rq.URL.Path
|
||||
if strings.HasSuffix("/"+rq.URL.Path, "/a") {
|
||||
|
||||
p = "a"
|
||||
log.Println("URL path", p)
|
||||
return p
|
||||
}
|
||||
if strings.HasSuffix(rq.URL.Path, "/") {
|
||||
p = filepath.Join(rq.URL.Path, "index.html")
|
||||
}
|
||||
@@ -46,12 +92,12 @@ func (f *EepHttpd) checkURL(rq *http.Request) string {
|
||||
}
|
||||
if !FileExists(filepath.Join(f.ServeDir, p)) {
|
||||
p = filepath.Join(rq.URL.Path, "index.tengo")
|
||||
if FileExists(filepath.Join(f.ServeDir, p)) {
|
||||
p = filepath.Join(rq.URL.Path, "index.tengo")
|
||||
if !FileExists(filepath.Join(f.ServeDir, p)) {
|
||||
p = rq.URL.Path
|
||||
}
|
||||
}
|
||||
log.Println(p)
|
||||
return filepath.Join(f.ServeDir, p)
|
||||
fp := filepath.Join(f.ServeDir, p)
|
||||
return fp
|
||||
}
|
||||
|
||||
func (f *EepHttpd) HandleScript(rw http.ResponseWriter, rq *http.Request) {
|
||||
@@ -84,6 +130,11 @@ func (f *EepHttpd) HandleMarkdown(rw http.ResponseWriter, rq *http.Request) {
|
||||
f.mark.Render(rw, bytes)
|
||||
}
|
||||
|
||||
func (f *EepHttpd) HandleGit(rw http.ResponseWriter, rq *http.Request) {
|
||||
log.Println("Handling Git")
|
||||
f.Server.ServeHTTP(rw, rq)
|
||||
}
|
||||
|
||||
func (f *EepHttpd) HandleFile(rw http.ResponseWriter, rq *http.Request) {
|
||||
path := f.checkURL(rq)
|
||||
bytes, err := ioutil.ReadFile(path)
|
||||
|
@@ -1,17 +1,17 @@
|
||||
<h1 id="eephttpd">eephttpd</h1>
|
||||
<p>So, basically everything I put on i2p is a bunch of static files. Until now, I tried to host them using darkhttpd(a fork of lighttpd from Alpine which functions as a static Web Server) and by adding tunnel configuration information to tunnels.conf for i2pd. This is easier than manipulating a web interface, but still tedious and kind of error-prone. So instead, this serves simple static sites directly to i2p via the SAM API.</p>
|
||||
<p>to build:</p>
|
||||
<pre><code> git clone https://github.com/eyedeekay/eephttpd && cd eephttpd
|
||||
go get -u "github.com/eyedeekay/sam-forwarder"
|
||||
go get -u "github.com/eyedeekay/sam-forwarder/config"
|
||||
go build</code></pre>
|
||||
<p>to run:</p>
|
||||
<pre><code> ./eephttpd</code></pre>
|
||||
<p>will serve the files from ./www, and store i2p keys in the working directory.</p>
|
||||
<h2 id="usage"><a href="USAGE.md">Usage</a></h2>
|
||||
<p>So much for a simple static file server.</p>
|
||||
<p>eepHttpd is a web hosting tool for content in I2P, I2P sites, and I2P torrents. On it’s own, it’s basically a static directory server with limited scripting abilities written in pure-Go.</p>
|
||||
<p>However, it responds differently to different kinds of interaction.</p>
|
||||
<ol type="1">
|
||||
<li>If a Git client attempts to access it, then they will be able to clone the entire site, up from the document root(So <strong>Use this for things</strong> <strong>You want to <em>SHARE ANONYMOUSLY</em> with a large audience</strong>, not for things you want to keep secret.) This allows people to clone the site in order to mirror it.</li>
|
||||
<li>When any file is changed in the docroot, eephttpd generates a multi-file torrent of the site and places it in the docroot under the file name <code>$SITEHOSTNAME.torrent</code>. This allows people to mirror the site’s exact content, and participate in keeping the site’s content up.</li>
|
||||
<li>When a browser with I2P in Private Browsing connects to it, it creates a magnet link and replies with it as an <code>X-I2P-TORRENTLOCATION</code> header. In this way, the browser can help the user download the whole web site using Bittorrent and substitute HTTP resources for Bittorrent resources when they are ready.</li>
|
||||
<li>If a Torrent client attempts to access the <code>/a</code> URL, it is forwarded to an Open Torrent Tracker. <strong>Every single eephttpd site is also an open</strong> <strong>torrent tracker.</strong> Moreover, every single eephttpd site treats itself as the primary tracker for the whole-site torrent it generates. <strong>This is</strong> <strong>intended to encourage the distribution of <em>open trackers</em> on I2P.</strong></li>
|
||||
</ol>
|
||||
<p>So… more to come on why this is cool.</p>
|
||||
<h1 id="eephttpd---static-file-server-automatically-forwarded-to-i2p">eephttpd - Static file server automatically forwarded to i2p</h1>
|
||||
<h2 id="usage-1">usage:</h2>
|
||||
<p>eephttpd is a static http server which automatically runs on i2p with the help of the SAM bridge. By default it will only be available from the localhost and it's i2p tunnel. It can be masked from the localhost using a container.</p>
|
||||
<h2 id="usage">usage:</h2>
|
||||
<p>eephttpd is a static http server which automatically runs on i2p with the help of the SAM bridge. By default it will only be available from the localhost and it’s i2p tunnel. It can be masked from the localhost using a container.</p>
|
||||
<pre><code>Usage of ./eephttpd:
|
||||
-a string
|
||||
hostname to serve on (default "127.0.0.1")
|
||||
@@ -81,4 +81,4 @@
|
||||
--volumes-from eephttpd-volume \
|
||||
eyedeekay/eephttpd</code></pre>
|
||||
<h2 id="instance">instance</h2>
|
||||
<p>a running instance of eephttpd with the example index file is availble on <a href="http://566niximlxdzpanmn4qouucvua3k7neniwss47li5r6ugoertzuq.b32.i2p" class="uri">http://566niximlxdzpanmn4qouucvua3k7neniwss47li5r6ugoertzuq.b32.i2p</a></p>
|
||||
<p>a running instance of eephttpd with the example index file is availble on <a href="http://566niximlxdzpanmn4qouucvua3k7neniwss47li5r6ugoertzuq.b32.i2p">http://566niximlxdzpanmn4qouucvua3k7neniwss47li5r6ugoertzuq.b32.i2p</a></p>
|
||||
|
Reference in New Issue
Block a user