diff options
author | leo <leo@azuminha.com> | 2025-07-01 17:46:39 -0300 |
---|---|---|
committer | leo <leo@azuminha.com> | 2025-07-01 17:46:39 -0300 |
commit | 5fc7e375af36e9fea450714731c6e07d033a041a (patch) | |
tree | 8c612084bc84655720bbdc5e67291b9bd2c5c7d7 |
part 2
-rw-r--r-- | go.mod | 5 | ||||
-rw-r--r-- | go.sum | 2 | ||||
-rw-r--r-- | main_server.go | 173 | ||||
-rw-r--r-- | web_server/go.mod | 3 | ||||
-rw-r--r-- | web_server/web_server.go | 47 |
5 files changed, 230 insertions, 0 deletions
@@ -0,0 +1,5 @@ +module main_server.go + +go 1.24.4 + +require github.com/mattn/go-sqlite3 v1.14.28 // indirect @@ -0,0 +1,2 @@ +github.com/mattn/go-sqlite3 v1.14.28 h1:ThEiQrnbtumT+QMknw63Befp/ce/nUPgBPMlRFEum7A= +github.com/mattn/go-sqlite3 v1.14.28/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= diff --git a/main_server.go b/main_server.go new file mode 100644 index 0000000..ea41ce8 --- /dev/null +++ b/main_server.go @@ -0,0 +1,173 @@ +package main + +import ( + "database/sql" + "fmt" + "log" + "crypto/md5" + "strings" + "net" + "encoding/json" + _ "github.com/mattn/go-sqlite3" +) + +type Data struct { + Type int `json:"type"` + URL string `json:"url"` +} + +var DB *sql.DB +func init_DB() { + var err error; + DB, err = sql.Open("sqlite3", "./app.db"); + if err != nil { + log.Fatal(err); + } + + sql_q := ` + CREATE TABLE IF NOT EXISTS urls ( + id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, + url TEXT NOT NULL, + short TEXT NOT NULL UNIQUE + )`; + + _, err = DB.Exec(sql_q); + if err != nil { + log.Fatal(err); + } +} + +var units = [16]string{"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f"}; +func gen_hash(url string) string{ + data := []byte(url); + hash := md5.Sum(data); + var ret string; + for i := 0; i < 3; i++ { + ret = ret + units[hash[i] / 16]; + ret = ret + units[hash[i] % 16]; + } + return ret; +} + +func correct_url(url string) string { + if(len(url) <= 7) { + return "https://" + url; + } + if(url[:8] != "https://") { + return "https://" + url; + } + return url; +} + +func add_url(url string) { + hurl := correct_url(url); + hsh := gen_hash(hurl); + fmt.Printf("adding: %s -> %s \n", hurl, hsh); + _, err := DB.Exec("INSERT INTO urls (url, short) VALUES (?, ?)", hurl, hsh); + if err != nil { + var ok bool; + ok = false; + tmp := strings.Split(err.Error(), " "); + for i := 0; i < len(tmp); i++ { + if tmp[i] == "UNIQUE" { + ok = true; + break; + } + } + if ok{ + fmt.Println("hash ja existe na tabela: Deletando valor antigo..."); + _, err := DB.Exec("DELETE FROM urls WHERE short = ?", hsh); + if err != nil { + log.Fatal(err); + } + + fmt.Println("Adicionando..."); + _, err = DB.Exec("INSERT INTO urls (url, short) VALUES (?, ?)", hurl, hsh); + if err != nil { + log.Fatal(err); + } + }else{ + log.Fatal(err); + } + } +} + +func get_hash_from_db(hash string) string{ + rows, err := DB.Query("SELECT url FROM urls WHERE short = ?", hash); + if err != nil { + log.Fatal(err); + } + defer rows.Close(); + + var url string; + for rows.Next() { + err = rows.Scan(&url); + if err != nil { + log.Fatal(err); + } + fmt.Println(url); + } + return url; +} + +func read_json(cont []byte) (Data, error) { + var data Data; + err := json.Unmarshal(cont, &data); + if err != nil { + return data, err; + } + + return data, nil; +} + +func handle_request(conn net.Conn, data Data) { + if data.Type == 1 { + add_url(data.URL); + }else if data.Type == 2 { + ret := get_hash_from_db(data.URL); + conn.Write([]byte(fmt.Sprintf("%s\n", ret))); + }else { + } +} +func handle_client(conn net.Conn){ + defer conn.Close(); + + buffer := make([]byte, 1024); + for { + n, err := conn.Read(buffer); + if err != nil { + log.Println(err); + return; + } + fmt.Printf("Recebido: %s\n", buffer[:n]); + data, err := read_json(buffer[:n]); + if err != nil { + log.Println(err); + }else { + handle_request(conn, data); + } + } +} + +func main() { + init_DB(); + /*add_url("google.com"); + get_hash_from_db("99999e");*/ + ln, err := net.Listen("tcp", "localhost:5555"); + defer ln.Close(); + fmt.Println("Listen on port 5555"); + if err != nil { + log.Fatal(err); + } + + for { + conn, err := ln.Accept(); + if err != nil { + log.Println(err); + continue; + } + fmt.Println("New connection accepted"); + go handle_client(conn); + + } +} diff --git a/web_server/go.mod b/web_server/go.mod new file mode 100644 index 0000000..88f4151 --- /dev/null +++ b/web_server/go.mod @@ -0,0 +1,3 @@ +module web_server.go + +go 1.24.4 diff --git a/web_server/web_server.go b/web_server/web_server.go new file mode 100644 index 0000000..7f1201c --- /dev/null +++ b/web_server/web_server.go @@ -0,0 +1,47 @@ +package main + +import ( + "fmt" + "log" + "net/http" + "strings" + "net" + "bufio" +) + +func handler(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Cache-Control", "no-cache, no-store, must-revalidate") + w.Header().Set("Expires", "0") + + tmp := strings.Split(r.URL.Path, "/"); + fmt.Println(tmp); + if len(tmp[1]) == 6 { + s := tmp[1]; + fmt.Println(tmp[1]); + conn, err := net.Dial("tcp", "localhost:5555"); + if err != nil { + log.Fatal(err); + } + + fmt.Println(s); + fmt.Fprintf(conn, "{\"type\": 2, \"url\": \"%s\"}", s); + res, _ := bufio.NewReader(conn).ReadBytes('\n'); + fmt.Println(string(res)); + http.Redirect(w, r, string(res), http.StatusPermanentRedirect); + + }else{ + //fmt.Fprintf(w, "oi", r.URL.Path[1:]); + } +} + +func main() { +// page := &Page{Title: "Redirect", Body: []byte("Redirecting...")}; + fmt.Println("Port 5556"); + server := &http.Server{ + Addr: "localhost:5556", + Handler: http.HandlerFunc(handler), + }; + server.SetKeepAlivesEnabled(false); + //http.HandleFunc("/", handler); + log.Fatal(server.ListenAndServe()); +} |