Created
February 24, 2016 20:30
-
-
Save anastasop/c99b6ad7f6e7c861dfa5 to your computer and use it in GitHub Desktop.
A very simple url shortener
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"bufio" | |
"bytes" | |
"crypto/sha1" | |
"flag" | |
"fmt" | |
"io/ioutil" | |
"net/http" | |
"os" | |
"path" | |
"path/filepath" | |
) | |
var cacheDir = flag.String("d", ".", "directory to store files") | |
var addr = flag.String("a", ":8080", "listen address") | |
func filePath(p string) string { | |
cleaned := path.Clean("/" + p) | |
sum := sha1.Sum([]byte(cleaned)) | |
h := fmt.Sprintf("%x", sum[:]) | |
parent := filepath.Join(*cacheDir, h[0:3]) | |
os.Mkdir(parent, 0777) | |
return filepath.Join("/", h[0:3], h[3:]) | |
} | |
func unShorten(w http.ResponseWriter, r *http.Request) { | |
if r.Method != "GET" { | |
http.Error(w, "Accepts only GET", http.StatusMethodNotAllowed) | |
return | |
} | |
pos := filepath.Join(*cacheDir, path.Clean(r.URL.Path)) | |
buf, err := ioutil.ReadFile(pos) | |
if err != nil { | |
http.Error(w, "Not Found", http.StatusNotFound) | |
return | |
} | |
http.Redirect(w, r, string(buf), http.StatusFound) | |
} | |
func shorten(w http.ResponseWriter, r *http.Request) { | |
if r.Method != "POST" { | |
http.Error(w, "Accepts only POST", http.StatusMethodNotAllowed) | |
return | |
} | |
var buf bytes.Buffer | |
defer r.Body.Close() | |
scanner := bufio.NewScanner(r.Body) | |
for scanner.Scan() { | |
line := scanner.Text() | |
p := filePath(line) | |
fmt.Fprintf(&buf, "%s %s\n", line, p) | |
if err := ioutil.WriteFile(filepath.Join(*cacheDir, p), []byte(line), os.ModePerm); err != nil { | |
http.Error(w, "Internal Error", http.StatusInternalServerError) | |
return | |
} | |
} | |
if err := scanner.Err(); err != nil { | |
http.Error(w, "Error Reading input", http.StatusBadRequest) | |
return | |
} | |
w.Write(buf.Bytes()) | |
} | |
func main() { | |
flag.Parse() | |
http.HandleFunc("/", unShorten) | |
http.HandleFunc("/shorten", shorten) | |
http.ListenAndServe(*addr, nil) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment