Skip to content

Instantly share code, notes, and snippets.

@anastasop
Created February 24, 2016 20:30
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save anastasop/c99b6ad7f6e7c861dfa5 to your computer and use it in GitHub Desktop.
Save anastasop/c99b6ad7f6e7c861dfa5 to your computer and use it in GitHub Desktop.
A very simple url shortener
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