526 lines
17 KiB
HTML
526 lines
17 KiB
HTML
<!doctype html>
|
|
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
<link rel="canonical" href="https://{{ .Domain }}/" />
|
|
<style>
|
|
body {
|
|
margin: 0;
|
|
padding-bottom: 40px
|
|
}
|
|
|
|
footer,
|
|
header,
|
|
main,
|
|
nav {
|
|
display: block
|
|
}
|
|
|
|
@media print {
|
|
* {
|
|
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) ")"
|
|
}
|
|
|
|
p {
|
|
orphans: 3;
|
|
widows: 3
|
|
}
|
|
}
|
|
|
|
* {
|
|
-webkit-box-sizing: border-box;
|
|
-moz-box-sizing: border-box;
|
|
box-sizing: border-box
|
|
}
|
|
|
|
:after,
|
|
:before {
|
|
-webkit-box-sizing: border-box;
|
|
-moz-box-sizing: border-box;
|
|
box-sizing: border-box
|
|
}
|
|
|
|
body {
|
|
font-family: monospace;
|
|
font-size: 1em;
|
|
line-height: 1.6;
|
|
color: #a5a5a5;
|
|
background-color: #121212
|
|
}
|
|
|
|
a {
|
|
text-decoration: none;
|
|
color: #fff
|
|
}
|
|
|
|
h1,
|
|
h4 {
|
|
font-weight: 500;
|
|
line-height: 1.1;
|
|
color: #fff;
|
|
font-family: monospace
|
|
}
|
|
|
|
h1 {
|
|
margin-top: 20px;
|
|
margin-bottom: 20px;
|
|
font-size: 2em
|
|
}
|
|
|
|
h4 {
|
|
margin-top: 15px;
|
|
margin-bottom: 10px;
|
|
padding-left: 15px;
|
|
font-size: 18px
|
|
}
|
|
|
|
p {
|
|
margin: 0 0 10px
|
|
}
|
|
|
|
.text-center {
|
|
text-align: center
|
|
}
|
|
|
|
ul {
|
|
margin-top: 0;
|
|
margin-bottom: 10px
|
|
}
|
|
|
|
.container {
|
|
padding-right: 15px;
|
|
padding-left: 15px;
|
|
margin-right: auto;
|
|
margin-left: auto
|
|
}
|
|
|
|
@media (min-width:768px) {
|
|
.container {
|
|
width: 750px
|
|
}
|
|
}
|
|
|
|
@media (min-width:992px) {
|
|
.container {
|
|
width: 970px
|
|
}
|
|
}
|
|
|
|
@media (min-width:1200px) {
|
|
.container {
|
|
width: 1170px
|
|
}
|
|
}
|
|
|
|
.col-sm-3,
|
|
.col-sm-4,
|
|
.col-sm-5,
|
|
.col-sm-8,
|
|
.col-sm-9 {
|
|
position: relative;
|
|
min-height: 1px;
|
|
padding-right: 15px;
|
|
padding-left: 15px
|
|
}
|
|
|
|
@media (min-width:768px) {
|
|
|
|
.col-sm-3,
|
|
.col-sm-4,
|
|
.col-sm-5,
|
|
.col-sm-8,
|
|
.col-sm-9 {
|
|
float: left
|
|
}
|
|
|
|
.col-sm-9 {
|
|
width: 75%
|
|
}
|
|
|
|
.col-sm-8 {
|
|
width: 60%
|
|
}
|
|
|
|
.col-sm-5 {
|
|
width: 50%
|
|
}
|
|
|
|
.col-sm-4 {
|
|
width: 40%
|
|
}
|
|
|
|
.col-sm-3 {
|
|
width: 25%
|
|
}
|
|
}
|
|
|
|
.list-group {
|
|
padding-left: 0;
|
|
padding-bottom: 15px
|
|
}
|
|
|
|
.list-group-item {
|
|
position: relative;
|
|
display: block;
|
|
padding: 10px 15px;
|
|
margin-bottom: -1px;
|
|
background-color: #1e1e1e
|
|
}
|
|
|
|
.panel {
|
|
margin-bottom: 20px;
|
|
background-color: #1e1e1e;
|
|
border-radius: 4px;
|
|
border-top:2px solid {{.Color}};
|
|
box-shadow:0 3px 6px rgba(0, 0, 0, .16),
|
|
0 3px 6px rgba(0, 0, 0, .23);
|
|
-webkit-box-shadow:0 3px 6px rgba(0, 0, 0, .16),
|
|
0 3px 6px rgba(0, 0, 0, .23)
|
|
}
|
|
|
|
.panel-heading {
|
|
padding: 10px 15px;
|
|
border-top:2px solid {{.Color}};
|
|
box-shadow:0 3px 6px rgba(0, 0, 0, .16),
|
|
0 3px 6px rgba(0, 0, 0, .23);
|
|
-webkit-box-shadow:0 3px 6px rgba(0, 0, 0, .16),
|
|
0 3px 6px rgba(0, 0, 0, .23)
|
|
}
|
|
|
|
li.list-group-item {
|
|
overflow: auto;
|
|
padding-top: 6px;
|
|
padding-bottom: 6px
|
|
}
|
|
|
|
header.page-header {
|
|
text-align: center
|
|
}
|
|
|
|
@media(max-width:750px) {
|
|
div.col-sm-3 {
|
|
font-weight: 700
|
|
}
|
|
}
|
|
|
|
footer {
|
|
position: fixed;
|
|
height: 60px;
|
|
width: 100%;
|
|
text-align: center;
|
|
left: 0;
|
|
right: 0;
|
|
bottom: 0
|
|
}
|
|
</style>
|
|
<title>{{ .Title }}</title>
|
|
</head>
|
|
|
|
<body>
|
|
<header class="page-header container">
|
|
<h1><a href="/">{{ .Title }}</a></h1>
|
|
</header>
|
|
<nav class="container"></nav>
|
|
<main class="container">
|
|
{{ if not .Info.Query }}
|
|
<div class="panel panel-default">
|
|
<div class="panel-heading">
|
|
<h4>Connection</h4>
|
|
</div>
|
|
<ul class="list-group">
|
|
{{ if .Info.Ip }}
|
|
<li class="list-group-item">
|
|
<div class="col-sm-3">IP Address</div>
|
|
<div class="col-sm-9">{{ .Info.Ip }}</div>
|
|
</li>
|
|
{{ end }}
|
|
{{ if .Info.Hostname }}
|
|
<li class="list-group-item">
|
|
<div class="col-sm-3">Hostname</div>
|
|
<div class="col-sm-9">{{ .Info.Hostname }}</div>
|
|
</li>
|
|
{{ end }}
|
|
{{ if .Info.Port }}
|
|
<li class="list-group-item">
|
|
<div class="col-sm-3">Port</div>
|
|
<div class="col-sm-9">{{ .Info.Port }}</div>
|
|
</li>
|
|
{{ end }}
|
|
{{ if .Info.UserAgent }}
|
|
<li class="list-group-item">
|
|
<div class="col-sm-3">User-agent</div>
|
|
<div class="col-sm-9">{{ .Info.UserAgent }}</div>
|
|
</li>
|
|
{{ end }}
|
|
{{ if .Info.MimeType }}
|
|
<li class="list-group-item">
|
|
<div class="col-sm-3">Mime-type</div>
|
|
<div class="col-sm-9">{{ .Info.MimeType }}</div>
|
|
</li>
|
|
{{ end }}
|
|
{{ if .Info.Language }}
|
|
<li class="list-group-item">
|
|
<div class="col-sm-3">Language</div>
|
|
<div class="col-sm-9">{{ .Info.Language }}</div>
|
|
</li>
|
|
{{ end }}
|
|
{{ if .Info.ContentType }}
|
|
<li class="list-group-item">
|
|
<div class="col-sm-3">Content-type</div>
|
|
<div class="col-sm-9">{{ .Info.ContentType }}</div>
|
|
</li>
|
|
{{ end }}
|
|
{{ if .Info.Encoding }}
|
|
<li class="list-group-item">
|
|
<div class="col-sm-3">Content-encoding</div>
|
|
<div class="col-sm-9">{{ .Info.Encoding }}</div>
|
|
</li>
|
|
{{ end }}
|
|
{{ if .Info.Method }}
|
|
<li class="list-group-item">
|
|
<div class="col-sm-3">Method</div>
|
|
<div class="col-sm-9">{{ .Info.Method }}</div>
|
|
</li>
|
|
{{ end }}
|
|
{{ if .Info.CacheControl }}
|
|
<li class="list-group-item">
|
|
<div class="col-sm-3">Cache-control</div>
|
|
<div class="col-sm-9">{{ .Info.CacheControl }}</div>
|
|
</li>
|
|
{{ end }}
|
|
{{ if .Info.Referer }}
|
|
<li class="list-group-item">
|
|
<div class="col-sm-3">Referer</div>
|
|
<div class="col-sm-9">{{ .Info.Referer }}</div>
|
|
</li>
|
|
{{ end }}
|
|
{{ if .Info.XForwardedFor }}
|
|
<li class="list-group-item">
|
|
<div class="col-sm-3">X-Forwarded-For</div>
|
|
<div class="col-sm-9">{{ .Info.XForwardedFor }}</div>
|
|
</li>
|
|
{{ end }}
|
|
{{ if .Info.XForwardedProto }}
|
|
<li class="list-group-item">
|
|
<div class="col-sm-3">X-Forwarded-Proto</div>
|
|
<div class="col-sm-9">{{ .Info.XForwardedProto }}</div>
|
|
</li>
|
|
{{ end }}
|
|
</ul>
|
|
</div>
|
|
{{ end }}
|
|
{{ if or .Info.Geo.Country .Info.Asn.Org }}
|
|
<div class="panel panel-default">
|
|
<div class="panel-heading">
|
|
<h4>Lookup</h4>
|
|
</div>
|
|
<ul class="list-group">
|
|
{{ if and .Info.Query .Info.Ip }}
|
|
<li class="list-group-item">
|
|
<div class="col-sm-3">IP address</div>
|
|
<div class="col-sm-9">{{ .Info.Ip }}</div>
|
|
</li>
|
|
{{ end }}
|
|
{{ if and .Info.Query .Info.Hostname }}
|
|
<li class="list-group-item">
|
|
<div class="col-sm-3">Hostname</div>
|
|
<div class="col-sm-9">{{ .Info.Hostname }}</div>
|
|
</li>
|
|
{{ end }}
|
|
{{ if .Info.Geo.Country }}
|
|
<li class="list-group-item">
|
|
<div class="col-sm-3">Country</div>
|
|
<div class="col-sm-9">{{ .Info.Geo.Country }}</div>
|
|
</li>
|
|
{{ end }}
|
|
{{ if .Info.Geo.Ccode }}
|
|
<li class="list-group-item">
|
|
<div class="col-sm-3">Country code</div>
|
|
<div class="col-sm-9">{{ .Info.Geo.Ccode }}</div>
|
|
</li>
|
|
{{ end }}
|
|
{{ if .Info.Geo.City }}
|
|
<li class="list-group-item">
|
|
<div class="col-sm-3">City</div>
|
|
<div class="col-sm-9">{{ .Info.Geo.City }}</div>
|
|
</li>
|
|
{{ end }}
|
|
{{ if .Info.Geo.Latitude }}
|
|
<li class="list-group-item">
|
|
<div class="col-sm-3">Latitude</div>
|
|
<div class="col-sm-9">{{ .Info.Geo.Latitude }}</div>
|
|
</li>
|
|
{{ end }}
|
|
{{ if .Info.Geo.Longitude }}
|
|
<li class="list-group-item">
|
|
<div class="col-sm-3">Longitude</div>
|
|
<div class="col-sm-9">{{ .Info.Geo.Longitude }}</div>
|
|
</li>
|
|
{{ end }}
|
|
{{ if .Info.Asn.Asn }}
|
|
<li class="list-group-item">
|
|
<div class="col-sm-3">ASN</div>
|
|
<div class="col-sm-9">{{ .Info.Asn.Asn }}</div>
|
|
</li>
|
|
{{ end }}
|
|
{{ if .Info.Asn.Org }}
|
|
<li class="list-group-item">
|
|
<div class="col-sm-3">Organisation</div>
|
|
<div class="col-sm-9">{{ .Info.Asn.Org }}</div>
|
|
</li>
|
|
{{ end }}
|
|
</ul>
|
|
</div>
|
|
{{ end }}
|
|
{{ if .Info.Ssl.Subject }}
|
|
<div class="panel panel-default">
|
|
<div class="panel-heading">
|
|
<h4>SSL</h4>
|
|
</div>
|
|
<ul class="list-group">
|
|
{{ if .Info.Ssl.Subject }}
|
|
<li class="list-group-item">
|
|
<div class="col-sm-3">Subject</div>
|
|
<div class="col-sm-9">{{ .Info.Ssl.Subject }}</div>
|
|
</li>
|
|
{{ end }}
|
|
{{ if .Info.Ssl.San }}
|
|
<li class="list-group-item">
|
|
<div class="col-sm-3">SAN</div>
|
|
<div class="col-sm-9">{{ range .Info.Ssl.San }}{{ . }} {{ end }}</div>
|
|
</li>
|
|
{{ end }}
|
|
{{ if .Info.Ssl.Issuer }}
|
|
<li class="list-group-item">
|
|
<div class="col-sm-3">Issuer</div>
|
|
<div class="col-sm-9">{{ .Info.Ssl.Issuer }}</div>
|
|
</li>
|
|
{{ end }}
|
|
{{ if .Info.Ssl.NotBefore }}
|
|
<li class="list-group-item">
|
|
<div class="col-sm-3">Not before</div>
|
|
<div class="col-sm-9">{{ .Info.Ssl.NotBefore }}</div>
|
|
</li>
|
|
{{ end }}
|
|
{{ if .Info.Ssl.NotAfter }}
|
|
<li class="list-group-item">
|
|
<div class="col-sm-3">Not after</div>
|
|
<div class="col-sm-9">{{ .Info.Ssl.NotAfter }}</div>
|
|
</li>
|
|
{{ end }}
|
|
{{ if .Info.Ssl.Ocsp }}
|
|
<li class="list-group-item">
|
|
<div class="col-sm-3">OCSP</div>
|
|
<div class="col-sm-9">{{ range .Info.Ssl.Ocsp }}{{ . }} {{ end }}</div>
|
|
</li>
|
|
{{ end }}
|
|
{{ if .Info.Ssl.Alpn }}
|
|
<li class="list-group-item">
|
|
<div class="col-sm-3">ALPN</div>
|
|
<div class="col-sm-9">{{ .Info.Ssl.Alpn }}</div>
|
|
</li>
|
|
{{ end }}
|
|
</ul>
|
|
</div>
|
|
{{ end }}
|
|
<details>
|
|
<summary>Usage examples</summary>
|
|
<div class="panel panel-default">
|
|
<div class="panel-heading">
|
|
<h4>API usage examples</h4>
|
|
</div>
|
|
<ul class="list-group">
|
|
<li class="list-group-item">
|
|
<div class="col-sm-4">curl {{ .Short }}{{ .Argument }}</div>
|
|
<div class="col-sm-8">{{ .Info.Ip }}</div>
|
|
</li>
|
|
{{ if .Info.UserAgent }}
|
|
<li class="list-group-item">
|
|
<div class="col-sm-4">curl {{ .Short }}{{ .Argument }}/user-agent</div>
|
|
<div class="col-sm-8">{{ .Info.UserAgent }}</div>
|
|
</li>
|
|
{{ end }}
|
|
{{ if .Info.Geo.Country }}
|
|
<li class="list-group-item">
|
|
<div class="col-sm-4">curl {{ .Short }}{{ .Argument }}/country</div>
|
|
<div class="col-sm-8">{{ .Info.Geo.Country }}</div>
|
|
</li>
|
|
{{ end }}
|
|
{{ if .Info.Asn.Org }}
|
|
<li class="list-group-item">
|
|
<div class="col-sm-4">curl {{ .Short }}{{ .Argument }}/org</div>
|
|
<div class="col-sm-8">{{ .Info.Asn.Org }}</div>
|
|
</li>
|
|
{{ end }}
|
|
<li class="list-group-item">
|
|
<div class="col-sm-4">curl {{ .Short }}{{ .Argument }}/all</div>
|
|
<div class="col-sm-8">{{ .Info }}</div>
|
|
</li>
|
|
{{ if .Info.Hostname }}
|
|
<li class="list-group-item">
|
|
<div class="col-sm-4">curl {{ .Short }}{{ .Argument }}/hostname</div>
|
|
<div class="col-sm-8">{{ .Info.Hostname }}</div>
|
|
</li>
|
|
{{ end }}
|
|
{{ if .Info.Ssl.Subject }}
|
|
<li class="list-group-item">
|
|
<div class="col-sm-4">curl {{ .Short }}{{ .Argument }}/ssl</div>
|
|
<div class="col-sm-8">{{ .Info.Ssl }}</div>
|
|
</li>
|
|
{{ end }}
|
|
{{ if .Info.Query }}
|
|
<li class="list-group-item">
|
|
<div class="col-sm-4">curl {{ .Short }}{{ .Argument }}/{{ .Info.Ip }}</div>
|
|
<div class="col-sm-8">{{ .Info.Ip }}</div>
|
|
</li>
|
|
{{ end }}
|
|
</ul>
|
|
</div>
|
|
</details>
|
|
</main>
|
|
<footer class="container text-center">
|
|
{{ if .Info.Cached }}
|
|
<p id="countdown">Cached for {{ .Info.Ttl }}s</p>
|
|
{{ else }}
|
|
<p id="countdown">Not cached</p>
|
|
{{ end }}
|
|
<p><a target="_blank" href="https://git.rznet.fr/tchivert/iplookup-go">{{ .Title }}</a> - code by <a
|
|
target="_blank" href="https://tchv.fr/">Tom</a></p>
|
|
</footer>
|
|
|
|
<script>
|
|
document.addEventListener('DOMContentLoaded', () => {
|
|
const countdownElement = document.getElementById('countdown');
|
|
const ttlSeconds = parseInt('{{ .Info.Ttl }}');
|
|
let remainingTime = ttlSeconds;
|
|
|
|
function updateCountdown() {
|
|
remainingTime -= 1;
|
|
if (remainingTime <= 0) {
|
|
countdownElement.textContent = `Not cached`;
|
|
} else {
|
|
countdownElement.textContent = `Cached for ${remainingTime}s`;
|
|
}
|
|
}
|
|
|
|
if ('{{ .Info.Cached }}' == "true") {
|
|
setInterval(updateCountdown, 1000);
|
|
}
|
|
});
|
|
</script>
|
|
</body>
|