feat: add support for encrypted query parameters
All checks were successful
CI / build (push) Successful in 1m18s
All checks were successful
CI / build (push) Successful in 1m18s
This commit is contained in:
parent
81aa259a31
commit
6bd0f28d77
4 changed files with 65 additions and 21 deletions
|
@ -137,12 +137,6 @@ func beforeProxy(next http.HandlerFunc) http.HandlerFunc {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func getenv(key string) string {
|
|
||||||
// `YTPROXY_` as a prefix
|
|
||||||
v, _ := syscall.Getenv("YTPROXY_" + key)
|
|
||||||
return v
|
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
defaultHost := "0.0.0.0"
|
defaultHost := "0.0.0.0"
|
||||||
defaultPort := "8080"
|
defaultPort := "8080"
|
||||||
|
@ -157,58 +151,58 @@ func main() {
|
||||||
var ipv6 bool = false
|
var ipv6 bool = false
|
||||||
var bc bool = true
|
var bc bool = true
|
||||||
|
|
||||||
if strings.ToLower(getenv("HTTP")) == "true" {
|
if strings.ToLower(utils.Getenv("HTTP")) == "true" {
|
||||||
http_server = true
|
http_server = true
|
||||||
}
|
}
|
||||||
if strings.ToLower(getenv("HTTPS")) == "true" {
|
if strings.ToLower(utils.Getenv("HTTPS")) == "true" {
|
||||||
https = true
|
https = true
|
||||||
}
|
}
|
||||||
if strings.ToLower(getenv("H2C")) == "true" {
|
if strings.ToLower(utils.Getenv("H2C")) == "true" {
|
||||||
h2c = true
|
h2c = true
|
||||||
}
|
}
|
||||||
if strings.ToLower(getenv("H3C")) == "true" {
|
if strings.ToLower(utils.Getenv("H3C")) == "true" {
|
||||||
h3c = true
|
h3c = true
|
||||||
}
|
}
|
||||||
if strings.ToLower(getenv("H3S")) == "true" {
|
if strings.ToLower(utils.Getenv("H3S")) == "true" {
|
||||||
h3s = true
|
h3s = true
|
||||||
}
|
}
|
||||||
if strings.ToLower(getenv("IPV6_ONLY")) == "true" {
|
if strings.ToLower(utils.Getenv("IPV6_ONLY")) == "true" {
|
||||||
ipv6 = true
|
ipv6 = true
|
||||||
}
|
}
|
||||||
if strings.ToLower(getenv("BLOCK_CHECKER")) == "false" {
|
if strings.ToLower(utils.Getenv("BLOCK_CHECKER")) == "false" {
|
||||||
bc = false
|
bc = false
|
||||||
}
|
}
|
||||||
|
|
||||||
tls_cert := getenv("TLS_CERT")
|
tls_cert := utils.Getenv("TLS_CERT")
|
||||||
if tls_cert == "" {
|
if tls_cert == "" {
|
||||||
tls_cert = defaultTLSCert
|
tls_cert = defaultTLSCert
|
||||||
}
|
}
|
||||||
tls_key := getenv("TLS_KEY")
|
tls_key := utils.Getenv("TLS_KEY")
|
||||||
if tls_key == "" {
|
if tls_key == "" {
|
||||||
tls_key = defaultTLSKey
|
tls_key = defaultTLSKey
|
||||||
}
|
}
|
||||||
sock := getenv("SOCK_PATH")
|
sock := utils.Getenv("SOCK_PATH")
|
||||||
if sock == "" {
|
if sock == "" {
|
||||||
sock = defaultSock
|
sock = defaultSock
|
||||||
}
|
}
|
||||||
port := getenv("PORT")
|
port := utils.Getenv("PORT")
|
||||||
if port == "" {
|
if port == "" {
|
||||||
port = defaultPort
|
port = defaultPort
|
||||||
}
|
}
|
||||||
host := getenv("HOST")
|
host := utils.Getenv("HOST")
|
||||||
if host == "" {
|
if host == "" {
|
||||||
host = defaultHost
|
host = defaultHost
|
||||||
}
|
}
|
||||||
// gh is where the gluetun api is located
|
// gh is where the gluetun api is located
|
||||||
gh := getenv("GLUETUN_HOSTNAME")
|
gh := utils.Getenv("GLUETUN_HOSTNAME")
|
||||||
if gh == "" {
|
if gh == "" {
|
||||||
gh = "127.0.0.1:8000"
|
gh = "127.0.0.1:8000"
|
||||||
}
|
}
|
||||||
bc_cooldown := getenv("BLOCK_CHECKER_COOLDOWN")
|
bc_cooldown := utils.Getenv("BLOCK_CHECKER_COOLDOWN")
|
||||||
if bc_cooldown == "" {
|
if bc_cooldown == "" {
|
||||||
bc_cooldown = "60"
|
bc_cooldown = "60"
|
||||||
}
|
}
|
||||||
httpc.Proxy = getenv("PROXY")
|
httpc.Proxy = utils.Getenv("PROXY")
|
||||||
|
|
||||||
flag.BoolVar(&https, "https", https, "Use built-in https server (recommended)")
|
flag.BoolVar(&https, "https", https, "Use built-in https server (recommended)")
|
||||||
flag.BoolVar(&h3c, "h3c", h3c, "Use HTTP/3 for client requests (high CPU usage)")
|
flag.BoolVar(&h3c, "h3c", h3c, "Use HTTP/3 for client requests (high CPU usage)")
|
||||||
|
|
|
@ -3,6 +3,8 @@ package paths
|
||||||
import (
|
import (
|
||||||
"net/http"
|
"net/http"
|
||||||
"regexp"
|
"regexp"
|
||||||
|
|
||||||
|
"git.nadeko.net/Fijxu/http3-ytproxy/internal/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -31,3 +33,5 @@ var videoplayback_headers = &http.Header{
|
||||||
|
|
||||||
// https://github.com/FreeTubeApp/FreeTube/blob/5a4cd981cdf2c2a20ab68b001746658fd0c6484e/src/renderer/components/ft-shaka-video-player/ft-shaka-video-player.js#L1097
|
// https://github.com/FreeTubeApp/FreeTube/blob/5a4cd981cdf2c2a20ab68b001746658fd0c6484e/src/renderer/components/ft-shaka-video-player/ft-shaka-video-player.js#L1097
|
||||||
var protobuf_body = []byte{0x78, 0} // protobuf body
|
var protobuf_body = []byte{0x78, 0} // protobuf body
|
||||||
|
|
||||||
|
var secret_key = utils.Getenv("SECRET_KEY")
|
||||||
|
|
|
@ -56,6 +56,19 @@ func checkRequest(w http.ResponseWriter, req *http.Request, params url.Values) {
|
||||||
func Videoplayback(w http.ResponseWriter, req *http.Request) {
|
func Videoplayback(w http.ResponseWriter, req *http.Request) {
|
||||||
q := req.URL.Query()
|
q := req.URL.Query()
|
||||||
|
|
||||||
|
if q.Get("enc") == "yes" {
|
||||||
|
deencryptedQueryParams, err := utils.DecryptQueryParams(req.URL.Query().Get("data"), secret_key)
|
||||||
|
if err != nil {
|
||||||
|
http.Error(w, "Internal Server Error:\nFailed to decrypt query parameters", http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
q, err = url.ParseQuery(deencryptedQueryParams)
|
||||||
|
if err != nil {
|
||||||
|
http.Error(w, "Internal Server Error:\nFailed to parse query parameters from the decrypted query parameters", http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
checkRequest(w, req, q)
|
checkRequest(w, req, q)
|
||||||
|
|
||||||
expire, err := strconv.ParseInt(q.Get("expire"), 10, 64)
|
expire, err := strconv.ParseInt(q.Get("expire"), 10, 64)
|
||||||
|
|
|
@ -1,10 +1,13 @@
|
||||||
package utils
|
package utils
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"crypto/aes"
|
||||||
|
"encoding/base64"
|
||||||
"log"
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
"strings"
|
"strings"
|
||||||
|
"syscall"
|
||||||
|
|
||||||
"git.nadeko.net/Fijxu/http3-ytproxy/internal/httpc"
|
"git.nadeko.net/Fijxu/http3-ytproxy/internal/httpc"
|
||||||
)
|
)
|
||||||
|
@ -74,3 +77,33 @@ func PanicHandler(w http.ResponseWriter) {
|
||||||
http.Error(w, "Internal Server Error", http.StatusInternalServerError)
|
http.Error(w, "Internal Server Error", http.StatusInternalServerError)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func Getenv(key string) string {
|
||||||
|
// `YTPROXY_` as a prefix
|
||||||
|
v, _ := syscall.Getenv("YTPROXY_" + key)
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://stackoverflow.com/a/41652605
|
||||||
|
func DecryptQueryParams(encryptedQuery string, key string) (string, error) {
|
||||||
|
se, err := base64.URLEncoding.DecodeString(encryptedQuery)
|
||||||
|
if err != nil {
|
||||||
|
log.Println("[ERROR] Error when decoding base64 string:", err)
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
cipher, err := aes.NewCipher([]byte(key)[0:16])
|
||||||
|
if err != nil {
|
||||||
|
log.Println("[ERROR] Error initializating cipher.Block:", err)
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
decrypted := make([]byte, len(se))
|
||||||
|
size := 16
|
||||||
|
|
||||||
|
for bs, be := 0, size; bs < len(se); bs, be = bs+size, be+size {
|
||||||
|
cipher.Decrypt(decrypted[bs:be], se[bs:be])
|
||||||
|
}
|
||||||
|
|
||||||
|
paddingSize := int(decrypted[len(decrypted)-1])
|
||||||
|
return string(decrypted[0 : len(decrypted)-paddingSize]), nil
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue