7 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
6 changed files with 189 additions and 51 deletions

View File

@@ -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

View File

@@ -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.

View File

@@ -3,20 +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
}
@@ -28,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()
}
}
@@ -36,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 {
@@ -51,24 +64,77 @@ 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))
@@ -81,7 +147,11 @@ func Never(gitkit.Credential, *gitkit.Request) (bool, error) {
//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 {
@@ -89,7 +159,10 @@ func NewEepHttpdFromOptions(opts ...func(*EepHttpd) error) (*EepHttpd, error) {
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,

30
go.mod
View File

@@ -3,37 +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

View File

@@ -1,6 +1,7 @@
package eephttpd
import (
"bytes"
"fmt"
"io/ioutil"
"log"
@@ -12,12 +13,46 @@ 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"))
log.Println(rq.Header.Get("User-Agent"))
f.HandleFile(rw, rq)
return
return
}
if strings.HasSuffix(rp, ".md") {
f.HandleMarkdown(rw, rq)
@@ -43,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")
}
@@ -55,8 +96,8 @@ func (f *EepHttpd) checkURL(rq *http.Request) string {
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) {
@@ -90,8 +131,8 @@ func (f *EepHttpd) HandleMarkdown(rw http.ResponseWriter, rq *http.Request) {
}
func (f *EepHttpd) HandleGit(rw http.ResponseWriter, rq *http.Request) {
log.Println("Handling Git")
f.Server.ServeHTTP(rw, rq)
log.Println("Handling Git")
f.Server.ServeHTTP(rw, rq)
}
func (f *EepHttpd) HandleFile(rw http.ResponseWriter, rq *http.Request) {

View File

@@ -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 &amp;&amp; cd eephttpd
go get -u &quot;github.com/eyedeekay/sam-forwarder&quot;
go get -u &quot;github.com/eyedeekay/sam-forwarder/config&quot;
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 its own, its 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 sites exact content, and participate in keeping the sites 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 its 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 &quot;127.0.0.1&quot;)
@@ -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>