diff --git a/.gitignore b/.gitignore
index aaadf73..bde3ac6 100644
--- a/.gitignore
+++ b/.gitignore
@@ -7,6 +7,7 @@
*.dll
*.so
*.dylib
+**.db
# Test binary, built with `go test -c`
*.test
@@ -29,4 +30,4 @@ go.work.sum
# Editor/IDE
# .idea/
-# .vscode/
+.vscode/
diff --git a/app/backend/binary.go b/app/backend/binary.go
new file mode 100644
index 0000000..b110003
--- /dev/null
+++ b/app/backend/binary.go
@@ -0,0 +1,114 @@
+package backend
+
+import (
+ "binaryserver/app/db"
+ "fmt"
+ "net/http"
+ "strconv"
+ "strings"
+
+ "github.com/go-rod/rod"
+ "github.com/go-rod/rod/lib/launcher"
+)
+
+var browser *rod.Browser
+
+func asciiToBinary(text string) string {
+ var result []string
+ for _, char := range text {
+ binary := fmt.Sprintf("%08b", char) // 8-bit binary format
+ result = append(result, binary)
+ }
+ return strings.Join(result, " ")
+}
+
+func binaryToASCII(binary string) (string, error) {
+ // Ensure the length of the binary string is a multiple of 8
+ if len(binary)%8 != 0 {
+ return "", fmt.Errorf("binary string length must be a multiple of 8")
+ }
+
+ var sb strings.Builder
+ for i := 0; i < len(binary); i += 8 {
+ byteStr := binary[i : i+8]
+ b, err := strconv.ParseUint(byteStr, 2, 8)
+ if err != nil {
+ return "", fmt.Errorf("invalid binary sequence at position %d: %v", i, err)
+ }
+ sb.WriteByte(byte(b))
+ }
+ return sb.String(), nil
+}
+
+func instagramHandleExists(username string, bypass ...bool) string {
+ records, _ := db.GetRecords(db.QueryOptions{Where: fmt.Sprintf(`handle='%v'`, username)})
+ if len(records) > 0 && len(bypass) == 0 {
+ return records[0].URL
+ }
+ url := fmt.Sprintf("https://www.instagram.com/%s/", username)
+
+ page := browser.MustPage(url)
+
+ // Wait until body is loaded
+ page.MustWaitLoad().MustWaitIdle()
+
+ body := page.MustElement("body").MustText()
+
+ record := db.NewRecord(username, url)
+
+ // Instagram shows this for non-existent users
+ if strings.Contains(body, "Sorry, this page isn't available") {
+ record.URL = ""
+ db.SaveRecord(record)
+ return ""
+ }
+ db.SaveRecord(record)
+ return url
+}
+
+func BinaryHandler(w http.ResponseWriter, req *http.Request) {
+ binaryInput := strings.ReplaceAll(req.URL.Query().Get("binary"), " ", "")
+ var text string
+ var handle string
+ var err error
+ if binaryInput == "" {
+ asciiInput := req.URL.Query().Get("text")
+ if asciiInput == "" {
+ fmt.Fprintf(w, "Could not encode or decode!\n")
+ return
+ }
+ text = asciiToBinary(asciiInput)
+ fmt.Fprintf(w, "%v\n", GetFancyResponse(`
`+text+`
`, ""))
+ return
+ } else {
+ text, err = binaryToASCII(binaryInput)
+ text = strings.ReplaceAll(text, "@", "")
+ handle = text
+ }
+
+ if err != nil {
+ fmt.Fprintf(w, "Could not decode!\n")
+ return
+ }
+
+ var url string
+ if url = instagramHandleExists(text); url != "" {
+ text = `` + text + ``
+ } else {
+ text = `` + text + `
`
+ }
+ if url == "" {
+ handle = ""
+ }
+
+ fmt.Fprintf(w, "%v\n", GetFancyResponse(text, handle))
+}
+
+func init() {
+ path, _ := launcher.New().
+ Headless(true).
+ // Uncomment below to see browser
+ // Set("headless", "false").
+ Launch()
+ browser = rod.New().ControlURL(path).MustConnect()
+}
diff --git a/app/backend/page.go b/app/backend/page.go
new file mode 100644
index 0000000..17ca29b
--- /dev/null
+++ b/app/backend/page.go
@@ -0,0 +1,51 @@
+package backend
+
+func GetFancyResponse(input, handle string) string {
+ var hasHandle string
+ if handle != "" {
+ hasHandle = `Report Broken Link`
+ }
+ return `
+
+
+
+
+
+ Decoded Binary
+
+
+
+
+ ` + input + `
+ ` + hasHandle + `
+
+
+
+ `
+}
diff --git a/app/backend/report.go b/app/backend/report.go
new file mode 100644
index 0000000..bac9f84
--- /dev/null
+++ b/app/backend/report.go
@@ -0,0 +1,20 @@
+package backend
+
+import (
+ "binaryserver/app/db"
+ "fmt"
+ "net/http"
+)
+
+func ReportHandler(w http.ResponseWriter, req *http.Request) {
+ handle := req.URL.Query().Get("handle")
+ records, _ := db.GetRecords(db.QueryOptions{Where: fmt.Sprintf(`handle='%v'`, handle)})
+ if len(records) > 0 {
+ if result := instagramHandleExists(records[0].Handle, true); result == "" && records[0].URL != "" {
+ fmt.Fprintf(w, "Link does seem to be bad. Fixing...\n")
+ db.DeleteRecord(records[0])
+ } else {
+ fmt.Fprintf(w, "Link seems to be active and working!\n")
+ }
+ }
+}
diff --git a/app/db/db.go b/app/db/db.go
new file mode 100644
index 0000000..073467d
--- /dev/null
+++ b/app/db/db.go
@@ -0,0 +1,39 @@
+package db
+
+import (
+ "database/sql"
+
+ _ "modernc.org/sqlite"
+)
+
+var conn *sql.DB
+
+func HandleConn(testing ...bool) *sql.DB {
+ if len(testing) > 0 {
+ conn, _ = sql.Open("sqlite", "file::memory:?cache=shared")
+ buildSchema()
+ return conn
+ }
+ if conn == nil {
+ conn, _ = sql.Open("sqlite", "records.db")
+ buildSchema()
+ return conn
+ }
+ return conn
+}
+
+func buildSchema() error {
+ c := HandleConn()
+ _, err := c.Exec(`
+
+CREATE TABLE IF NOT EXISTS records
+(
+ UUID TEXT NOT NULL,
+ Handle TEXT NOT NULL UNIQUE,
+ URL TEXT NOT NULL,
+ PRIMARY KEY (UUID)
+);
+
+`)
+ return err
+}
diff --git a/app/db/record.go b/app/db/record.go
new file mode 100644
index 0000000..3744bdc
--- /dev/null
+++ b/app/db/record.go
@@ -0,0 +1,77 @@
+package db
+
+import (
+ "binaryserver/app/utils"
+
+ "github.com/google/uuid"
+)
+
+type Record struct {
+ UUID uuid.UUID `json:"uuid"`
+ Handle string `json:"handle"`
+ URL string `json:"url"`
+}
+
+func NewRecord(handle, url string) Record {
+ return Record{
+ UUID: utils.GetUUID(),
+ Handle: handle,
+ URL: url,
+ }
+}
+
+func SaveRecord(record Record) error {
+ conn := HandleConn()
+ stmt, err := conn.Prepare(`INSERT INTO records
+ VALUES(?, ?, ?)`)
+ if err != nil {
+ return err
+ }
+ _, err = stmt.Exec(record.UUID.String(), record.Handle, record.URL)
+ if err != nil {
+ return err
+ }
+ defer stmt.Close()
+ return nil
+}
+
+func GetRecords(opts QueryOptions) ([]Record, error) {
+ conn := HandleConn()
+ var records []Record
+ stmt, err := opts.Build(conn, "records")
+ if err != nil {
+ return nil, err
+ }
+ row, err := stmt.Query()
+ stmt.Close()
+ if err != nil {
+ return nil, err
+ }
+ defer row.Close()
+ for {
+ if err != nil {
+ return nil, err
+ }
+ if !row.Next() {
+ break
+ }
+ record := Record{}
+ row.Scan(&record.UUID, &record.Handle, &record.URL)
+ records = append(records, record)
+ }
+ return records, nil
+}
+
+func DeleteRecord(record Record) error {
+ stmt, err := conn.Prepare(`DELETE FROM records
+ WHERE UUID = ?`)
+ if err != nil {
+ return err
+ }
+ defer stmt.Close()
+ _, err = stmt.Exec(record.UUID.String())
+ if err != nil {
+ return err
+ }
+ return nil
+}
diff --git a/app/db/record_test.go b/app/db/record_test.go
new file mode 100644
index 0000000..66e140d
--- /dev/null
+++ b/app/db/record_test.go
@@ -0,0 +1,18 @@
+package db
+
+import (
+ "testing"
+
+ "github.com/stretchr/testify/assert"
+)
+
+func TestRecords(t *testing.T) {
+ HandleConn(true)
+ rec := NewRecord("test", "https://instagram.com/handle")
+ err := SaveRecord(rec)
+ assert.Nil(t, err)
+ records, err := GetRecords(QueryOptions{Where: `handle='test'`})
+ assert.Nil(t, err)
+ assert.Greater(t, len(records), 0)
+ assert.Equal(t, "https://instagram.com/handle", records[0].URL)
+}
diff --git a/app/db/types.go b/app/db/types.go
new file mode 100644
index 0000000..4bffcef
--- /dev/null
+++ b/app/db/types.go
@@ -0,0 +1,50 @@
+package db
+
+import (
+ "database/sql"
+ "fmt"
+ "strings"
+)
+
+type QueryOptions struct {
+ Select []string
+ Where string
+ OrderBy string
+ Limit uint
+ Offset uint
+}
+
+func (o *QueryOptions) Build(conn *sql.DB, table string) (*sql.Stmt, error) {
+ sel := "*"
+ where := ""
+ orderby := ""
+ limit := ""
+ if o.Select != nil {
+ sel = strings.Join(o.Select, ", ")
+ }
+ if o.Where != "" {
+ where = fmt.Sprintf(
+ `WHERE
+%v`, o.Where)
+ }
+ if o.OrderBy != "" {
+ orderby = fmt.Sprintf(
+ `ORDER BY
+ %v`, o.OrderBy)
+ }
+ if o.Limit != 0 && o.Offset != 0 {
+ limit = fmt.Sprintf(
+ `LIMIT %v OFFSET %v;`, o.Limit, o.Offset)
+ } else if o.Limit != 0 {
+ limit = fmt.Sprintf(
+ `LIMIT %v`, o.Limit)
+ }
+ return conn.Prepare(fmt.Sprintf(
+ `SELECT
+ %v
+FROM
+ %v
+%v
+%v
+%v;`, sel, table, where, orderby, limit))
+}
diff --git a/app/utils/utils.go b/app/utils/utils.go
new file mode 100644
index 0000000..e428057
--- /dev/null
+++ b/app/utils/utils.go
@@ -0,0 +1,12 @@
+package utils
+
+import "github.com/google/uuid"
+
+func GetUUID() uuid.UUID {
+ uuid.SetClockSequence(uuid.ClockSequence())
+ if uid, err := uuid.NewV7(); err == nil {
+ return uid
+ }
+ uid, _ := uuid.NewUUID()
+ return uid
+}
diff --git a/go.mod b/go.mod
new file mode 100644
index 0000000..aa25c20
--- /dev/null
+++ b/go.mod
@@ -0,0 +1,31 @@
+module binaryserver
+
+go 1.24.2
+
+require (
+ github.com/go-rod/rod v0.116.2
+ github.com/google/uuid v1.6.0
+ github.com/patrickmn/go-cache v2.1.0+incompatible
+ github.com/stretchr/testify v1.10.0
+ modernc.org/sqlite v1.38.0
+)
+
+require (
+ github.com/davecgh/go-spew v1.1.1 // indirect
+ github.com/dustin/go-humanize v1.0.1 // indirect
+ github.com/mattn/go-isatty v0.0.20 // indirect
+ github.com/ncruces/go-strftime v0.1.9 // indirect
+ github.com/pmezard/go-difflib v1.0.0 // indirect
+ github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
+ github.com/ysmood/fetchup v0.2.3 // indirect
+ github.com/ysmood/goob v0.4.0 // indirect
+ github.com/ysmood/got v0.40.0 // indirect
+ github.com/ysmood/gson v0.7.3 // indirect
+ github.com/ysmood/leakless v0.9.0 // indirect
+ golang.org/x/exp v0.0.0-20250408133849-7e4ce0ab07d0 // indirect
+ golang.org/x/sys v0.33.0 // indirect
+ gopkg.in/yaml.v3 v3.0.1 // indirect
+ modernc.org/libc v1.65.10 // indirect
+ modernc.org/mathutil v1.7.1 // indirect
+ modernc.org/memory v1.11.0 // indirect
+)
diff --git a/go.sum b/go.sum
new file mode 100644
index 0000000..0b07da1
--- /dev/null
+++ b/go.sum
@@ -0,0 +1,75 @@
+github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
+github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
+github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
+github.com/go-rod/rod v0.116.2 h1:A5t2Ky2A+5eD/ZJQr1EfsQSe5rms5Xof/qj296e+ZqA=
+github.com/go-rod/rod v0.116.2/go.mod h1:H+CMO9SCNc2TJ2WfrG+pKhITz57uGNYU43qYHh438Mg=
+github.com/google/pprof v0.0.0-20250317173921-a4b03ec1a45e h1:ijClszYn+mADRFY17kjQEVQ1XRhq2/JR1M3sGqeJoxs=
+github.com/google/pprof v0.0.0-20250317173921-a4b03ec1a45e/go.mod h1:boTsfXsheKC2y+lKOCMpSfarhxDeIzfZG1jqGcPl3cA=
+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/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
+github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
+github.com/ncruces/go-strftime v0.1.9 h1:bY0MQC28UADQmHmaF5dgpLmImcShSi2kHU9XLdhx/f4=
+github.com/ncruces/go-strftime v0.1.9/go.mod h1:Fwc5htZGVVkseilnfgOVb9mKy6w1naJmn9CehxcKcls=
+github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc=
+github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ=
+github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
+github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE=
+github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
+github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
+github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
+github.com/ysmood/fetchup v0.2.3 h1:ulX+SonA0Vma5zUFXtv52Kzip/xe7aj4vqT5AJwQ+ZQ=
+github.com/ysmood/fetchup v0.2.3/go.mod h1:xhibcRKziSvol0H1/pj33dnKrYyI2ebIvz5cOOkYGns=
+github.com/ysmood/goob v0.4.0 h1:HsxXhyLBeGzWXnqVKtmT9qM7EuVs/XOgkX7T6r1o1AQ=
+github.com/ysmood/goob v0.4.0/go.mod h1:u6yx7ZhS4Exf2MwciFr6nIM8knHQIE22lFpWHnfql18=
+github.com/ysmood/gop v0.2.0 h1:+tFrG0TWPxT6p9ZaZs+VY+opCvHU8/3Fk6BaNv6kqKg=
+github.com/ysmood/gop v0.2.0/go.mod h1:rr5z2z27oGEbyB787hpEcx4ab8cCiPnKxn0SUHt6xzk=
+github.com/ysmood/got v0.40.0 h1:ZQk1B55zIvS7zflRrkGfPDrPG3d7+JOza1ZkNxcc74Q=
+github.com/ysmood/got v0.40.0/go.mod h1:W7DdpuX6skL3NszLmAsC5hT7JAhuLZhByVzHTq874Qg=
+github.com/ysmood/gotrace v0.6.0 h1:SyI1d4jclswLhg7SWTL6os3L1WOKeNn/ZtzVQF8QmdY=
+github.com/ysmood/gotrace v0.6.0/go.mod h1:TzhIG7nHDry5//eYZDYcTzuJLYQIkykJzCRIo4/dzQM=
+github.com/ysmood/gson v0.7.3 h1:QFkWbTH8MxyUTKPkVWAENJhxqdBa4lYTQWqZCiLG6kE=
+github.com/ysmood/gson v0.7.3/go.mod h1:3Kzs5zDl21g5F/BlLTNcuAGAYLKt2lV5G8D1zF3RNmg=
+github.com/ysmood/leakless v0.9.0 h1:qxCG5VirSBvmi3uynXFkcnLMzkphdh3xx5FtrORwDCU=
+github.com/ysmood/leakless v0.9.0/go.mod h1:R8iAXPRaG97QJwqxs74RdwzcRHT1SWCGTNqY8q0JvMQ=
+golang.org/x/exp v0.0.0-20250408133849-7e4ce0ab07d0 h1:R84qjqJb5nVJMxqWYb3np9L5ZsaDtB+a39EqjV0JSUM=
+golang.org/x/exp v0.0.0-20250408133849-7e4ce0ab07d0/go.mod h1:S9Xr4PYopiDyqSyp5NjCrhFrqg6A5zA2E/iPHPhqnS8=
+golang.org/x/mod v0.24.0 h1:ZfthKaKaT4NrhGVZHO1/WDTwGES4De8KtWO0SIbNJMU=
+golang.org/x/mod v0.24.0/go.mod h1:IXM97Txy2VM4PJ3gI61r1YEk/gAj6zAHN3AdZt6S9Ww=
+golang.org/x/sync v0.14.0 h1:woo0S4Yywslg6hp4eUFjTVOyKt0RookbpAHG4c1HmhQ=
+golang.org/x/sync v0.14.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
+golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw=
+golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
+golang.org/x/tools v0.33.0 h1:4qz2S3zmRxbGIhDIAgjxvFutSvH5EfnsYrRBj0UI0bc=
+golang.org/x/tools v0.33.0/go.mod h1:CIJMaWEY88juyUfo7UbgPqbC8rU2OqfAV1h2Qp0oMYI=
+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.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
+gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+modernc.org/cc/v4 v4.26.1 h1:+X5NtzVBn0KgsBCBe+xkDC7twLb/jNVj9FPgiwSQO3s=
+modernc.org/cc/v4 v4.26.1/go.mod h1:uVtb5OGqUKpoLWhqwNQo/8LwvoiEBLvZXIQ/SmO6mL0=
+modernc.org/ccgo/v4 v4.28.0 h1:rjznn6WWehKq7dG4JtLRKxb52Ecv8OUGah8+Z/SfpNU=
+modernc.org/ccgo/v4 v4.28.0/go.mod h1:JygV3+9AV6SmPhDasu4JgquwU81XAKLd3OKTUDNOiKE=
+modernc.org/fileutil v1.3.3 h1:3qaU+7f7xxTUmvU1pJTZiDLAIoJVdUSSauJNHg9yXoA=
+modernc.org/fileutil v1.3.3/go.mod h1:HxmghZSZVAz/LXcMNwZPA/DRrQZEVP9VX0V4LQGQFOc=
+modernc.org/gc/v2 v2.6.5 h1:nyqdV8q46KvTpZlsw66kWqwXRHdjIlJOhG6kxiV/9xI=
+modernc.org/gc/v2 v2.6.5/go.mod h1:YgIahr1ypgfe7chRuJi2gD7DBQiKSLMPgBQe9oIiito=
+modernc.org/libc v1.65.10 h1:ZwEk8+jhW7qBjHIT+wd0d9VjitRyQef9BnzlzGwMODc=
+modernc.org/libc v1.65.10/go.mod h1:StFvYpx7i/mXtBAfVOjaU0PWZOvIRoZSgXhrwXzr8Po=
+modernc.org/mathutil v1.7.1 h1:GCZVGXdaN8gTqB1Mf/usp1Y/hSqgI2vAGGP4jZMCxOU=
+modernc.org/mathutil v1.7.1/go.mod h1:4p5IwJITfppl0G4sUEDtCr4DthTaT47/N3aT6MhfgJg=
+modernc.org/memory v1.11.0 h1:o4QC8aMQzmcwCK3t3Ux/ZHmwFPzE6hf2Y5LbkRs+hbI=
+modernc.org/memory v1.11.0/go.mod h1:/JP4VbVC+K5sU2wZi9bHoq2MAkCnrt2r98UGeSK7Mjw=
+modernc.org/opt v0.1.4 h1:2kNGMRiUjrp4LcaPuLY2PzUfqM/w9N23quVwhKt5Qm8=
+modernc.org/opt v0.1.4/go.mod h1:03fq9lsNfvkYSfxrfUhZCWPk1lm4cq4N+Bh//bEtgns=
+modernc.org/sortutil v1.2.1 h1:+xyoGf15mM3NMlPDnFqrteY07klSFxLElE2PVuWIJ7w=
+modernc.org/sortutil v1.2.1/go.mod h1:7ZI3a3REbai7gzCLcotuw9AC4VZVpYMjDzETGsSMqJE=
+modernc.org/sqlite v1.38.0 h1:+4OrfPQ8pxHKuWG4md1JpR/EYAh3Md7TdejuuzE7EUI=
+modernc.org/sqlite v1.38.0/go.mod h1:1Bj+yES4SVvBZ4cBOpVZ6QgesMCKpJZDq0nxYzOpmNE=
+modernc.org/strutil v1.2.1 h1:UneZBkQA+DX2Rp35KcM69cSsNES9ly8mQWD71HKlOA0=
+modernc.org/strutil v1.2.1/go.mod h1:EHkiggD70koQxjVdSBM3JKM7k6L0FbGE5eymy9i3B9A=
+modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y=
+modernc.org/token v1.1.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM=
diff --git a/main.go b/main.go
new file mode 100644
index 0000000..db663c0
--- /dev/null
+++ b/main.go
@@ -0,0 +1,12 @@
+package main
+
+import (
+ "binaryserver/app/backend"
+ "net/http"
+)
+
+func main() {
+ http.HandleFunc("/report", backend.ReportHandler)
+ http.HandleFunc("/", backend.BinaryHandler)
+ http.ListenAndServe(":8080", nil)
+}