http3-ytproxy/main.go

191 lines
4.3 KiB
Go
Raw Normal View History

2020-10-24 12:47:41 -03:00
package main
import (
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 01:29:55 -03:00
"sync"
"syscall"
2021-03-12 03:59:53 -03:00
"time"
2020-10-24 12:47:41 -03:00
2023-11-07 11:05:53 -03:00
"github.com/quic-go/quic-go/http3"
2020-10-24 12:47:41 -03:00
)
2020-10-25 09:41:17 -03:00
// http/3 client
var h3client = &http.Client{
2020-10-24 12:47:41 -03:00
Transport: &http3.RoundTripper{},
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,
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 01:29:55 -03:00
// https://github.com/lucas-clemente/quic-go/issues/2836
var client = h2client
// 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",
"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",
"Etag",
2024-10-04 21:14:01 -03:00
"Alt-Svc",
"Server",
"Cache-Control",
2022-05-17 06:19:43 -04: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 01:29:55 -03:00
var reqs int64
var reqs_Forbidden int64
var mu sync.Mutex
2020-10-25 09:41:17 -03:00
2024-10-29 01:29:55 -03:00
type statusJson struct {
RequestCount int64 `json:"requestCount"`
RequestsForbidden int64 `json:"requestsForbidden"`
2020-10-25 09:41:17 -03:00
}
2024-10-29 01:29:55 -03:00
func root(w http.ResponseWriter, req *http.Request) {
io.WriteString(w, "HTTP youtube proxy for https://inv.nadeko.net\n")
2020-10-25 09:41:17 -03:00
}
2024-10-29 01:29:55 -03:00
func status(w http.ResponseWriter, req *http.Request) {
response := statusJson{
RequestCount: reqs,
RequestsForbidden: reqs_Forbidden,
2020-10-25 09:41:17 -03:00
}
2024-10-29 01:29:55 -03:00
w.Header().Set("Content-Type", "application/json")
2020-10-25 09:41:17 -03:00
2024-10-29 01:29:55 -03:00
if err := json.NewEncoder(w).Encode(response); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
2021-06-20 03:19:07 -04:00
}
2021-11-07 15:23:39 -03:00
}
2020-10-25 09:41:17 -03:00
func main() {
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-10-04 20:56:01 -03:00
var cert string
var key string
2023-11-07 11:33:20 -03:00
path_prefix = os.Getenv("PREFIX_PATH")
2024-10-28 01:58:29 -03:00
ipv6_only = os.Getenv("IPV6_ONLY") == "1"
2024-10-29 01:29:55 -03:00
// disable_webp = os.Getenv("DISABLE_WEBP") == "1"
2024-10-02 19:04:19 -03:00
2024-10-04 20:56:01 -03:00
flag.StringVar(&cert, "tls-cert", "", "TLS Certificate path")
flag.StringVar(&key, "tls-key", "", "TLS Certificate Key path")
var https = flag.Bool("https", false, "Use built-in https server")
2024-10-28 01:58:29 -03:00
var ipv6 = flag.Bool("ipv6_only", false, "Only use ipv6 for requests")
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-10-28 01:58:29 -03:00
ipv6_only = *ipv6
2024-10-29 01:29:55 -03:00
mux := http.NewServeMux()
mux.HandleFunc("/", root)
mux.HandleFunc("/status", status)
mux.HandleFunc("/videoplayback", videoplayback)
mux.HandleFunc("/vi/", vi)
mux.HandleFunc("/vi_webp/", vi)
mux.HandleFunc("/sb/", vi)
mux.HandleFunc("/ggpht/", ggpht)
mux.HandleFunc("/a/", ggpht)
mux.HandleFunc("/ytc/", ggpht)
2021-03-12 03:59:53 -03:00
srv := &http.Server{
ReadTimeout: 5 * time.Second,
WriteTimeout: 1 * time.Hour,
2024-10-04 20:56:01 -03:00
Addr: string(host) + ":" + string(port),
2024-10-29 01:29:55 -03:00
Handler: mux,
2021-03-12 03:59:53 -03:00
}
2024-10-02 19:04:19 -03:00
2024-10-04 20:56:01 -03:00
socket := string(sock)
syscall.Unlink(socket)
listener, err := net.Listen("unix", socket)
2024-10-29 01:29:55 -03:00
fmt.Println("Unix socket listening at:", string(sock))
2024-10-04 20:56:01 -03:00
2020-10-25 09:41:17 -03:00
if err != nil {
2023-11-07 12:18:20 -03:00
fmt.Println("Failed to bind to UDS, please check the socket name, falling back to TCP/IP")
2020-10-25 09:41:17 -03:00
fmt.Println(err.Error())
2023-11-07 12:18:20 -03:00
err := srv.ListenAndServe()
if err != nil {
fmt.Println("Cannot bind to port", string(port), "Error:", err)
fmt.Println("Please try changing the port number")
}
2020-10-25 09:41:17 -03:00
} else {
2021-03-04 05:57:42 -03:00
defer listener.Close()
2024-10-02 19:04:19 -03:00
// To allow everyone to access the socket
err = os.Chmod(socket, 0777)
if err != nil {
fmt.Println("Error setting permissions:", err)
return
} else {
fmt.Println("Setting socket permissions to 777")
}
go srv.Serve(listener)
2024-10-04 20:56:01 -03:00
if *https {
2024-10-29 01:29:55 -03:00
fmt.Println("Serving HTTPS at port", string(port))
2024-10-04 20:56:01 -03:00
if err := srv.ListenAndServeTLS(cert, key); err != nil {
log.Fatal(err)
}
} else {
2024-10-29 01:29:55 -03:00
fmt.Println("Serving HTTP at port", string(port))
2024-10-04 20:56:01 -03:00
srv.ListenAndServe()
}
2020-10-25 09:41:17 -03:00
}
2020-10-24 12:47:41 -03:00
}