diff options
-rw-r--r-- | client.go | 20 | ||||
-rw-r--r-- | main.go | 35 | ||||
-rw-r--r-- | static/faq.html | 4 | ||||
-rw-r--r-- | static/index.html | 20 | ||||
-rw-r--r-- | static/ncatalog.html | 6 | ||||
-rw-r--r-- | static/posts.html | 32 |
6 files changed, 85 insertions, 32 deletions
@@ -174,6 +174,9 @@ func AllNewsGet(w http.ResponseWriter, r *http.Request, db *sql.DB) { func OutboxGet(w http.ResponseWriter, r *http.Request, db *sql.DB, collection Collection){ t := template.Must(template.New("").Funcs(template.FuncMap{ + "proxy": func(url string) string { + return MediaProxy(url) + }, "sub": func (i, j int) int { return i - j }}).ParseFiles("./static/main.html", "./static/nposts.html", "./static/top.html", "./static/bottom.html", "./static/posts.html")) @@ -224,6 +227,9 @@ func OutboxGet(w http.ResponseWriter, r *http.Request, db *sql.DB, collection Co func CatalogGet(w http.ResponseWriter, r *http.Request, db *sql.DB, collection Collection){ t := template.Must(template.New("").Funcs(template.FuncMap{ + "proxy": func(url string) string { + return MediaProxy(url) + }, "sub": func (i, j int) int { return i - j }}).ParseFiles("./static/main.html", "./static/ncatalog.html", "./static/top.html")) actor := collection.Actor @@ -258,6 +264,9 @@ func CatalogGet(w http.ResponseWriter, r *http.Request, db *sql.DB, collection C func PostGet(w http.ResponseWriter, r *http.Request, db *sql.DB){ t := template.Must(template.New("").Funcs(template.FuncMap{ + "proxy": func(url string) string { + return MediaProxy(url) + }, "sub": func (i, j int) int { return i - j }}).ParseFiles("./static/main.html", "./static/npost.html", "./static/top.html", "./static/bottom.html", "./static/posts.html")) path := r.URL.Path @@ -567,3 +576,14 @@ type BoardSortAsc []Board func (a BoardSortAsc) Len() int { return len(a) } func (a BoardSortAsc) Less(i, j int) bool { return a[i].Name < a[j].Name } func (a BoardSortAsc) Swap(i, j int) { a[i], a[j] = a[j], a[i] } + +func MediaProxy(url string) string { + re := regexp.MustCompile("(.+)?" + Domain + "(.+)?") + + if re.MatchString(url) { + return url + } + + MediaHashs[HashMedia(url)] = url + return "/api/media?hash=" + HashMedia(url) +} @@ -21,6 +21,8 @@ import ( "bufio" "io" "github.com/gofrs/uuid" + "crypto/sha256" + "encoding/hex" ) var Port = ":" + GetConfigValue("instanceport") @@ -45,6 +47,8 @@ var Salt = GetConfigValue("instancesalt") var activitystreams = "application/ld+json; profile=\"https://www.w3.org/ns/activitystreams\"" +var MediaHashs = make(map[string]string) + func main() { CreatedNeededDirectories() @@ -1203,6 +1207,10 @@ func main() { go AddInstanceToIndexDB(db, actor) }) + http.HandleFunc("/api/media", func(w http.ResponseWriter, r *http.Request) { + RouteImages(w, r.URL.Query().Get("hash")) + }) + fmt.Println("Server for " + Domain + " running on port " + Port) fmt.Println("Mod key: " + *Key) @@ -2566,3 +2574,30 @@ func GetCollectionFromReq(path string) Collection { return respCollection } +func HashMedia(media string) string { + h:= sha256.New() + h.Write([]byte(media)) + return hex.EncodeToString(h.Sum(nil)) +} + +func RouteImages(w http.ResponseWriter, media string) { + + req, err := http.NewRequest("GET", MediaHashs[media], nil) + + CheckError(err, "error with Route Images req") + + resp, err := http.DefaultClient.Do(req) + + CheckError(err, "error with Route Images resp") + + defer resp.Body.Close() + + body, _ := ioutil.ReadAll(resp.Body) + for name, values := range resp.Header { + for _, value := range values { + w.Header().Set(name, value) + } + } + + w.Write(body) +} diff --git a/static/faq.html b/static/faq.html index f98fd9c..35c07f0 100644 --- a/static/faq.html +++ b/static/faq.html @@ -10,7 +10,7 @@ <h1 style="text-align: center;">FAQ</h1> <div> <h4>What is fchan?</h4> - <p>fchan, short for FChannel, is a federated image board based on <a href="https://activitypub.rocks/">ActivityPub</a>, a protocol which allows social sites like social media and image boards to be decentralized. Boards across sites which are on the opposite sides of the Globe can be connected and feeds can be shared or followed. It strives to be familiar looking to regular *chan users.</p><p> You can get the source code on <a href="https://github.com/FChannel0">https://github.com/FChannel0</a> which is available under <a href="https://en.wikipedia.org/wiki/Affero_General_Public_License">AGPLv3</a>, which means that you can modify the source code of fchan however you like as long as you share your source code with everyone else. We appreciate and encourage any positive contributions to the source code!</p> + <p>fchan, short for FChannel, is a federated image board based on <a href="https://activitypub.rocks/">ActivityPub</a>, a protocol which allows social sites like social media and image boards to be decentralized. Boards across sites which are on the opposite sides of the Globe can be connected and feeds can be shared or followed. It pulls likeness from other chans for ease of familiarity and use.</p><p> You can get the source code on <a href="https://github.com/FChannel0">https://github.com/FChannel0</a> which is available under <a href="https://en.wikipedia.org/wiki/Affero_General_Public_License">AGPLv3</a>, which means that you can modify the source code of fchan however you like as long as you share your source code with everyone else. We appreciate and encourage any positive contributions to the source code!</p> <h4 id="options">What are the "Options" used for when posting?</h4> <p>The "Options" field can be used for special options when posting.</p> @@ -56,7 +56,7 @@ <p>Soon™.</p> <h4 id="version">What version is this FChannel instance?</h4> - <p>v0.6.1-dev</p> + <p>v0.0.7-dev</p> </div> <div style="width: 500px; margin:0 auto; margin-top: 50px; text-align: center;"> <a href="/">[Home]</a><a href="/static/rules.html">[Rules]</a><a href="/static/faq.html">[FAQ]</a> diff --git a/static/index.html b/static/index.html index 667efd4..b706e6b 100644 --- a/static/index.html +++ b/static/index.html @@ -64,17 +64,15 @@ {{ end }} <div class="popup-box" style="margin-top:50px;"> - <table style="text-align: left; margin: 25px;"> - <th> - <tr><h4>Current known instances</h4></tr> - </th> - - {{ range .InstanceIndex }} - <tr> - <td><a href="{{ .Id }}">{{ .Id }}</a></td> - </tr> - {{ end }} - </table> + <h4 style="margin-bottom:5px;">Current known instances</h4> + <span>(always use a proxy)</span> + <table style="text-align: left; margin: 25px;"> + {{ range .InstanceIndex }} + <tr> + <td><a href="{{ .Id }}">{{ .Id }}</a></td> + </tr> + {{ end }} + </table> </div> </div> {{ end }} diff --git a/static/ncatalog.html b/static/ncatalog.html index 1f6fc69..4c6c589 100644 --- a/static/ncatalog.html +++ b/static/ncatalog.html @@ -67,7 +67,7 @@ img.style = "max-width: 180px; max-height: 180px;" img.setAttribute("id", "img") img.setAttribute("main", "1") - img.setAttribute("src", "{{ (index .Attachment 0).Href }}") + img.setAttribute("src", "{{ proxy (index .Attachment 0).Href }}") media.appendChild(img) } @@ -75,7 +75,7 @@ var audio = document.createElement("audio") audio.controls = 'controls' audio.preload = 'metadata' - audio.src = '{{ (index .Attachment 0).Href }}' + audio.src = '{{ proxy (index .Attachment 0).Href }}' audio.type = '{{ (index .Attachment 0).MediaType }}' audio.style = "margin-right: 10px; margin-bottom: 10px; max-width: 180px; max-height: 180px;" audio.innerText = 'Audio is not supported.' @@ -87,7 +87,7 @@ video.controls = 'controls' video.preload = 'metadata' video.muted = 'muted' - video.src = '{{ (index .Attachment 0).Href }}' + video.src = '{{ proxy (index .Attachment 0).Href }}' video.type = '{{ (index .Attachment 0).MediaType }}' video.style = "margin-right: 10px; margin-bottom: 10px; max-width: 180px; max-height: 180px;" video.innerText = 'Video is not supported.' diff --git a/static/posts.html b/static/posts.html index 319da03..d16f780 100644 --- a/static/posts.html +++ b/static/posts.html @@ -16,7 +16,7 @@ <a href="/deleteattach?id={{ .Id }}&board={{ $board.Actor.Name }}">[Delete Attachment]</a> <a href="/marksensitive?id={{ .Id }}&board={{ $board.Actor.Name }}">[Mark Sensitive]</a> {{ end }} - <span style="display: block;">File: <a id="{{ .Id }}-img" href="{{ (index .Attachment 0).Href}}">{{ (index .Attachment 0).Name }}</a><span id="{{ .Id }}-size">({{ (index .Attachment 0).Size }})</span></span> + <span style="display: block;">File: <a id="{{ .Id }}-img" href="{{ proxy (index .Attachment 0).Href}}">{{ (index .Attachment 0).Name }}</a><span id="{{ .Id }}-size">({{ (index .Attachment 0).Size }})</span></span> <div id="hide-{{ .Id }}" style="display: none;">[Hide]</div> <div id="sensitive-{{ .Id }}" style="display: none;"><div style="position: relative; text-align: center;"><img id="sensitive-img-{{ .Id }}" style="float: left; margin-right: 10px; margin-bottom: 10px; max-width: 250px; max-height: 250px;" src="/static/sensitive.png"><div id="sensitive-text-{{ .Id }}" style="width: 240px; position: absolute; margin-top: 110px; padding: 5px; background-color: black; color: white; cursor: default; ">NSFW Content</div></div></div> <div id="media-{{ .Id }}"></div> @@ -49,13 +49,13 @@ img.setAttribute("id", "img") img.setAttribute("main", "1") img.setAttribute("enlarge", "0") - img.setAttribute("attachment", "{{ (index .Attachment 0).Href }}") + img.setAttribute("attachment", "{{ proxy (index .Attachment 0).Href }}") {{ if .Preview.Href }} - img.setAttribute("src", "{{ .Preview.Href }}") - img.setAttribute("preview", "{{ .Preview.Href }}") + img.setAttribute("src", "{{ proxy .Preview.Href }}") + img.setAttribute("preview", "{{ proxy .Preview.Href }}") {{ else }} - img.setAttribute("src", "{{ (index .Attachment 0).Href }}") - img.setAttribute("preview", "{{ (index .Attachment 0).Href }}") + img.setAttribute("src", "{{ proxy (index .Attachment 0).Href }}") + img.setAttribute("preview", "{{ proxy (index .Attachment 0).Href }}") {{ end }} media.appendChild(img) } @@ -64,7 +64,7 @@ var audio = document.createElement("audio") audio.controls = 'controls' audio.preload = 'metadata' - audio.src = '{{ (index .Attachment 0).Href }}' + audio.src = '{{ proxy (index .Attachment 0).Href }}' audio.type = '{{ (index .Attachment 0).MediaType }}' audio.style = "float: left; margin-right: 10px; margin-bottom: 10px; max-width: 250px; max-height: 250px;" audio.innerText = 'Audio is not supported.' @@ -76,7 +76,7 @@ video.controls = 'controls' video.preload = 'metadata' video.muted = 'muted' - video.src = '{{ (index .Attachment 0).Href }}' + video.src = '{{ proxy (index .Attachment 0).Href }}' video.type = '{{ (index .Attachment 0).MediaType }}' video.style = "float: left; margin-right: 10px; margin-bottom: 10px; max-width: 250px; max-height: 250px;" video.innerText = 'Video is not supported.' @@ -106,7 +106,7 @@ <a href="/deleteattach?id={{ .Id }}&board={{ $board.Actor.Name }}">[Delete Attachment]</a> <a href="/marksensitive?id={{ .Id }}&board={{ $board.Actor.Name }}">[Mark Sensitive]</a> {{ end }} - <span style="display: block;">File <a id="{{ .Id }}-img" href="{{ (index .Attachment 0).Href}}">{{ (index .Attachment 0).Name }}</a> <span id="{{ .Id }}-size">({{ (index .Attachment 0).Size }})</span></span> + <span style="display: block;">File <a id="{{ .Id }}-img" href="{{ proxy (index .Attachment 0).Href}}">{{ (index .Attachment 0).Name }}</a> <span id="{{ .Id }}-size">({{ (index .Attachment 0).Size }})</span></span> <div id="hide-{{ .Id }}" style="display: none;">[Hide]</div> <div id="sensitive-{{ .Id }}" style="display: none;"><div style="position: relative; text-align: center;"><img id="sensitive-img-{{ .Id }}" style="float: left; margin-right: 10px; margin-bottom: 10px; max-width: 250px; max-height: 250px;" src="/static/sensitive.png"><div id="sensitive-text-{{ .Id }}" style="width: 240px; position: absolute; margin-top: 110px; padding: 5px; background-color: black; color: white; cursor: default; ">NSFW Content</div></div></div> <div> </div> @@ -140,14 +140,14 @@ img.setAttribute("id", "img") img.setAttribute("main", "1") img.setAttribute("enlarge", "0") - img.setAttribute("attachment", "{{ (index .Attachment 0).Href }}") + img.setAttribute("attachment", "{{ proxy (index .Attachment 0).Href }}") img.setAttribute("post", "{{ .Id }}") {{ if and .Preview.Href . }} - img.setAttribute("src", "{{ .Preview.Href }}") - img.setAttribute("preview", "{{ .Preview.Href }}") + img.setAttribute("src", "{{ proxy .Preview.Href }}") + img.setAttribute("preview", "{{ proxy .Preview.Href }}") {{ else }} - img.setAttribute("src", "{{ (index .Attachment 0).Href }}") - img.setAttribute("preview", "{{ (index .Attachment 0).Href }}") + img.setAttribute("src", "{{ proxy (index .Attachment 0).Href }}") + img.setAttribute("preview", "{{ proxy (index .Attachment 0).Href }}") {{ end }} media.appendChild(img) } @@ -156,7 +156,7 @@ var audio = document.createElement("audio") audio.controls = 'controls' audio.preload = 'metadata' - audio.src = '{{ (index .Attachment 0).Href }}' + audio.src = '{{ proxy (index .Attachment 0).Href }}' audio.type = '{{ (index .Attachment 0).MediaType }}' audio.style = "float: left; margin-right: 10px; margin-bottom: 10px; max-width: 250px; max-height: 250px;" audio.innerText = 'Audio is not supported.' @@ -168,7 +168,7 @@ video.controls = 'controls' video.preload = 'metadata' video.muted = 'muted' - video.src = '{{ (index .Attachment 0).Href }}' + video.src = '{{ proxy (index .Attachment 0).Href }}' video.type = '{{ (index .Attachment 0).MediaType }}' video.style = "float: left; margin-right: 10px; margin-bottom: 10px; max-width: 250px; max-height: 250px;" video.innerText = 'Video is not supported.' |