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(url[:7] == "https:/") { return "https://" + url[7:]; } if(url[:6] == "http:/") { return "http://" + url[:6]; } return "https://" + url; } func add_url(url string) 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); } } return hsh; } 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 { ret := add_url(data.URL); conn.Write([]byte(fmt.Sprintf("%s\n", ret))); }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); } }