delete works and with test
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,2 +1,3 @@
|
|||||||
.git
|
.git
|
||||||
|
target
|
||||||
proxy-lite
|
proxy-lite
|
||||||
@ -1,2 +1,3 @@
|
|||||||
# proxy-lite
|
# infinite-noodle
|
||||||
|
The best damn network proxy in the universe.
|
||||||
|
|
||||||
|
|||||||
17
build.sh
Executable file
17
build.sh
Executable file
@ -0,0 +1,17 @@
|
|||||||
|
PROG="./target/infinite-noodle.net-proxy"
|
||||||
|
CODE=""
|
||||||
|
|
||||||
|
echo "building for linux"
|
||||||
|
env GOOS=linux GOARCH=amd64 go build -o $PROG -buildvcs=false $CODE
|
||||||
|
|
||||||
|
echo "building for mac arm64"
|
||||||
|
env GOOS=darwin GOARCH=arm64 go build -o $PROG.mac.arm64 -buildvcs=false $CODE
|
||||||
|
|
||||||
|
echo "building for mac amd64"
|
||||||
|
env GOOS=darwin GOARCH=amd64 go build -o $PROG.mac.amd64 -buildvcs=false $CODE
|
||||||
|
|
||||||
|
echo "building for win arm64"
|
||||||
|
env GOOS=windows GOARCH=arm64 go build -o $PROG.win.arm64 -buildvcs=false $CODE
|
||||||
|
|
||||||
|
echo "building for win amd64"
|
||||||
|
env GOOS=windows GOARCH=amd64 go build -o $PROG.win.amd64 -buildvcs=false $CODE
|
||||||
86
database.go
Normal file
86
database.go
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/google/uuid"
|
||||||
|
"go.mills.io/bitcask/v2"
|
||||||
|
"log"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Database struct {
|
||||||
|
connection *bitcask.Bitcask
|
||||||
|
Handle *bitcask.Collection
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewDatabase(path string) *Database {
|
||||||
|
db, err := bitcask.Open(path)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
return &Database{
|
||||||
|
connection: db,
|
||||||
|
Handle: db.Collection("noodles"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (db *Database) MakeID() string {
|
||||||
|
id, err := uuid.NewUUID()
|
||||||
|
if err != nil {
|
||||||
|
log.Print(err)
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
return id.String()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (db *Database) GetAll() []Noodle {
|
||||||
|
var data []Noodle
|
||||||
|
err := db.Handle.List(&data)
|
||||||
|
if err != nil {
|
||||||
|
log.Print(err)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return data
|
||||||
|
}
|
||||||
|
|
||||||
|
func (db *Database) GetAllGeneric() []interface{} {
|
||||||
|
var data []interface{}
|
||||||
|
err := db.Handle.List(&data)
|
||||||
|
if err != nil {
|
||||||
|
log.Print(err)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return data
|
||||||
|
}
|
||||||
|
|
||||||
|
func (db *Database) Get(id string) Noodle {
|
||||||
|
var noodle Noodle
|
||||||
|
log.Printf("Looking up noodle key='%s'", id)
|
||||||
|
log.Printf("key='%s' exists=%b", id, db.Handle.Has(id))
|
||||||
|
err := db.Handle.Get(id, &noodle)
|
||||||
|
if err != nil {
|
||||||
|
log.Print(err)
|
||||||
|
return Noodle{}
|
||||||
|
}
|
||||||
|
return noodle
|
||||||
|
}
|
||||||
|
|
||||||
|
func (db *Database) Add(noodle Noodle) error {
|
||||||
|
err := db.Handle.Add(noodle.Id, noodle)
|
||||||
|
if err != nil {
|
||||||
|
log.Print(err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (db *Database) Delete(id string) error {
|
||||||
|
err := db.Handle.Delete(id)
|
||||||
|
if err != nil {
|
||||||
|
log.Print(err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (db *Database) Close() error {
|
||||||
|
return db.connection.Close()
|
||||||
|
}
|
||||||
20
go.mod
20
go.mod
@ -1,5 +1,21 @@
|
|||||||
module proxy-lite
|
module infinite-noodle
|
||||||
|
|
||||||
go 1.19
|
go 1.19
|
||||||
|
|
||||||
require inet.af/tcpproxy v0.0.0-20231102063150-2862066fc2a9
|
require (
|
||||||
|
go.mills.io/bitcask/v2 v2.1.3
|
||||||
|
inet.af/tcpproxy v0.0.0-20231102063150-2862066fc2a9
|
||||||
|
)
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/abcum/lcp v0.0.0-20201209214815-7a3f3840be81 // indirect
|
||||||
|
github.com/gofrs/flock v0.8.1 // indirect
|
||||||
|
github.com/google/uuid v1.6.0 // indirect
|
||||||
|
github.com/hashicorp/go-immutable-radix/v2 v2.0.0 // indirect
|
||||||
|
github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect
|
||||||
|
github.com/mattetti/filebuffer v1.0.1 // indirect
|
||||||
|
github.com/pkg/errors v0.9.1 // indirect
|
||||||
|
github.com/sirupsen/logrus v1.9.3 // indirect
|
||||||
|
golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 // indirect
|
||||||
|
golang.org/x/sys v0.20.0 // indirect
|
||||||
|
)
|
||||||
|
|||||||
51
go.sum
51
go.sum
@ -1,3 +1,54 @@
|
|||||||
|
github.com/abcum/lcp v0.0.0-20201209214815-7a3f3840be81 h1:uHogIJ9bXH75ZYrXnVShHIyywFiUZ7OOabwd9Sfd8rw=
|
||||||
|
github.com/abcum/lcp v0.0.0-20201209214815-7a3f3840be81/go.mod h1:6ZvnjTZX1LNo1oLpfaJK8h+MXqHxcBFBIwkgsv+xlv0=
|
||||||
github.com/armon/go-proxyproto v0.0.0-20210323213023-7e956b284f0a/go.mod h1:QmP9hvJ91BbJmGVGSbutW19IC0Q9phDCLGaomwTJbgU=
|
github.com/armon/go-proxyproto v0.0.0-20210323213023-7e956b284f0a/go.mod h1:QmP9hvJ91BbJmGVGSbutW19IC0Q9phDCLGaomwTJbgU=
|
||||||
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
|
||||||
|
github.com/gofrs/flock v0.8.1 h1:+gYjHKf32LDeiEEFhQaotPbLuUXjY5ZqxKgXy7n59aw=
|
||||||
|
github.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU=
|
||||||
|
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||||
|
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||||
|
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
||||||
|
github.com/gopherjs/gopherjs v0.0.0-20200217142428-fce0ec30dd00 h1:l5lAOZEym3oK3SQ2HBHWsJUfbNBiTXJDeW2QDxw9AQ0=
|
||||||
|
github.com/gopherjs/gopherjs v0.0.0-20200217142428-fce0ec30dd00/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
||||||
|
github.com/hashicorp/go-immutable-radix/v2 v2.0.0 h1:nq9lQ5I71Heg2lRb2/+szuIWKY3Y73d8YKyXyN91WzU=
|
||||||
|
github.com/hashicorp/go-immutable-radix/v2 v2.0.0/go.mod h1:hgdqLXA4f6NIjRVisM1TJ9aOJVNRqKZj+xDGF6m7PBw=
|
||||||
|
github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8=
|
||||||
|
github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k=
|
||||||
|
github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM=
|
||||||
|
github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
|
||||||
|
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
|
||||||
|
github.com/mattetti/filebuffer v1.0.1 h1:gG7pyfnSIZCxdoKq+cPa8T0hhYtD9NxCdI4D7PTjRLM=
|
||||||
|
github.com/mattetti/filebuffer v1.0.1/go.mod h1:YdMURNDOttIiruleeVr6f56OrMc+MydEnTcXwtkxNVs=
|
||||||
|
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||||
|
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
|
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
|
||||||
|
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
|
||||||
|
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
|
||||||
|
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
|
||||||
|
github.com/smartystreets/assertions v1.2.0 h1:42S6lae5dvLc7BrLu/0ugRtcFVjoJNMC/N3yZFZkDFs=
|
||||||
|
github.com/smartystreets/assertions v1.2.0/go.mod h1:tcbTF8ujkAEcZ8TElKY+i30BzYlVhC/LOxJk7iOWnoo=
|
||||||
|
github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s=
|
||||||
|
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
|
||||||
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
|
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
|
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
|
||||||
|
go.mills.io/bitcask/v2 v2.1.3 h1:xOe0sdkTHqgpMxsfDjcpaWOm8VtCmA5JzRy4dbicFfk=
|
||||||
|
go.mills.io/bitcask/v2 v2.1.3/go.mod h1:ZQFykoTTCvMwy24lBstZhSRQuleYIB4EzWKSOgEv6+k=
|
||||||
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
|
golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 h1:vr/HnozRka3pE4EsMEg1lgkXJkTFJCVUX+S/ZT6wYzM=
|
||||||
|
golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842/go.mod h1:XtvwrStGgqGPLc4cjQfWqZHG1YFdYs6swckp8vpsjnc=
|
||||||
|
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
|
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y=
|
||||||
|
golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
|
golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||||
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||||
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
|
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||||
inet.af/tcpproxy v0.0.0-20231102063150-2862066fc2a9 h1:zomTWJvjwLbKRgGameQtpK6DNFUbZ2oNJuWhgUkGp3M=
|
inet.af/tcpproxy v0.0.0-20231102063150-2862066fc2a9 h1:zomTWJvjwLbKRgGameQtpK6DNFUbZ2oNJuWhgUkGp3M=
|
||||||
inet.af/tcpproxy v0.0.0-20231102063150-2862066fc2a9/go.mod h1:Tojt5kmHpDIR2jMojxzZK2w2ZR7OILODmUo2gaSwjrk=
|
inet.af/tcpproxy v0.0.0-20231102063150-2862066fc2a9/go.mod h1:Tojt5kmHpDIR2jMojxzZK2w2ZR7OILODmUo2gaSwjrk=
|
||||||
|
|||||||
103
main.go
103
main.go
@ -2,47 +2,110 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"embed"
|
"embed"
|
||||||
"html/template"
|
"flag"
|
||||||
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"time"
|
||||||
|
|
||||||
"inet.af/tcpproxy"
|
"inet.af/tcpproxy"
|
||||||
)
|
)
|
||||||
|
|
||||||
//go:embed templates/*.html
|
//go:embed pub webfonts templates/*.html
|
||||||
var templatesFS embed.FS
|
var content embed.FS
|
||||||
|
|
||||||
|
var dataFlag = flag.String("data", "./infinite.db", "Path to database.")
|
||||||
|
var hostFlag = flag.String("host", "0.0.0.0", "Host to listen on.")
|
||||||
|
var portFlag = flag.Int("port", 7878, "Port to listen on.")
|
||||||
|
var runTest = flag.Bool("test", false, "Run data test")
|
||||||
|
|
||||||
|
var listenString string
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
flag.Parse()
|
||||||
|
listenString = fmt.Sprintf("%s:%d", *hostFlag, *portFlag)
|
||||||
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
//currentTime := time.Now()
|
||||||
|
noodleChannel := make(chan Noodle)
|
||||||
|
|
||||||
go proxify()
|
db := NewDatabase(*dataFlag)
|
||||||
|
defer db.Close()
|
||||||
|
|
||||||
// Parse templates from the embedded file system
|
if *runTest {
|
||||||
tmpl, err := template.ParseFS(templatesFS, "templates/*.html")
|
runTestSequence(db)
|
||||||
if err != nil {
|
|
||||||
log.Fatalf("Error parsing templates: %v", err)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
|
go systemCheck(db, noodleChannel)
|
||||||
data := struct{ Name string }{Name: "Go Embed"}
|
go tcpProxify(noodleChannel)
|
||||||
err := tmpl.ExecuteTemplate(w, "index.html", data)
|
|
||||||
if err != nil {
|
|
||||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
log.Println("Server starting on :8080")
|
http.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.FS(content))))
|
||||||
log.Fatal(http.ListenAndServe(":8080", nil))
|
// TODO: CRYPTO hrefs
|
||||||
|
http.HandleFunc("/", handleMain(db, &noodleChannel))
|
||||||
|
http.HandleFunc("/delete", handleDelete(db, &noodleChannel))
|
||||||
|
|
||||||
|
log.Printf("Server starting on %s", listenString)
|
||||||
|
log.Fatal(http.ListenAndServe(listenString, nil))
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func proxify() {
|
func systemCheck(db *Database, noodleChannel chan Noodle) {
|
||||||
|
for {
|
||||||
|
noodles := db.GetAll()
|
||||||
|
for _, noodle := range noodles {
|
||||||
|
noodleChannel <- noodle
|
||||||
|
}
|
||||||
|
time.Sleep(60 * time.Second)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func startProxy(proxy *tcpproxy.Proxy) {
|
||||||
|
log.Print(proxy.Run())
|
||||||
|
}
|
||||||
|
|
||||||
|
func tcpProxify(noodleChannel chan Noodle) {
|
||||||
|
noodleMap := make(map[string]*tcpproxy.Proxy)
|
||||||
|
for {
|
||||||
|
noodle := <-noodleChannel
|
||||||
|
_, running := noodleMap[noodle.Id]
|
||||||
|
if noodle.IsUp && !running {
|
||||||
var p tcpproxy.Proxy
|
var p tcpproxy.Proxy
|
||||||
p.AddRoute("127.0.0.1:5555", tcpproxy.To("127.0.0.1:6666"))
|
src := fmt.Sprintf("0.0.0.0:%d", noodle.ListenPort)
|
||||||
|
dst := fmt.Sprintf("%s:%d", noodle.DestHost, noodle.DestPort)
|
||||||
|
log.Printf("Starting a noodle from %s to %s", src, dst)
|
||||||
|
p.AddRoute(src, tcpproxy.To(dst))
|
||||||
|
//p.Start()
|
||||||
|
noodleMap[noodle.Id] = &p
|
||||||
|
go startProxy(&p)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if !noodle.IsUp && running {
|
||||||
|
log.Printf("Closing noodle=%v", noodle)
|
||||||
|
err := noodleMap[noodle.Id].Close()
|
||||||
|
if err != nil {
|
||||||
|
log.Print(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//p.AddHTTPHostRoute(":80", "foo.com", tcpproxy.To("10.0.0.1:8081"))
|
//p.AddHTTPHostRoute(":80", "foo.com", tcpproxy.To("10.0.0.1:8081"))
|
||||||
//p.AddHTTPHostRoute(":80", "bar.com", tcpproxy.To("10.0.0.2:8082"))
|
//p.AddHTTPHostRoute(":80", "bar.com", tcpproxy.To("10.0.0.2:8082"))
|
||||||
//p.AddRoute(":80", tcpproxy.To("10.0.0.1:8081")) // fallback
|
//p.AddRoute(":80", tcpproxy.To("10.0.0.1:8081")) // fallback
|
||||||
//p.AddSNIRoute(":443", "foo.com", tcpproxy.To("10.0.0.1:4431"))
|
//p.AddSNIRoute(":443", "foo.com", tcpproxy.To("10.0.0.1:4431"))
|
||||||
//p.AddSNIRoute(":443", "bar.com", tcpproxy.To("10.0.0.2:4432"))
|
//p.AddSNIRoute(":443", "bar.com", tcpproxy.To("10.0.0.2:4432"))
|
||||||
//p.AddRoute(":443", tcpproxy.To("10.0.0.1:4431")) // fallback
|
//p.AddRoute(":443", tcpproxy.To("10.0.0.1:4431")) // fallback
|
||||||
log.Fatal(p.Run())
|
//log.Fatal(p.Run())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func runTestSequence(db *Database) {
|
||||||
|
for i := 0; i < 21; i++ {
|
||||||
|
noodle := Noodle{db.MakeID(), "Name_Test", "Proto_Test", 1080+i, 22, "localhost", time.Now().Second(), true}
|
||||||
|
log.Printf("Test noodle=%v", noodle)
|
||||||
|
db.Add(noodle)
|
||||||
|
log.Printf("Test id=%s exists=%s", noodle.Id, db.Handle.Has(noodle.Id))
|
||||||
|
log.Printf("Test GetAllGeneric=%v", db.GetAllGeneric())
|
||||||
|
//db.Delete(noodle.Id)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
12
model.go
Normal file
12
model.go
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
type Noodle struct {
|
||||||
|
Id string
|
||||||
|
Name string
|
||||||
|
Proto string
|
||||||
|
ListenPort int
|
||||||
|
DestPort int
|
||||||
|
DestHost string
|
||||||
|
Expiration int
|
||||||
|
IsUp bool
|
||||||
|
}
|
||||||
@ -1,12 +1,104 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html>
|
<html data-theme="dark">
|
||||||
|
|
||||||
<head>
|
<head>
|
||||||
<title>Embedded Template</title>
|
<title>Infinite-Noodles</title>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<link rel="stylesheet" href="/static/pub/bulma.min.css">
|
||||||
|
<link rel="stylesheet" href="/static/pub/all.min.css">
|
||||||
|
<style>
|
||||||
|
.banner-container {
|
||||||
|
background-image: url("/static/pub/long-banner.jpg");
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-size: cover;
|
||||||
|
position: relative;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
img.banner {
|
||||||
|
height: 50px;
|
||||||
|
}
|
||||||
|
img.banner-long {
|
||||||
|
height: 50px;
|
||||||
|
object-fit: fill;
|
||||||
|
}
|
||||||
|
table {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body class="has-navbar-fixed-top">
|
||||||
<h1>Hello, {{.Name}}!</h1>
|
<nav class="navbar is-fixed-top" role="navigation" aria-label="main navigation">
|
||||||
|
<div class="navbar-brand">
|
||||||
|
<img class="banner" src="/static/pub/logo.jpg"/>
|
||||||
|
</div>
|
||||||
|
<div class="banner-container">
|
||||||
|
<!-- <img class="banner-long" src="/static/pub/long-banner.jpg"/> -->
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
|
||||||
|
<div class="table-container">
|
||||||
|
<table class="table is-bordered is-striped is-narrow is-hoverable is-fullwidth">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Name</th>
|
||||||
|
<th>Proto</th>
|
||||||
|
<th>Listening Port</th>
|
||||||
|
<th>Dest Port</th>
|
||||||
|
<th>Dest Host/IP</th>
|
||||||
|
<th>Expiration</th>
|
||||||
|
<th>Status</th>
|
||||||
|
<th></th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td><input class="input is-link is-small" type="text" placeholder="Name"/></td>
|
||||||
|
<td>TCP</td>
|
||||||
|
<td><input class="input is-link is-small" type="text" placeholder="Listen Port"/></td>
|
||||||
|
<td><input class="input is-link is-small" type="text" placeholder="Destination Port"/></td>
|
||||||
|
<td><input class="input is-link is-small" type="text" placeholder="Destination Host"/></td>
|
||||||
|
<td>Expiration</td>
|
||||||
|
<td>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<button class="button">
|
||||||
|
<span class="icon has-text-success"><i class="fas fa-plus"></i></span>
|
||||||
|
</button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{{range .}}
|
||||||
|
<tr>
|
||||||
|
<td>{{.Name}}</td>
|
||||||
|
<td>{{.Proto}}</td>
|
||||||
|
<td>{{.ListenPort}}</td>
|
||||||
|
<td>{{.DestPort}}</td>
|
||||||
|
<td>{{.DestHost}}</td>
|
||||||
|
<td>{{.Expiration}}</td>
|
||||||
|
<td>
|
||||||
|
{{if .IsUp}}
|
||||||
|
<span class="icon has-text-success"><i class="fas fa-check-square"></i></span>
|
||||||
|
{{ else }}
|
||||||
|
<span class="icon has-text-danger"><i class="fas fa-ban"></i></span>
|
||||||
|
{{ end }}
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<a href="/delete?id={{.Id}}">
|
||||||
|
<span class="icon has-text-danger"><i class="fas fa-minus"></i></span>
|
||||||
|
</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{{end}}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
<footer class="footer">
|
||||||
|
<div class="content has-text-centered">
|
||||||
|
<p>
|
||||||
|
<strong>Infinite-Noodles Network Proxy</strong> - © 2025 Jimmy Allen
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</footer>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
52
web.go
Normal file
52
web.go
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"html/template"
|
||||||
|
"log"
|
||||||
|
"net/http"
|
||||||
|
)
|
||||||
|
|
||||||
|
func handleMain(db *Database, pc *chan Noodle) func(w http.ResponseWriter, req *http.Request) {
|
||||||
|
tmpl, err := template.ParseFS(content, "templates/*.html")
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("Error parsing templates: %v", err)
|
||||||
|
}
|
||||||
|
return func(w http.ResponseWriter, req *http.Request) {
|
||||||
|
data := db.GetAll()
|
||||||
|
err := tmpl.ExecuteTemplate(w, "index.html", data)
|
||||||
|
if err != nil {
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func handleDelete(db *Database, pc *chan Noodle) func(w http.ResponseWriter, req *http.Request) {
|
||||||
|
return func(w http.ResponseWriter, req *http.Request) {
|
||||||
|
|
||||||
|
q := req.URL.Query()
|
||||||
|
vals, ok := q["id"]
|
||||||
|
if ok {
|
||||||
|
id := vals[0]
|
||||||
|
noodle := db.Get(id)
|
||||||
|
noodle.IsUp = false
|
||||||
|
*pc <- noodle
|
||||||
|
log.Printf("Deleting noodle=%v", noodle)
|
||||||
|
//log.Printf("Deleting noodle=%s", id)
|
||||||
|
db.Delete(noodle.Id)
|
||||||
|
}
|
||||||
|
|
||||||
|
http.Redirect(w, req, "/", 307)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func handleAdd(db *Database, pc *chan Noodle) func(w http.ResponseWriter, req *http.Request) {
|
||||||
|
return func(w http.ResponseWriter, req *http.Request) {
|
||||||
|
|
||||||
|
if req.Method != "POST" {
|
||||||
|
http.Error(w, "", http.StatusMethodNotAllowed)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
http.Redirect(w, req, "/", 307)
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user