2020-10-24 12:47:41 -03:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
2024-11-04 10:48:00 -03:00
|
|
|
"crypto/tls"
|
2024-10-29 01:29:55 -03:00
|
|
|
"encoding/json"
|
2024-09-17 03:23:49 -03:00
|
|
|
"flag"
|
2020-10-24 12:47:41 -03:00
|
|
|
"fmt"
|
2020-10-25 09:41:17 -03:00
|
|
|
"io"
|
2020-10-24 12:47:41 -03:00
|
|
|
"log"
|
2020-10-25 09:41:17 -03:00
|
|
|
"net"
|
2020-10-24 12:47:41 -03:00
|
|
|
"net/http"
|
2020-10-25 11:01:23 -03:00
|
|
|
"os"
|
2021-11-07 15:23:39 -03:00
|
|
|
"regexp"
|
2024-10-29 19:34:26 -03:00
|
|
|
"runtime"
|
2024-10-29 15:01:35 -03:00
|
|
|
"sync/atomic"
|
2020-10-25 09:52:02 -03:00
|
|
|
"syscall"
|
2021-03-12 03:59:53 -03:00
|
|
|
"time"
|
2020-10-24 12:47:41 -03:00
|
|
|
|
2024-10-29 21:27:09 -03:00
|
|
|
"github.com/conduitio/bwlimit"
|
2024-11-06 00:36:54 -03:00
|
|
|
"github.com/prometheus/client_golang/prometheus"
|
|
|
|
"github.com/prometheus/client_golang/prometheus/promhttp"
|
2024-11-04 10:48:00 -03:00
|
|
|
"github.com/quic-go/quic-go"
|
2023-11-07 11:05:53 -03:00
|
|
|
"github.com/quic-go/quic-go/http3"
|
2020-10-24 12:47:41 -03:00
|
|
|
)
|
|
|
|
|
2024-10-29 21:27:09 -03:00
|
|
|
var (
|
|
|
|
wl = flag.Int("w", 8000, "Write limit in Kbps")
|
|
|
|
rl = flag.Int("r", 8000, "Read limit in Kbps")
|
|
|
|
)
|
|
|
|
|
2020-10-25 09:41:17 -03:00
|
|
|
var h3client = &http.Client{
|
2024-10-29 15:01:35 -03:00
|
|
|
Transport: &http3.Transport{},
|
2024-09-17 03:23:49 -03:00
|
|
|
Timeout: 10 * time.Second,
|
2020-10-24 12:47:41 -03:00
|
|
|
}
|
|
|
|
|
2022-06-27 08:25:31 -04:00
|
|
|
var dialer = &net.Dialer{
|
|
|
|
Timeout: 30 * time.Second,
|
|
|
|
KeepAlive: 30 * time.Second,
|
|
|
|
}
|
|
|
|
|
2020-10-25 09:41:17 -03:00
|
|
|
// http/2 client
|
2021-03-12 03:59:53 -03:00
|
|
|
var h2client = &http.Client{
|
|
|
|
Transport: &http.Transport{
|
2022-06-27 08:25:31 -04:00
|
|
|
Dial: func(network, addr string) (net.Conn, error) {
|
2024-10-28 01:58:29 -03:00
|
|
|
var net string
|
|
|
|
if ipv6_only {
|
|
|
|
net = "tcp6"
|
|
|
|
} else {
|
|
|
|
net = "tcp4"
|
2022-06-27 08:25:31 -04:00
|
|
|
}
|
2024-10-28 01:58:29 -03:00
|
|
|
return dialer.Dial(net, addr)
|
2022-06-27 08:25:31 -04:00
|
|
|
},
|
2021-03-12 03:59:53 -03:00
|
|
|
TLSHandshakeTimeout: 10 * time.Second,
|
2021-06-20 06:37:39 -04:00
|
|
|
ResponseHeaderTimeout: 20 * time.Second,
|
2021-03-12 03:59:53 -03:00
|
|
|
ExpectContinueTimeout: 1 * time.Second,
|
2021-04-09 04:50:14 -04:00
|
|
|
IdleConnTimeout: 30 * time.Second,
|
2021-04-09 10:37:35 -04:00
|
|
|
ReadBufferSize: 16 * 1024,
|
|
|
|
ForceAttemptHTTP2: true,
|
|
|
|
MaxConnsPerHost: 0,
|
|
|
|
MaxIdleConnsPerHost: 10,
|
|
|
|
MaxIdleConns: 0,
|
2021-03-12 03:59:53 -03:00
|
|
|
},
|
|
|
|
}
|
2020-10-25 09:41:17 -03:00
|
|
|
|
2024-10-29 19:34:26 -03:00
|
|
|
var client *http.Client
|
2024-10-29 01:29:55 -03:00
|
|
|
|
|
|
|
// Same user agent as Invidious
|
|
|
|
var ua = "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36"
|
2020-10-25 09:41:17 -03:00
|
|
|
|
2021-07-21 14:23:27 -04:00
|
|
|
var allowed_hosts = []string{
|
|
|
|
"youtube.com",
|
|
|
|
"googlevideo.com",
|
|
|
|
"ytimg.com",
|
|
|
|
"ggpht.com",
|
2021-08-04 11:00:40 -04:00
|
|
|
"googleusercontent.com",
|
2021-07-21 14:23:27 -04:00
|
|
|
}
|
|
|
|
|
2022-05-17 06:19:43 -04:00
|
|
|
var strip_headers = []string{
|
|
|
|
"Accept-Encoding",
|
|
|
|
"Authorization",
|
|
|
|
"Origin",
|
2022-05-18 08:50:31 -04:00
|
|
|
"Referer",
|
2022-05-17 06:19:43 -04:00
|
|
|
"Cookie",
|
|
|
|
"Set-Cookie",
|
2022-06-02 22:33:51 -04:00
|
|
|
"Etag",
|
2024-10-04 21:14:01 -03:00
|
|
|
"Alt-Svc",
|
|
|
|
"Server",
|
|
|
|
"Cache-Control",
|
2022-05-17 06:19:43 -04:00
|
|
|
}
|
|
|
|
|
2021-11-17 10:14:51 -03:00
|
|
|
var path_prefix = ""
|
|
|
|
|
2021-11-07 15:23:39 -03:00
|
|
|
var manifest_re = regexp.MustCompile(`(?m)URI="([^"]+)"`)
|
|
|
|
|
2024-10-28 01:58:29 -03:00
|
|
|
var ipv6_only = false
|
2020-10-24 12:47:41 -03:00
|
|
|
|
2024-10-29 19:34:26 -03:00
|
|
|
var version string
|
|
|
|
|
2024-11-04 10:48:00 -03:00
|
|
|
var h3s bool
|
|
|
|
|
2024-11-04 12:05:59 -03:00
|
|
|
var programInit = time.Now()
|
|
|
|
|
2024-11-04 11:56:46 -03:00
|
|
|
type ConnectionWatcher struct {
|
|
|
|
totalEstablished int64
|
|
|
|
established int64
|
|
|
|
active int64
|
|
|
|
idle int64
|
|
|
|
}
|
|
|
|
|
|
|
|
// https://stackoverflow.com/questions/51317122/how-to-get-number-of-idle-and-active-connections-in-go
|
|
|
|
|
|
|
|
// OnStateChange records open connections in response to connection
|
|
|
|
// state changes. Set net/http Server.ConnState to this method
|
|
|
|
// as value.
|
|
|
|
func (cw *ConnectionWatcher) OnStateChange(conn net.Conn, state http.ConnState) {
|
|
|
|
switch state {
|
|
|
|
case http.StateNew:
|
2024-11-06 00:36:54 -03:00
|
|
|
atomic.AddInt64(&stats_.EstablishedConnections, 1)
|
|
|
|
metrics.EstablishedConnections.Inc()
|
|
|
|
atomic.AddInt64(&stats_.TotalConnEstablished, 1)
|
|
|
|
metrics.TotalConnEstablished.Inc()
|
2024-11-04 11:56:46 -03:00
|
|
|
// case http.StateActive:
|
|
|
|
// atomic.AddInt64(&cw.active, 1)
|
|
|
|
case http.StateClosed, http.StateHijacked:
|
2024-11-06 00:36:54 -03:00
|
|
|
atomic.AddInt64(&stats_.EstablishedConnections, -1)
|
|
|
|
metrics.EstablishedConnections.Dec()
|
2024-11-04 11:56:46 -03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// // Count returns the number of connections at the time
|
|
|
|
// // the call.
|
|
|
|
// func (cw *ConnectionWatcher) Count() int {
|
|
|
|
// return int(atomic.LoadInt64(&cw.n))
|
|
|
|
// }
|
|
|
|
|
|
|
|
// // Add adds c to the number of active connections.
|
|
|
|
// func (cw *ConnectionWatcher) Add(c int64) {
|
|
|
|
// atomic.AddInt64(&cw.n, c)
|
|
|
|
// }
|
|
|
|
|
|
|
|
var cw ConnectionWatcher
|
|
|
|
|
2024-10-29 01:29:55 -03:00
|
|
|
type statusJson struct {
|
2024-11-04 12:05:59 -03:00
|
|
|
Version string `json:"version"`
|
|
|
|
Uptime time.Duration `json:"uptime"`
|
|
|
|
RequestCount int64 `json:"requestCount"`
|
|
|
|
RequestPerSecond int64 `json:"requestPerSecond"`
|
|
|
|
RequestPerMinute int64 `json:"requestPerMinute"`
|
2024-11-06 00:36:54 -03:00
|
|
|
TotalConnEstablished int64 `json:"totalEstablished"`
|
2024-11-04 12:05:59 -03:00
|
|
|
EstablishedConnections int64 `json:"establishedConnections"`
|
|
|
|
ActiveConnections int64 `json:"activeConnections"`
|
|
|
|
IdleConnections int64 `json:"idleConnections"`
|
2024-11-04 11:56:46 -03:00
|
|
|
RequestsForbidden struct {
|
2024-10-29 15:01:35 -03:00
|
|
|
Videoplayback int64 `json:"videoplayback"`
|
|
|
|
Vi int64 `json:"vi"`
|
|
|
|
Ggpht int64 `json:"ggpht"`
|
|
|
|
} `json:"requestsForbidden"`
|
2020-10-25 09:41:17 -03:00
|
|
|
}
|
|
|
|
|
2024-10-29 15:01:35 -03:00
|
|
|
var stats_ = statusJson{
|
2024-11-04 11:56:46 -03:00
|
|
|
Version: version + "-" + runtime.GOARCH,
|
2024-11-04 12:05:59 -03:00
|
|
|
Uptime: 0,
|
2024-11-04 11:56:46 -03:00
|
|
|
RequestCount: 0,
|
|
|
|
RequestPerSecond: 0,
|
|
|
|
RequestPerMinute: 0,
|
2024-11-06 00:36:54 -03:00
|
|
|
TotalConnEstablished: 0,
|
2024-11-04 11:56:46 -03:00
|
|
|
EstablishedConnections: 0,
|
|
|
|
ActiveConnections: 0,
|
|
|
|
IdleConnections: 0,
|
2024-10-29 15:01:35 -03:00
|
|
|
RequestsForbidden: struct {
|
|
|
|
Videoplayback int64 `json:"videoplayback"`
|
|
|
|
Vi int64 `json:"vi"`
|
|
|
|
Ggpht int64 `json:"ggpht"`
|
|
|
|
}{
|
|
|
|
Videoplayback: 0,
|
|
|
|
Vi: 0,
|
|
|
|
Ggpht: 0,
|
|
|
|
},
|
2020-10-25 09:41:17 -03:00
|
|
|
}
|
|
|
|
|
2024-11-06 00:36:54 -03:00
|
|
|
type Metrics struct {
|
|
|
|
Uptime prometheus.Gauge
|
|
|
|
RequestCount prometheus.Counter
|
|
|
|
RequestPerSecond prometheus.Gauge
|
|
|
|
RequestPerMinute prometheus.Gauge
|
|
|
|
TotalConnEstablished prometheus.Counter
|
|
|
|
EstablishedConnections prometheus.Gauge
|
|
|
|
ActiveConnections prometheus.Gauge
|
|
|
|
IdleConnections prometheus.Gauge
|
|
|
|
RequestForbidden struct {
|
|
|
|
Videoplayback prometheus.Counter
|
|
|
|
Vi prometheus.Counter
|
|
|
|
Ggpht prometheus.Counter
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
var metrics = Metrics{
|
|
|
|
Uptime: prometheus.NewGauge(prometheus.GaugeOpts{
|
2024-11-06 00:53:01 -03:00
|
|
|
Name: "http3_ytproxy_uptime",
|
2024-11-06 00:36:54 -03:00
|
|
|
}),
|
|
|
|
RequestCount: prometheus.NewGauge(prometheus.GaugeOpts{
|
2024-11-06 00:53:01 -03:00
|
|
|
Name: "http3_ytproxy_request_count",
|
2024-11-06 00:36:54 -03:00
|
|
|
}),
|
|
|
|
RequestPerSecond: prometheus.NewGauge(prometheus.GaugeOpts{
|
2024-11-06 00:53:01 -03:00
|
|
|
Name: "http3_ytproxy_request_per_second",
|
2024-11-06 00:36:54 -03:00
|
|
|
}),
|
|
|
|
RequestPerMinute: prometheus.NewGauge(prometheus.GaugeOpts{
|
2024-11-06 00:53:01 -03:00
|
|
|
Name: "http3_ytproxy_request_per_minute",
|
2024-11-06 00:36:54 -03:00
|
|
|
}),
|
|
|
|
TotalConnEstablished: prometheus.NewGauge(prometheus.GaugeOpts{
|
2024-11-06 00:53:01 -03:00
|
|
|
Name: "http3_ytproxy_total_conn_established",
|
2024-11-06 00:36:54 -03:00
|
|
|
}),
|
|
|
|
EstablishedConnections: prometheus.NewGauge(prometheus.GaugeOpts{
|
2024-11-06 00:53:01 -03:00
|
|
|
Name: "http3_ytproxy_established_conns",
|
2024-11-06 00:36:54 -03:00
|
|
|
}),
|
|
|
|
ActiveConnections: prometheus.NewGauge(prometheus.GaugeOpts{
|
2024-11-06 00:53:01 -03:00
|
|
|
Name: "http3_ytproxy_active_conns",
|
2024-11-06 00:36:54 -03:00
|
|
|
}),
|
|
|
|
IdleConnections: prometheus.NewGauge(prometheus.GaugeOpts{
|
2024-11-06 00:53:01 -03:00
|
|
|
Name: "http3_ytproxy_idle_conns",
|
2024-11-06 00:36:54 -03:00
|
|
|
}),
|
|
|
|
|
|
|
|
RequestForbidden: struct {
|
|
|
|
Videoplayback prometheus.Counter
|
|
|
|
Vi prometheus.Counter
|
|
|
|
Ggpht prometheus.Counter
|
|
|
|
}{
|
|
|
|
Videoplayback: prometheus.NewCounter(prometheus.CounterOpts{
|
2024-11-06 00:53:01 -03:00
|
|
|
Name: "http3_ytproxy_request_forbidden_videoplayback",
|
2024-11-06 00:36:54 -03:00
|
|
|
}),
|
|
|
|
Vi: prometheus.NewCounter(prometheus.CounterOpts{
|
2024-11-06 00:53:01 -03:00
|
|
|
Name: "http3_ytproxy_request_forbidden_vi",
|
2024-11-06 00:36:54 -03:00
|
|
|
}),
|
|
|
|
Ggpht: prometheus.NewCounter(prometheus.CounterOpts{
|
2024-11-06 00:53:01 -03:00
|
|
|
Name: "http3_ytproxy_request_forbidden_ggpht",
|
2024-11-06 00:36:54 -03:00
|
|
|
}),
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
2024-10-29 15:01:35 -03:00
|
|
|
func root(w http.ResponseWriter, req *http.Request) {
|
|
|
|
const msg = `
|
|
|
|
HTTP youtube proxy for https://inv.nadeko.net
|
|
|
|
https://git.nadeko.net/Fijxu/http3-ytproxy
|
|
|
|
|
|
|
|
Routes:
|
|
|
|
/stats
|
|
|
|
/health`
|
|
|
|
io.WriteString(w, msg)
|
|
|
|
}
|
2020-10-25 09:41:17 -03:00
|
|
|
|
2024-11-06 00:36:54 -03:00
|
|
|
// CustomHandler wraps the default promhttp.Handler with custom logic
|
|
|
|
func metricsHandler() http.Handler {
|
|
|
|
return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
|
|
|
|
metrics.Uptime.Set(float64(time.Duration(time.Since(programInit).Seconds())))
|
|
|
|
promhttp.Handler().ServeHTTP(w, req)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2024-10-29 15:01:35 -03:00
|
|
|
func stats(w http.ResponseWriter, req *http.Request) {
|
2024-10-29 01:29:55 -03:00
|
|
|
w.Header().Set("Content-Type", "application/json")
|
2024-11-04 12:05:59 -03:00
|
|
|
stats_.Uptime = time.Duration(time.Since(programInit).Seconds())
|
2024-11-06 00:36:54 -03:00
|
|
|
// stats_.TotalEstablished = int64(cw.totalEstablished)
|
|
|
|
// stats_.EstablishedConnections = int64(cw.established)
|
2024-11-04 11:56:46 -03:00
|
|
|
// stats_.ActiveConnections = int64(cw.active)
|
|
|
|
// stats_.IdleConnections = int64(cw.idle)
|
2020-10-25 09:41:17 -03:00
|
|
|
|
2024-10-29 15:01:35 -03:00
|
|
|
if err := json.NewEncoder(w).Encode(stats_); err != nil {
|
2024-10-29 01:29:55 -03:00
|
|
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
2021-06-20 03:19:07 -04:00
|
|
|
}
|
2021-11-07 15:23:39 -03:00
|
|
|
}
|
|
|
|
|
2024-10-29 15:01:35 -03:00
|
|
|
func health(w http.ResponseWriter, req *http.Request) {
|
|
|
|
w.WriteHeader(200)
|
|
|
|
io.WriteString(w, "OK")
|
|
|
|
}
|
|
|
|
|
|
|
|
func requestPerSecond() {
|
|
|
|
var last int64
|
|
|
|
for {
|
|
|
|
time.Sleep(1 * time.Second)
|
|
|
|
current := stats_.RequestCount
|
|
|
|
stats_.RequestPerSecond = current - last
|
2024-11-06 00:36:54 -03:00
|
|
|
metrics.RequestPerSecond.Set(float64(stats_.RequestPerSecond))
|
2024-10-29 15:01:35 -03:00
|
|
|
last = current
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func requestPerMinute() {
|
|
|
|
var last int64
|
|
|
|
for {
|
|
|
|
time.Sleep(60 * time.Second)
|
|
|
|
current := stats_.RequestCount
|
2024-10-29 19:38:10 -03:00
|
|
|
stats_.RequestPerMinute = current - last
|
2024-11-06 00:36:54 -03:00
|
|
|
metrics.RequestPerMinute.Set(float64(stats_.RequestPerMinute))
|
2024-10-29 15:01:35 -03:00
|
|
|
last = current
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func beforeAll(next http.HandlerFunc) http.HandlerFunc {
|
|
|
|
return func(w http.ResponseWriter, req *http.Request) {
|
2024-10-31 16:29:30 -03:00
|
|
|
defer panicHandler(w)
|
|
|
|
|
2024-11-04 10:48:00 -03:00
|
|
|
if h3s {
|
|
|
|
w.Header().Set("Alt-Svc", "h3=\":8443\"; ma=86400")
|
|
|
|
}
|
|
|
|
|
|
|
|
if req.Method == "OPTIONS" {
|
|
|
|
w.WriteHeader(http.StatusOK)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2024-10-29 15:01:35 -03:00
|
|
|
if req.Method != "GET" && req.Method != "HEAD" {
|
|
|
|
io.WriteString(w, "Only GET and HEAD requests are allowed.")
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2024-10-30 03:08:24 -03:00
|
|
|
// To look like more like a browser
|
|
|
|
req.Header.Add("Origin", "https://www.youtube.com")
|
|
|
|
req.Header.Add("Referer", "https://www.youtube.com/")
|
|
|
|
|
2024-10-29 15:01:35 -03:00
|
|
|
w.Header().Set("Access-Control-Allow-Origin", "*")
|
|
|
|
w.Header().Set("Access-Control-Allow-Headers", "*")
|
|
|
|
w.Header().Set("Access-Control-Max-Age", "1728000")
|
|
|
|
|
2024-11-04 10:48:00 -03:00
|
|
|
atomic.AddInt64(&stats_.RequestCount, 1)
|
2024-11-06 00:36:54 -03:00
|
|
|
metrics.RequestCount.Inc()
|
2024-10-29 15:01:35 -03:00
|
|
|
next(w, req)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-10-25 09:41:17 -03:00
|
|
|
func main() {
|
2024-04-28 14:24:50 -04:00
|
|
|
var sock string
|
2024-10-04 20:56:01 -03:00
|
|
|
var host string
|
2023-11-07 12:18:20 -03:00
|
|
|
var port string
|
2024-11-04 10:48:00 -03:00
|
|
|
|
2024-10-29 15:01:35 -03:00
|
|
|
var tls_cert string
|
|
|
|
var tls_key string
|
2024-11-04 10:48:00 -03:00
|
|
|
var ipv6 bool
|
|
|
|
var https bool
|
|
|
|
var h3c bool
|
|
|
|
|
|
|
|
ua = os.Getenv("USER_AGENT")
|
|
|
|
https = os.Getenv("HTTPS") == "1"
|
|
|
|
h3c = os.Getenv("H3C") == "1"
|
|
|
|
h3s = os.Getenv("H3S") == "1"
|
|
|
|
ipv6 = os.Getenv("IPV6_ONLY") == "1"
|
|
|
|
|
|
|
|
flag.BoolVar(&https, "https", false, "Use built-in https server (recommended)")
|
|
|
|
flag.BoolVar(&h3s, "h3c", false, "Use HTTP/3 for client requests (high CPU usage)")
|
|
|
|
flag.BoolVar(&h3s, "h3s", true, "Use HTTP/3 for server requests")
|
|
|
|
flag.BoolVar(&ipv6_only, "ipv6_only", false, "Only use ipv6 for requests")
|
2024-10-29 15:01:35 -03:00
|
|
|
flag.StringVar(&tls_cert, "tls-cert", "", "TLS Certificate path")
|
|
|
|
flag.StringVar(&tls_key, "tls-key", "", "TLS Certificate Key path")
|
2024-10-04 20:56:01 -03:00
|
|
|
flag.StringVar(&sock, "s", "/tmp/http-ytproxy.sock", "Specify a socket name")
|
2023-11-07 12:18:20 -03:00
|
|
|
flag.StringVar(&port, "p", "8080", "Specify a port number")
|
2024-10-08 23:14:29 -03:00
|
|
|
flag.StringVar(&host, "l", "0.0.0.0", "Specify a listen address")
|
2024-09-17 03:23:49 -03:00
|
|
|
flag.Parse()
|
|
|
|
|
2024-11-04 10:48:00 -03:00
|
|
|
if h3c {
|
2024-10-29 19:34:26 -03:00
|
|
|
client = h3client
|
|
|
|
} else {
|
|
|
|
client = h2client
|
|
|
|
}
|
|
|
|
|
2024-11-04 10:48:00 -03:00
|
|
|
if https {
|
2024-10-29 15:01:35 -03:00
|
|
|
if len(tls_cert) <= 0 {
|
2024-11-04 10:48:00 -03:00
|
|
|
fmt.Println("tls-cert argument is missing, you need a TLS certificate for HTTPS")
|
|
|
|
os.Exit(1)
|
2024-10-29 15:01:35 -03:00
|
|
|
}
|
|
|
|
|
|
|
|
if len(tls_key) <= 0 {
|
2024-11-04 10:48:00 -03:00
|
|
|
fmt.Println("tls-key argument is missing, you need a TLS key for HTTPS")
|
|
|
|
os.Exit(1)
|
2024-10-29 15:01:35 -03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-11-04 10:48:00 -03:00
|
|
|
ipv6_only = ipv6
|
2024-10-28 01:58:29 -03:00
|
|
|
|
2024-10-29 01:29:55 -03:00
|
|
|
mux := http.NewServeMux()
|
|
|
|
|
|
|
|
mux.HandleFunc("/", root)
|
2024-10-29 15:01:35 -03:00
|
|
|
mux.HandleFunc("/health", health)
|
|
|
|
mux.HandleFunc("/stats", stats)
|
|
|
|
|
2024-11-06 00:36:54 -03:00
|
|
|
prometheus.MustRegister(metrics.Uptime)
|
|
|
|
prometheus.MustRegister(metrics.ActiveConnections)
|
|
|
|
prometheus.MustRegister(metrics.IdleConnections)
|
|
|
|
prometheus.MustRegister(metrics.EstablishedConnections)
|
|
|
|
prometheus.MustRegister(metrics.TotalConnEstablished)
|
|
|
|
prometheus.MustRegister(metrics.RequestCount)
|
|
|
|
prometheus.MustRegister(metrics.RequestPerSecond)
|
|
|
|
prometheus.MustRegister(metrics.RequestPerMinute)
|
|
|
|
prometheus.MustRegister(metrics.RequestForbidden.Videoplayback)
|
|
|
|
prometheus.MustRegister(metrics.RequestForbidden.Vi)
|
|
|
|
prometheus.MustRegister(metrics.RequestForbidden.Ggpht)
|
|
|
|
|
|
|
|
mux.Handle("/metrics", metricsHandler())
|
|
|
|
|
2024-10-29 15:01:35 -03:00
|
|
|
mux.HandleFunc("/videoplayback", beforeAll(videoplayback))
|
|
|
|
mux.HandleFunc("/vi/", beforeAll(vi))
|
|
|
|
mux.HandleFunc("/vi_webp/", beforeAll(vi))
|
|
|
|
mux.HandleFunc("/sb/", beforeAll(vi))
|
|
|
|
mux.HandleFunc("/ggpht/", beforeAll(ggpht))
|
|
|
|
mux.HandleFunc("/a/", beforeAll(ggpht))
|
|
|
|
mux.HandleFunc("/ytc/", beforeAll(ggpht))
|
|
|
|
|
|
|
|
go requestPerSecond()
|
|
|
|
go requestPerMinute()
|
2024-10-29 01:29:55 -03:00
|
|
|
|
2024-10-29 21:27:09 -03:00
|
|
|
ln, err := net.Listen("tcp", host+":"+port)
|
|
|
|
if err != nil {
|
|
|
|
log.Fatalf("Failed to listen: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
// 1Kbit = 125Bytes
|
|
|
|
var (
|
|
|
|
writeLimit = bwlimit.Byte(*wl) * bwlimit.Byte(125)
|
|
|
|
readLimit = bwlimit.Byte(*rl) * bwlimit.Byte(125)
|
|
|
|
)
|
|
|
|
|
|
|
|
ln = bwlimit.NewListener(ln, writeLimit, readLimit)
|
2024-11-04 10:48:00 -03:00
|
|
|
// srvDialer := bwlimit.NewDialer(&net.Dialer{}, writeLimit, readLimit)
|
2024-10-29 21:27:09 -03:00
|
|
|
|
2021-03-12 03:59:53 -03:00
|
|
|
srv := &http.Server{
|
2024-11-04 10:48:00 -03:00
|
|
|
Handler: mux,
|
2021-03-12 03:59:53 -03:00
|
|
|
ReadTimeout: 5 * time.Second,
|
2022-04-18 04:33:19 -04:00
|
|
|
WriteTimeout: 1 * time.Hour,
|
2024-11-04 11:56:46 -03:00
|
|
|
ConnState: cw.OnStateChange,
|
2024-11-04 10:48:00 -03:00
|
|
|
}
|
|
|
|
|
|
|
|
srvh3 := &http3.Server{
|
|
|
|
Handler: mux,
|
|
|
|
EnableDatagrams: false, // https://quic.video/blog/never-use-datagrams/ (Read it)
|
|
|
|
IdleTimeout: 120 * time.Second,
|
|
|
|
TLSConfig: http3.ConfigureTLSConfig(&tls.Config{}),
|
|
|
|
QUICConfig: &quic.Config{
|
|
|
|
// KeepAlivePeriod: 10 * time.Second,
|
|
|
|
MaxIncomingStreams: 256, // I'm not sure if this is correct.
|
|
|
|
MaxIncomingUniStreams: 256, // Same as above
|
|
|
|
},
|
|
|
|
Addr: host + ":" + port,
|
2021-03-12 03:59:53 -03:00
|
|
|
}
|
2024-10-02 19:04:19 -03:00
|
|
|
|
2024-10-29 21:27:09 -03:00
|
|
|
syscall.Unlink(sock)
|
|
|
|
socket_listener, err := net.Listen("unix", sock)
|
2024-10-04 20:56:01 -03:00
|
|
|
|
2020-10-25 09:41:17 -03:00
|
|
|
if err != nil {
|
2024-10-29 21:27:09 -03:00
|
|
|
fmt.Println("Failed to bind to UDS, please check the socket name")
|
2020-10-25 09:41:17 -03:00
|
|
|
fmt.Println(err.Error())
|
|
|
|
} else {
|
2024-10-29 21:27:09 -03:00
|
|
|
defer socket_listener.Close()
|
2024-10-02 19:04:19 -03:00
|
|
|
// To allow everyone to access the socket
|
2024-10-29 21:27:09 -03:00
|
|
|
err = os.Chmod(sock, 0777)
|
2024-10-02 19:04:19 -03:00
|
|
|
if err != nil {
|
|
|
|
fmt.Println("Error setting permissions:", err)
|
|
|
|
return
|
|
|
|
} else {
|
|
|
|
fmt.Println("Setting socket permissions to 777")
|
|
|
|
}
|
2024-10-29 21:27:09 -03:00
|
|
|
|
|
|
|
go srv.Serve(socket_listener)
|
|
|
|
fmt.Println("Unix socket listening at:", string(sock))
|
|
|
|
|
2024-11-04 10:48:00 -03:00
|
|
|
if https {
|
2024-10-29 01:29:55 -03:00
|
|
|
fmt.Println("Serving HTTPS at port", string(port))
|
2024-11-04 10:48:00 -03:00
|
|
|
go func() {
|
|
|
|
if err := srv.ServeTLS(ln, tls_cert, tls_key); err != nil {
|
|
|
|
log.Fatal(err)
|
|
|
|
}
|
|
|
|
}()
|
|
|
|
if h3s {
|
|
|
|
fmt.Println("Serving HTTPS via QUIC at port", string(port))
|
|
|
|
go func() {
|
|
|
|
if err := srvh3.ListenAndServeTLS(tls_cert, tls_key); err != nil {
|
|
|
|
log.Fatal(err)
|
|
|
|
}
|
|
|
|
}()
|
2024-10-04 20:56:01 -03:00
|
|
|
}
|
2024-11-04 10:48:00 -03:00
|
|
|
select {}
|
2024-10-04 20:56:01 -03:00
|
|
|
} else {
|
2024-10-29 01:29:55 -03:00
|
|
|
fmt.Println("Serving HTTP at port", string(port))
|
2024-10-29 21:27:09 -03:00
|
|
|
if err := srv.Serve(ln); err != nil {
|
|
|
|
log.Fatal(err)
|
|
|
|
}
|
2024-10-04 20:56:01 -03:00
|
|
|
}
|
2020-10-25 09:41:17 -03:00
|
|
|
}
|
2020-10-24 12:47:41 -03:00
|
|
|
}
|