func (site Site) Post(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Content-Type", "application/javascript")
	decoder := json.NewDecoder(r.Body)
	var t shortRequest
	decoder.Decode(&t)
	shortURL, err := site.saveShort(t.URL)
	errMsg := ""
	if err != nil {
		errMsg = err.Error()
	}
	if r.Header.Get("Content-Type") == "application/json" {
		fmt.Fprintf(w, "{\"short\":\"%s\", \"error\":\"%s\"}", shortURL, errMsg)
		return
	}
}
/*
Post Only accepts json data in the following format

{"url": "https://example.org"}

return results is always in the following format:

{"short":"https://short.me/ab", "error":""}

If there was any error short will be empty and error message will show.
package short
import (
	"crypto/md5"
	"encoding/json"
	"errors"
	"fmt"
	"net/http"
	"net/url"
	"os"
	"github.com/asaskevich/govalidator"
	"github.com/garyburd/redigo/redis"
)
type Site struct {
	Host string
	RedisURL string
}
func (site Site) redisURL() string {
	if site.RedisURL != "" {
		return site.RedisURL
	}
	return os.Getenv("REDISURL")
}
func (site Site) redisdb() redis.Conn {
	redisdb, err := redis.DialURL(site.redisURL())
	if err != nil {
		panic(err)
	}
	return redisdb
}
func (site Site) saveShort(url string) (shortest string, err error) {
	if !govalidator.IsURL(url) {
		return "", errors.New("invalid url")
	}
	redisdb := site.redisdb()
	defer redisdb.Close()
	hash := fmt.Sprintf("%x", md5.Sum([]byte(url)))
	similar, _ := redis.String(redisdb.Do("GET", "i:"+hash))
	if similar != "" {
		return site.Host + similar, nil
	}
	for hashShortestLen := 1; hashShortestLen <= 32; hashShortestLen++ {
		s, _ := redisdb.Do("GET", hash[0:hashShortestLen])
		if s == nil {
			shortest = hash[0:hashShortestLen]
			break
		}
	}
	if shortest == "" {
		return "", errors.New("url shortening failed")
	}
	redisdb.Do("SET", shortest, url)
	redisdb.Do("SET", "i:"+hash, shortest)
	return site.Host + shortest, nil
}
type shortRequest struct {
	URL string
}