chore: add peerfinder assets
This commit is contained in:
8 files changed
+416
-1
No files matched your search
@@ -0,0 +1,119 @@
|
||||
package graphiql
|
||||
|
||||
import (
|
||||
"html/template"
|
||||
"net/http"
|
||||
"net/url"
|
||||
)
|
||||
|
||||
var page = template.Must(template.New("graphiql").Parse(`<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>{{.title}}</title>
|
||||
<style>
|
||||
body {
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
#graphiql {
|
||||
height: 100vh;
|
||||
}
|
||||
</style>
|
||||
<script
|
||||
src="https://cdn.jsdelivr.net/npm/react@17.0.2/umd/react.production.min.js"
|
||||
integrity="{{.reactSRI}}"
|
||||
crossorigin="anonymous"
|
||||
></script>
|
||||
<script
|
||||
src="https://cdn.jsdelivr.net/npm/react-dom@17.0.2/umd/react-dom.production.min.js"
|
||||
integrity="{{.reactDOMSRI}}"
|
||||
crossorigin="anonymous"
|
||||
></script>
|
||||
<link
|
||||
rel="stylesheet"
|
||||
href="https://cdn.jsdelivr.net/npm/graphiql@{{.version}}/graphiql.min.css"
|
||||
x-integrity="{{.cssSRI}}"
|
||||
crossorigin="anonymous"
|
||||
/>
|
||||
</head>
|
||||
<body>
|
||||
<div id="graphiql">Loading...</div>
|
||||
|
||||
<script
|
||||
src="https://cdn.jsdelivr.net/npm/graphiql@{{.version}}/graphiql.min.js"
|
||||
x-integrity="{{.jsSRI}}"
|
||||
crossorigin="anonymous"
|
||||
></script>
|
||||
|
||||
<script>
|
||||
{{- if .endpointIsAbsolute}}
|
||||
const url = {{.endpoint}};
|
||||
const subscriptionUrl = {{.subscriptionEndpoint}};
|
||||
{{- else}}
|
||||
const url = location.protocol + '//' + location.host + {{.endpoint}};
|
||||
const wsProto = location.protocol == 'https:' ? 'wss:' : 'ws:';
|
||||
const subscriptionUrl = wsProto + '//' + location.host + {{.endpoint}};
|
||||
{{- end}}
|
||||
|
||||
const fetcher = GraphiQL.createFetcher({ url, subscriptionUrl });
|
||||
ReactDOM.render(
|
||||
React.createElement(GraphiQL, {
|
||||
fetcher: fetcher,
|
||||
isHeadersEditorEnabled: true,
|
||||
shouldPersistHeaders: true
|
||||
}),
|
||||
document.getElementById('graphiql'),
|
||||
);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
`))
|
||||
|
||||
// Handler responsible for setting up the playground
|
||||
func Handler(title string, endpoint string) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Add("Content-Type", "text/html; charset=UTF-8")
|
||||
err := page.Execute(w, map[string]interface{}{
|
||||
"title": title,
|
||||
"endpoint": endpoint,
|
||||
"endpointIsAbsolute": endpointHasScheme(endpoint),
|
||||
"subscriptionEndpoint": getSubscriptionEndpoint(endpoint),
|
||||
"version": "2.0.10",
|
||||
"cssSRI": "sha256-gQryfbGYeYFxnJYnfPStPYFt0+uv8RP8Dm++eh00G9c=",
|
||||
"jsSRI": "sha256-qQ6pw7LwTLC+GfzN+cJsYXfVWRKH9O5o7+5H96gTJhQ=",
|
||||
"reactSRI": "sha256-Ipu/TQ50iCCVZBUsZyNJfxrDk0E2yhaEIz0vqI+kFG8=",
|
||||
"reactDOMSRI": "sha256-nbMykgB6tsOFJ7OdVmPpdqMFVk4ZsqWocT6issAPUF0=",
|
||||
})
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// endpointHasScheme checks if the endpoint has a scheme.
|
||||
func endpointHasScheme(endpoint string) bool {
|
||||
u, err := url.Parse(endpoint)
|
||||
return err == nil && u.Scheme != ""
|
||||
}
|
||||
|
||||
// getSubscriptionEndpoint returns the subscription endpoint for the given
|
||||
// endpoint if it is parsable as a URL, or an empty string.
|
||||
func getSubscriptionEndpoint(endpoint string) string {
|
||||
u, err := url.Parse(endpoint)
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
switch u.Scheme {
|
||||
case "https":
|
||||
u.Scheme = "wss"
|
||||
default:
|
||||
u.Scheme = "ws"
|
||||
}
|
||||
|
||||
return u.String()
|
||||
}
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
/*!
|
||||
* Bootstrap v3.3.6 (http://getbootstrap.com)
|
||||
* Copyright 2011-2015 Twitter, Inc.
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
||||
*//*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */html{font-family:sans-serif;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}dfn{font-style:italic}h1{margin:.67em 0;font-size:2em}mark{color:#000;background:#ff0}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{height:0;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{margin:0;font:inherit;color:inherit}button{overflow:visible}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{padding:0;border:0}input{line-height:normal}input[type=checkbox],input[type=radio]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:0}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{height:auto}input[type=search]{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;-webkit-appearance:textfield}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}fieldset{padding:.35em .625em .75em;margin:0 2px;border:1px solid silver}legend{padding:0;border:0}textarea{overflow:auto}optgroup{font-weight:700}table{border-spacing:0;border-collapse:collapse}td,th{padding:0}/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */@media print{*,:after,:before{color:#000!important;text-shadow:none!important;background:0 0!important;-webkit-box-shadow:none!important;box-shadow:none!important}a,a:visited{text-decoration:underline}a[href]:after{content:" (" attr(href) ")"}abbr[title]:after{content:" (" attr(title) ")"}a[href^="javascript:"]:after,a[href^="#"]:after{content:""}blockquote,pre{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}img{max-width:100%!important}h2,h3,p{orphans:3;widows:3}h2,h3{page-break-after:avoid}.navbar{display:none}.btn>.caret,.dropup>.btn>.caret{border-top-color:#000!important}.label{border:1px solid #000}.table{border-collapse:collapse!important}.table td,.table th{background-color:#fff!important}.table-bordered td,.table-bordered th{border:1px solid #ddd!important}}@font-face{font-family:'Glyphicons Halflings';src:url(../fonts/glyphicons-halflings-regular.eot);src:url(../fonts/glyphicons-halflings-regular.eot?#iefix) format('embedded-opentype'),url(../fonts/glyphicons-halflings-regular.woff2) format('woff2'),url(../fonts/glyphicons-halflings-regular.woff) format('woff'),url(../fonts/glyphicons-halflings-regular.ttf) format('truetype'),url(../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular) format('svg')}.glyphicon{position:relative;top:1px;display:inline-block;font-family:'Glyphicons Halflings';font-style:normal;font-weight:400;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.glyphicon-asterisk:before{content:"\002a"}.glyphicon-plus:before{content:"\002b"}.glyphicon-eur:before,.glyphicon-euro:before{content:"\20ac"}.glyphicon-minus:before{content:"\2212"}.glyphicon-cloud:before{content:"\2601"}.glyphicon-envelope:before{content:"\2709"}.glyphicon-pencil:before{content:"\270f"}.glyphicon-glass:before{content:"\e001"}.glyphicon-music:before{content:"\e002"}.glyphicon-search:before{content:"\e003"}.glyphicon-heart:before{content:"\e005"}.glyphicon-star:before{content:"\e006"}.glyphicon-star-empty:before{content:"\e007"}.glyphicon-user:before{content:"\e008"}.glyphicon-film:before{content:"\e009"}.glyphicon-th-large:before{content:"\e010"}.glyphicon-th:before{content:"\e011"}.glyphicon-th-list:before{content:"\e012"}.glyphicon-ok:before{content:"\e013"}.glyphicon-remove:before{content:"\e014"}.glyphicon-zoom-in:before{content:"\e015"}.glyphicon-zoom-out:before{content:"\e016"}.glyphicon-off:before{content:"\e017"}.glyphicon-signal:before{content:"\e018"}.glyphicon-cog:before{content:"\e019"}.glyphicon-trash:before{content:"\e020"}.glyphicon-home:before{content:"\e021"}.glyphicon-file:before{content:"\e022"}.glyphicon-time:before{content:"\e023"}.glyphicon-road:before{content:"\e024"}.glyphicon-download-alt:before{content:"\e025"}.glyphicon-download:before{content:"\Line truncated
|
||||
/*# sourceMappingURL=bootstrap.min.css.map */
|
||||
@@ -0,0 +1,58 @@
|
||||
/* Space out content a bit */
|
||||
body {
|
||||
padding-top: 20px;
|
||||
padding-bottom: 20px;
|
||||
}
|
||||
|
||||
/* Everything but the jumbotron gets side spacing for mobile first views */
|
||||
.header,
|
||||
.footer {
|
||||
padding-right: 15px;
|
||||
padding-left: 15px;
|
||||
}
|
||||
|
||||
/* Custom page header */
|
||||
.header {
|
||||
padding-bottom: 20px;
|
||||
border-bottom: 1px solid #e5e5e5;
|
||||
}
|
||||
/* Make the masthead heading the same height as the navigation */
|
||||
.header h3 {
|
||||
margin-top: 0;
|
||||
margin-bottom: 0;
|
||||
line-height: 40px;
|
||||
}
|
||||
|
||||
/* Custom page footer */
|
||||
.footer {
|
||||
padding-top: 19px;
|
||||
color: #777;
|
||||
border-top: 1px solid #e5e5e5;
|
||||
}
|
||||
|
||||
/* Customize container */
|
||||
@media (min-width: 768px) {
|
||||
.container {
|
||||
max-width: 730px;
|
||||
}
|
||||
}
|
||||
.container-narrow > hr {
|
||||
margin: 30px 0;
|
||||
}
|
||||
|
||||
|
||||
/* Responsive: Portrait tablets and up */
|
||||
@media screen and (min-width: 768px) {
|
||||
/* Remove the padding we set earlier */
|
||||
.header,
|
||||
.footer {
|
||||
padding-right: 0;
|
||||
padding-left: 0;
|
||||
}
|
||||
/* Space out the masthead */
|
||||
.header {
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
}
|
||||
|
||||
.panel-primary a { color: white; font-weight:bold }
|
||||
@@ -0,0 +1,21 @@
|
||||
<div class="form-group"><label class="col-sm-2 control-label" >Peer Name</label><div class='col-sm-10'><input class="form-control" type=text name=peer_name value="{$o.peer_name|default:''|escape}"/></div></div>
|
||||
<div class="form-group"><label class="col-sm-2 control-label" >IRC Nick</label><div class='col-sm-10'><input class="form-control" type=text name=peer_nick value="{$o.peer_nick|default:''|escape}"/></div></div>
|
||||
<div class="form-group"><label class="col-sm-2 control-label" >Note</label><div class='col-sm-10'><input class="form-control" type=text name=peer_note value="{$o.peer_note|default:''|escape}"/></div></div>
|
||||
<div class="form-group"><label class="col-sm-2 control-label" >Country</label><div class='col-sm-2'><input class="form-control" type=text name=peer_country maxlength=3 value="{$o.peer_country|default:''|escape}"/></div></div>
|
||||
<div class="form-group"><label class="col-sm-2 control-label" >VPN Types</label><div class='col-sm-10'><select class="form-control" size=12 multiple name="peer_type[]">
|
||||
<option {$types['openvpn']|default:''} value="openvpn">openvpn</option>
|
||||
<option {$types['gre/ipsec']|default:''} value="gre/ipsec">gre/ipsec</option>
|
||||
<option {$types['gre/plain']|default:''} value="gre/plain">gre/plain</option>
|
||||
<option {$types['fastd']|default:''} value="fastd">fastd</option>
|
||||
<option {$types['tinc']|default:''} value="tinc">tinc</option>
|
||||
<option {$types['zerotier']|default:''} value="zerotier">zerotier</option>
|
||||
<option {$types['wireguard']|default:''} value="wireguard">wireguard</option>
|
||||
<option {$types['pptp']|default:''} value="pptp">pptp</option>
|
||||
<option {$types['l2tp']|default:''} value="l2tp">l2tp</option>
|
||||
<option {$types['other']|default:''} value="other">other</option>
|
||||
</select></div></div>
|
||||
<div class="form-group"><label class="col-sm-2 control-label" >Address Family</label><div class='col-sm-10'>
|
||||
<label><input type="radio" name="peer_family" value="1" {$fam[0]|default:''} /> ipv4 </label>
|
||||
<label><input type="radio" name="peer_family" value="2" {$fam[1]|default:''} /> ipv6 </label>
|
||||
<label><input type="radio" name="peer_family" value="3" {$fam[2]|default:''} /> both </label>
|
||||
</div></div>
|
||||
@@ -0,0 +1,41 @@
|
||||
{{define "main"}}
|
||||
<!DOCTYPE html>
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
{{template "meta" .}}
|
||||
<title>DN42 PingFinder</title>
|
||||
|
||||
<link href="/peers/assets/bootstrap.min.css" rel="stylesheet" integrity="sha384-1q8mTJOASx8j1Au+a5WDVnPi2lkFfwwEAa8hDDdjZlpLegxhjVME1fgjWPGmkzs7" crossorigin="anonymous">
|
||||
<link href="/peers/assets/peerfinder.css" rel="stylesheet" integrity="sha384-ZsT4S9156eA60lsB4aOfffKowiaZ0NG7gIQfgIfGoxT6FxFocYH39kZgYaeZCvql" crossorigin="anonymous">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<div class="container-fluid">
|
||||
<div class="header clearfix">
|
||||
<nav>
|
||||
<ul class="nav nav-pills pull-right">
|
||||
<li role="presentation"><a href="/peers">Home</a></li>
|
||||
<li role="presentation"><a href="/peers/status">Status</a></li>
|
||||
<li role="presentation"><a href="//util.sour.is/peer">Sign up/Manage</a></li>
|
||||
<li role="presentation"><a href="//git.dn42.us/dn42/pingfinder/src/master/clients">Scripts</a></li>
|
||||
</ul>
|
||||
</nav>
|
||||
<h3 class="text-muted">DN42 PeerFinder</h3>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class=container>
|
||||
{{template "content" .}}
|
||||
</div>
|
||||
|
||||
<div class=container>
|
||||
<h2>JSON Output</h2>
|
||||
<pre style="background:#222; color:#ddd; height: 20em; font-size: 65%">{$o|json_encode:128|escape}</pre>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
{{end}}
|
||||
@@ -0,0 +1,43 @@
|
||||
{{template "main" .}}
|
||||
|
||||
{{define "meta"}}
|
||||
<meta http-equiv="refresh" content="30">
|
||||
{{end}}
|
||||
|
||||
{{define "content"}}
|
||||
<h2>What is this?</h2>
|
||||
|
||||
<p>This tool allows you to find "good" peerings
|
||||
for <a href="https://dn42.net">dn42</a>, by measuring the latency from
|
||||
various points in the network towards you.</p>
|
||||
|
||||
<p>If you don't know what dn42 is,
|
||||
read <a href="https://dn42.net/Home">the website</a> and in particular
|
||||
the <a href="https://dn42.net/Getting-started-with-dn42">Getting Started
|
||||
guide</a>.</p>
|
||||
|
||||
<h2>How does it work?</h2>
|
||||
|
||||
<p>
|
||||
<ol>
|
||||
<li>You enter your (Internet) IP address</li>
|
||||
<li>Various routers participating in dn42 will ping you over the Internet</li>
|
||||
<li>After a short while, you get back all the latency results</li>
|
||||
<li>You can then peer with people close to you (low latency)</li>
|
||||
</ol>
|
||||
</p>
|
||||
|
||||
<form class="form-inline" method="POST" action="/peers/req">
|
||||
<label>Ping IP Address [Check Hidden?]:</label>
|
||||
<div class="input-group input-group-sm">
|
||||
<input class="form-control" type="text" name="req_ip" placeholder="{$rq->remote_ip}">
|
||||
<span class="input-group-addon">
|
||||
<input type="checkbox" name="req_hidden" value=1 aria-label="Hidden?">
|
||||
</span>
|
||||
</div>
|
||||
<button class="btn btn-default" type="submit">Submit</button>
|
||||
</form>
|
||||
|
||||
<p>If you mark your measurement as hidden, it will not be displayed on the
|
||||
page below. Note that the IP addresses of the target will be shown alongside the result.</p>
|
||||
{{end}}
|
||||
Reference in new issue
Block a user