Initial commit
This commit is contained in:
commit
5140f1f399
8
go.mod
Normal file
8
go.mod
Normal file
@ -0,0 +1,8 @@
|
||||
module papatutuwawa/miniproxy
|
||||
|
||||
go 1.16
|
||||
|
||||
require (
|
||||
github.com/BurntSushi/toml v0.4.1 // indirect
|
||||
github.com/gorilla/mux v1.8.0 // indirect
|
||||
)
|
4
go.sum
Normal file
4
go.sum
Normal file
@ -0,0 +1,4 @@
|
||||
github.com/BurntSushi/toml v0.4.1 h1:GaI7EiDXDRfa8VshkTj7Fym7ha+y8/XxIgD2okUIjLw=
|
||||
github.com/BurntSushi/toml v0.4.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
|
||||
github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI=
|
||||
github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
|
102
main.go
Normal file
102
main.go
Normal file
@ -0,0 +1,102 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"net/url"
|
||||
"log"
|
||||
"os"
|
||||
"strconv"
|
||||
"crypto/hmac"
|
||||
"crypto/sha256"
|
||||
"encoding/base64"
|
||||
"io"
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/BurntSushi/toml"
|
||||
)
|
||||
|
||||
type tomlConfig struct {
|
||||
Port int `toml:"port"`
|
||||
Secret string `toml:"secret"`
|
||||
}
|
||||
|
||||
func proxyRequest(w http.ResponseWriter, r *http.Request, secret []byte) {
|
||||
vars := mux.Vars(r)
|
||||
requestUrl, err := url.QueryUnescape(vars["url"])
|
||||
if err != nil {
|
||||
log.Printf("Failed to url decode url: %s", err)
|
||||
return
|
||||
}
|
||||
macRaw, err := url.QueryUnescape(vars["hmac"])
|
||||
if err != nil {
|
||||
log.Printf("Failed to url decode HMAC: %s", err)
|
||||
return
|
||||
}
|
||||
|
||||
mac := hmac.New(sha256.New, secret)
|
||||
mac.Write([]byte(requestUrl))
|
||||
|
||||
expectedMac := mac.Sum(nil)
|
||||
receivedMac, err := base64.StdEncoding.DecodeString(macRaw)
|
||||
if err != nil {
|
||||
log.Printf("Failed to decode HMAC: %s", err)
|
||||
return
|
||||
}
|
||||
|
||||
if !hmac.Equal(expectedMac, receivedMac) {
|
||||
log.Printf("invalid-hmac:%s", r.RemoteAddr)
|
||||
log.Printf("URL: '%s'", requestUrl)
|
||||
http.Error(w, "Invalid HMAC", http.StatusUnauthorized)
|
||||
return
|
||||
}
|
||||
|
||||
client := &http.Client{}
|
||||
resp, err := client.Get(requestUrl)
|
||||
defer resp.Body.Close()
|
||||
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to perform GET: %s", err)
|
||||
}
|
||||
|
||||
w.WriteHeader(resp.StatusCode)
|
||||
io.Copy(w, resp.Body)
|
||||
}
|
||||
|
||||
func makeProxyRequestHandler(secret []byte) http.HandlerFunc {
|
||||
fn := func(w http.ResponseWriter, r *http.Request) {
|
||||
proxyRequest(w, r, secret)
|
||||
}
|
||||
|
||||
return http.HandlerFunc(fn)
|
||||
}
|
||||
|
||||
func exists(path string) bool {
|
||||
// Returns true if path exists. false otherwise
|
||||
_, err := os.Stat(path)
|
||||
return !os.IsNotExist(err)
|
||||
}
|
||||
|
||||
func main() {
|
||||
config := tomlConfig {
|
||||
Port: 8080,
|
||||
}
|
||||
|
||||
switch {
|
||||
case exists("./config.toml"):
|
||||
_, err := toml.DecodeFile("./config.toml", &config)
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to read ./config.toml: %s", err)
|
||||
}
|
||||
case exists("/etc/miniproxy/config.toml"):
|
||||
_, err := toml.DecodeFile("/etc/miniproxy/config.toml", &config)
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to read /etc/miniproxy/config.toml: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
log.Printf("Running on :%d\n", config.Port)
|
||||
|
||||
r := mux.NewRouter()
|
||||
r.UseEncodedPath()
|
||||
r.HandleFunc("/proxy/{hmac}/{url:.+}", makeProxyRequestHandler([]byte(config.Secret)))
|
||||
log.Fatal(http.ListenAndServe(":" + strconv.Itoa(config.Port), r))
|
||||
}
|
Loading…
Reference in New Issue
Block a user