15 Commits

Author SHA1 Message Date
idk
3c05e27c50 update link 2021-02-01 13:41:22 -05:00
idk
7f007c23f2 fix infohash calculation 2021-02-01 13:12:39 -05:00
idk
c76deb6eab fix the port switch 2021-02-01 12:47:34 -05:00
idk
cfdbca31ff update the index 2021-02-01 12:31:42 -05:00
idk
aff18aabac update the readme 2021-02-01 12:29:34 -05:00
idk
b83a30591a Add an X-I2P-TORRENTLOCATION header 2021-02-01 11:47:02 -05:00
idk
5b14e7b5bd Now every one of them is also an open torrent tracker too. So much for a simple static site host 2021-02-01 11:44:25 -05:00
idk
471c01455f git compatibility read only 2019-10-14 01:02:27 -04:00
idk
f0fc381076 git compatibility read only 2019-10-14 00:59:36 -04:00
idk
91a6049575 git compatibility read only 2019-10-14 00:57:55 -04:00
idk
2f101752fd git compatibility read only 2019-10-14 00:49:47 -04:00
idk
d4e8455e95 git compatibility read only 2019-10-14 00:47:59 -04:00
idk
071895b67e git compatibility read only 2019-10-14 00:44:16 -04:00
idk
513326387a git compatibility read only 2019-10-14 00:38:22 -04:00
idk
9beecead2f skip markdown and scripts when encountering a git user agent 2019-10-13 23:51:37 -04:00
6 changed files with 213 additions and 50 deletions

View File

@@ -12,7 +12,7 @@ echo:
USER_GH=eyedeekay USER_GH=eyedeekay
packagename=eephttpd packagename=eephttpd
VERSION=0.0.8 VERSION=0.0.97
tag: tag:
gothub release -s $(GITHUB_TOKEN) -u $(USER_GH) -r $(packagename) -t v$(VERSION) -d "I2P Tunnel Management tool for Go applications" 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 "" >> USAGE.md @echo "" >> USAGE.md
@echo "a running instance of eephttpd with the example index file is availble on" >> 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 @echo "" >> USAGE.md
@cat USAGE.md @cat USAGE.md

View File

@@ -1,23 +1,31 @@
# eephttpd # eephttpd
So, basically everything I put on i2p is a bunch of static files. Until now, I So much for a simple static file server.
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.
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 However, it responds differently to different kinds of interaction.
go get -u "github.com/eyedeekay/sam-forwarder"
go get -u "github.com/eyedeekay/sam-forwarder/config"
go build
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 So... more to come on why this is cool.
will serve the files from ./www, and store i2p keys in the working directory.
## [Usage](USAGE.md)

View File

@@ -3,18 +3,32 @@ package eephttpd
import ( import (
"log" "log"
"net/http" "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/interface"
"github.com/eyedeekay/sam-forwarder/tcp" "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" "gitlab.com/golang-commonmark/markdown"
) )
//EepHttpd is a structure which automatically configured the forwarding of //EepHttpd is a structure which automatically configured the forwarding of
//a local service to i2p over the SAM API. //a local service to i2p over the SAM API.
type EepHttpd struct { type EepHttpd struct {
*samforwarder.SAMForwarder *samtracker.SamTracker
//tracker
*gitkit.Server
*watcher.Watcher
ServeDir string ServeDir string
up bool up bool
magnet string
mark *markdown.Markdown mark *markdown.Markdown
} }
@@ -26,7 +40,7 @@ func (f *EepHttpd) GetType() string {
func (f *EepHttpd) ServeParent() { func (f *EepHttpd) ServeParent() {
log.Println("Starting eepsite server", f.Base32()) log.Println("Starting eepsite server", f.Base32())
if err = f.SAMForwarder.Serve(); err != nil { if err = f.SamTracker.Serve(); err != nil {
f.Cleanup() f.Cleanup()
} }
} }
@@ -34,6 +48,7 @@ func (f *EepHttpd) ServeParent() {
//Serve starts the SAM connection and and forwards the local host:port to i2p //Serve starts the SAM connection and and forwards the local host:port to i2p
func (f *EepHttpd) Serve() error { func (f *EepHttpd) Serve() error {
go f.ServeParent() go f.ServeParent()
f.MakeTorrent()
if f.Up() { if f.Up() {
log.Println("Starting web server", f.Target()) log.Println("Starting web server", f.Target())
if err := http.ListenAndServe(f.Target(), f); err != nil { if err := http.ListenAndServe(f.Target(), f); err != nil {
@@ -49,41 +64,112 @@ func (f *EepHttpd) Up() bool {
//Close shuts the whole thing down. //Close shuts the whole thing down.
func (f *EepHttpd) Close() error { func (f *EepHttpd) Close() error {
return f.SAMForwarder.Close() return f.SamTracker.Close()
} }
func (s *EepHttpd) Load() (samtunnel.SAMTunnel, error) { func (s *EepHttpd) Load() (samtunnel.SAMTunnel, error) {
if !s.up { if !s.up {
log.Println("Started putting tunnel up") log.Println("Started putting tunnel up")
} }
f, e := s.SAMForwarder.Load() f, e := s.SamTracker.Load()
if e != nil { if e != nil {
return nil, e return nil, e
} }
s.SAMForwarder = f.(*samforwarder.SAMForwarder) s.SamTracker = f.(*samtracker.SamTracker)
s.mark = markdown.New(markdown.XHTMLOutput(true)) s.mark = markdown.New(markdown.XHTMLOutput(true))
s.up = 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") log.Println("Finished putting tunnel up")
return s, nil 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 //NewEepHttpd makes a new SAM forwarder with default options, accepts host:port arguments
func NewEepHttpd(host, port string) (*EepHttpd, error) { func NewEepHttpd(host, port string) (*EepHttpd, error) {
return NewEepHttpdFromOptions(SetHost(host), SetPort(port)) 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 //NewEepHttpdFromOptions makes a new SAM forwarder with default options, accepts host:port arguments
func NewEepHttpdFromOptions(opts ...func(*EepHttpd) error) (*EepHttpd, error) { func NewEepHttpdFromOptions(opts ...func(*EepHttpd) error) (*EepHttpd, error) {
var s EepHttpd 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") log.Println("Initializing eephttpd")
for _, o := range opts { for _, o := range opts {
if err := o(&s); err != nil { if err := o(&s); err != nil {
return nil, err 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() 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()) //log.Println("Options loaded", s.Print())
if e != nil { if e != nil {
return nil, e return nil, e

32
go.mod
View File

@@ -3,35 +3,53 @@ module github.com/eyedeekay/eephttpd
go 1.12 go 1.12
require ( require (
github.com/PeteGabriel/torgo v0.0.0-20200509093753-d38b3aa2685a
github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d // indirect github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d // indirect
github.com/andybalholm/cascadia v1.1.0 // 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/creack/pty v1.1.9 // indirect
github.com/cryptix/go v1.5.0 // 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/outproxy v0.0.0-20190913044809-33f1668ccb7d // indirect
github.com/eyedeekay/sam-forwarder v0.0.0-20190928041036-d2f767dbe008 github.com/eyedeekay/sam-forwarder v0.32.1
github.com/eyedeekay/sam3 v0.0.0-20190730185140-f8d54526ea25 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/google/go-cmp v0.3.1 // indirect
github.com/gorilla/sessions v1.2.0 // 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/errors v0.0.0-20190930114154-d42613fe1ab9 // indirect
github.com/juju/testing v0.0.0-20191001232224-ce9dec17d28b // indirect github.com/juju/testing v0.0.0-20191001232224-ce9dec17d28b // indirect
github.com/julienschmidt/httprouter v1.3.0 // indirect github.com/julienschmidt/httprouter v1.3.0 // indirect
github.com/konsorten/go-windows-terminal-sequences v1.0.2 // indirect github.com/konsorten/go-windows-terminal-sequences v1.0.2 // indirect
github.com/kr/pty v1.1.8 // indirect github.com/kr/pty v1.1.8 // indirect
github.com/miolini/datacounter v0.0.0-20190724021726-aa48df3a02c1 // 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/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f // indirect
github.com/oxtoacart/bpool v0.0.0-20190530202638-03653db5a59c // 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/common v0.7.0 // indirect
github.com/prometheus/procfs v0.0.5 // 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/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/spf13/pflag v1.0.5 // indirect
github.com/stretchr/objx v0.2.0 // 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 go.uber.org/multierr v1.2.0 // indirect
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550 // indirect golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad // indirect
golang.org/x/net v0.0.0-20191011234655-491137f69257 // indirect golang.org/x/net v0.0.0-20210119194325-5f4716e94777 // indirect
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e // 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/time v0.0.0-20190921001708-c4c64cad1fd0 // indirect
golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a // indirect golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a // indirect
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898 // indirect golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898 // indirect

View File

@@ -1,6 +1,7 @@
package eephttpd package eephttpd
import ( import (
"bytes"
"fmt" "fmt"
"io/ioutil" "io/ioutil"
"log" "log"
@@ -12,8 +13,47 @@ import (
"github.com/d5/tengo/script" "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) { func (f *EepHttpd) ServeHTTP(rw http.ResponseWriter, rq *http.Request) {
rp := f.checkURL(rq) 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") { if strings.HasSuffix(rp, ".md") {
f.HandleMarkdown(rw, rq) f.HandleMarkdown(rw, rq)
return return
@@ -38,6 +78,12 @@ func FileExists(filename string) bool {
func (f *EepHttpd) checkURL(rq *http.Request) string { func (f *EepHttpd) checkURL(rq *http.Request) string {
p := rq.URL.Path 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, "/") { if strings.HasSuffix(rq.URL.Path, "/") {
p = filepath.Join(rq.URL.Path, "index.html") 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)) { if !FileExists(filepath.Join(f.ServeDir, p)) {
p = filepath.Join(rq.URL.Path, "index.tengo") p = filepath.Join(rq.URL.Path, "index.tengo")
if FileExists(filepath.Join(f.ServeDir, p)) { if !FileExists(filepath.Join(f.ServeDir, p)) {
p = filepath.Join(rq.URL.Path, "index.tengo") p = rq.URL.Path
} }
} }
log.Println(p) fp := filepath.Join(f.ServeDir, p)
return filepath.Join(f.ServeDir, p) return fp
} }
func (f *EepHttpd) HandleScript(rw http.ResponseWriter, rq *http.Request) { 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) 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) { func (f *EepHttpd) HandleFile(rw http.ResponseWriter, rq *http.Request) {
path := f.checkURL(rq) path := f.checkURL(rq)
bytes, err := ioutil.ReadFile(path) bytes, err := ioutil.ReadFile(path)

View File

@@ -1,17 +1,17 @@
<h1 id="eephttpd">eephttpd</h1> <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>So much for a simple static file server.</p>
<p>to build:</p> <p>eepHttpd is a web hosting tool for content in I2P, I2P sites, and I2P torrents. On its own, its basically a static directory server with limited scripting abilities written in pure-Go.</p>
<pre><code> git clone https://github.com/eyedeekay/eephttpd &amp;&amp; cd eephttpd <p>However, it responds differently to different kinds of interaction.</p>
go get -u &quot;github.com/eyedeekay/sam-forwarder&quot; <ol type="1">
go get -u &quot;github.com/eyedeekay/sam-forwarder/config&quot; <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>
go build</code></pre> <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 sites exact content, and participate in keeping the sites content up.</li>
<p>to run:</p> <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>
<pre><code> ./eephttpd</code></pre> <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>
<p>will serve the files from ./www, and store i2p keys in the working directory.</p> </ol>
<h2 id="usage"><a href="USAGE.md">Usage</a></h2> <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> <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> <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> <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 its i2p tunnel. It can be masked from the localhost using a container.</p>
<pre><code>Usage of ./eephttpd: <pre><code>Usage of ./eephttpd:
-a string -a string
hostname to serve on (default &quot;127.0.0.1&quot;) hostname to serve on (default &quot;127.0.0.1&quot;)
@@ -81,4 +81,4 @@
--volumes-from eephttpd-volume \ --volumes-from eephttpd-volume \
eyedeekay/eephttpd</code></pre> eyedeekay/eephttpd</code></pre>
<h2 id="instance">instance</h2> <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>