예제 #1
0
// GetJSResponse response to javascript request, based on the URL and the bookmarklet flag
func (controller *ShawtyJSController) GetJSResponse(url, creatorIP string, bm bool) (res *ResPkg) {
	domain := controller.config["SHAWTY_DOMAIN"]
	limit, _ := strconv.ParseUint(controller.config["SHAWTY_LPM"], 0, 32)

	res = NewResPkg()
	res.Data["Bookmarklet"] = bm
	res.Data["Domain"] = domain
	res.Data["Success"] = 1

	if !urlPattern.MatchString(url) {
		res.Data["Success"] = 0
		res.Errors = append(res.Errors, errors.New("a valid url has to start with http:// or https://"))
		return
	}

	dupDomainPattern := regexp.MustCompile(fmt.Sprintf("^(?i)(https?)://%s.*", domain))
	if dupDomainPattern.MatchString(url) {
		res.Data["Success"] = 0
		res.Errors = append(res.Errors, errors.New("this url is already shortened"))
		return
	}

	shawty, err := controller.sh.GetByUrl(url)

	if err != nil { // need to create
		minuteAgo := time.Unix(time.Now().Unix()-60, 0)
		numLinks, err := controller.sh.NumLinks(creatorIP, minuteAgo)

		if err != nil {
			res.Data["Success"] = 0
			res.Errors = append(res.Errors, errors.New("unknown error occured"))
			log.Errorf("%v", err)
		} else {

			// check for rate limit
			if numLinks >= uint32(limit) {
				res.Data["Success"] = 0
				res.Errors = append(res.Errors, errors.New("you are shortening your links too quickly"))
				log.Errorf("%s has reached the rate limit (%d)", creatorIP, limit)
			} else {
				shawty, err = controller.sh.Create("", url, creatorIP)
				if err != nil {
					res.Data["Success"] = 0
					res.Errors = append(res.Errors, errors.New("cannot shorten this link"))
					log.Errorf("%v", err)
				}
			}
		}
	}

	if res.Data["Success"] == 1 {
		res.Data["Shawty"] = shawty
		res.Data["Short"] = data.ShortID(shawty.ID, shawty.Rand)
	}

	return
}
예제 #2
0
파일: main.go 프로젝트: RickieChang/shawty
func main() {
	runtime.GOMAXPROCS(runtime.NumCPU())

	// read configurations
	confKeys := []string{
		"SHAWTY_PORT", "SHAWTY_DB_TYPE", "SHAWTY_DB", "SHAWTY_DOMAIN",
		"SHAWTY_MODE", "SHAWTY_LPM", "SHAWTY_LOG_DIR",
	}
	config := make(map[string]string)
	for _, k := range confKeys {
		config[k] = os.Getenv(k)
	}

	// setup logger
	log.SetDir(config["SHAWTY_LOG_DIR"])

	// setup data
	random := utils.NewBestRand()
	dbType := strings.ToLower(config["SHAWTY_DB_TYPE"])
	var shawties data.Shawties
	var err error

	if dbType == "pg" || dbType == "postgres" || dbType == "postgresql" {
		shawties, err = data.NewPgSh(random, config["SHAWTY_DB"])
	} else if dbType == "mysql" {
		shawties, err = data.NewMySh(random, config["SHAWTY_DB"])
	} else {
		err = errors.New("Unknown database type. Please check $SHAWTY_DB_TYPE")
	}
	if err != nil {
		log.Error("Cannot create data source")
		log.Error(err)
		return
	}
	defer shawties.Close()

	// register routes
	home := web.NewHomeController(config)
	shawtyjs := web.NewShawtyJSController(config, shawties)
	shortID := web.NewShortIDController(config, shawties)

	// setup HTTP server
	router := mux.NewRouter()
	router.PathPrefix("/static/").Handler(http.StripPrefix("/static/", http.FileServer(http.Dir("static/"))))
	router.Handle("/", home)
	router.Handle("/shawty.js", shawtyjs)
	router.Handle("/{shortID:[A-Za-z0-9]+}", shortID)

	var port = config["SHAWTY_PORT"]
	if port == "" {
		port = "80"
	}

	l, err := net.Listen("tcp", "0.0.0.0:"+port)
	if err != nil {
		log.Errorf("Cannot listen at %s", port)
		fmt.Println(err)
		return
	}
	defer l.Close()

	log.Infof("Listening at %s", port)

	runMode := strings.ToLower(config["SHAWTY_MODE"])

	switch runMode {
	case "fcgi":
		log.Info("Serving FCGI mode")
		fcgi.Serve(l, router)
	default:
		log.Info("Serving HTTP mode")
		http.Serve(l, router)
	}
}