diff --git a/main.go b/main.go index 05e00b3..4bc7fad 100644 --- a/main.go +++ b/main.go @@ -2,6 +2,13 @@ package main import ( "context" + "log" + "net/http" + "os" + "regexp" + "strings" + "time" + "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promauto" "github.com/prometheus/client_golang/prometheus/promhttp" @@ -10,39 +17,53 @@ import ( "go.mongodb.org/mongo-driver/mongo" "go.mongodb.org/mongo-driver/mongo/options" "go.mongodb.org/mongo-driver/x/mongo/driver/connstring" - "log" - "net/http" - "os" - "regexp" - "strings" - "time" ) type inventoryItemType struct { - ID primitive.ObjectID `bson:"_id" json:"_id,omitempty"` + ID primitive.ObjectID `bson:"_id" json:"_id,omitempty"` Shortener struct { Slug string `bson:"slug" json:"slug"` URL string `bson:"url" json:"url"` } `bson:"shortener" json:"shortener"` } -var reValid = regexp.MustCompile("^[a-zA-Z0-9]{4,6}$") -var mongoURI string = "mongodb://127.0.0.1:27017/default?replicaSet=rs0" -var collectionName string = "inventory" -var redirectFound string = os.Getenv("GOREDIRECT_FOUND") -var redirectNotFound string = os.Getenv("GOREDIRECT_NOT_FOUND") +var ( + mongoURI = "mongodb://127.0.0.1:27017/default?replicaSet=rs0" + mongoCollection = "inventory" +) + +var ( + regexValid = regexp.MustCompile("^[a-zA-Z0-9]{4,6}$") + redirectFound = os.Getenv("GOREDIRECT_FOUND") + redirectNotFound = os.Getenv("GOREDIRECT_NOT_FOUND") + redirectNoPath = os.Getenv("GOREDIRECT_NOPATH") +) func wrapper(coll *mongo.Collection) func(w http.ResponseWriter, r *http.Request) { return func(w http.ResponseWriter, r *http.Request) { counterQueries.Inc() slug := r.URL.Path[1:] - match := reValid.MatchString(slug) - if !match { + + // Prevalidation + + if slug == "" && redirectNoPath != "" { + counterNoPath.Inc() + + log.Printf("Redirecting empty slug to %s\n", redirectNoPath) + http.Redirect(w, r, redirectNoPath, 302) + + return + } + + if match := regexValid.MatchString(slug); !match { counterInvalidSlug.Inc() + http.Error(w, "Invalid slug", 400) return } + // Query + var doc inventoryItemType err := coll.FindOne(context.TODO(), bson.M{"shortener.slug": slug}).Decode(&doc) if err != nil { @@ -57,12 +78,14 @@ func wrapper(coll *mongo.Collection) func(w http.ResponseWriter, r *http.Request } counterFound.Inc() - var u = doc.Shortener.URL - if u == "" { - u = strings.Replace(redirectFound, "%s", doc.ID.Hex(), 1) + + redirURL := doc.Shortener.URL + if redirURL == "" { + redirURL = strings.Replace(redirectFound, "%s", doc.ID.Hex(), 1) } - http.Redirect(w, r, u, 302) - log.Printf("Redirecting %s to %s\n", slug, doc.Shortener.URL) + + http.Redirect(w, r, redirURL, 302) + log.Printf("Redirecting %s to %s\n", slug, redirURL) } } @@ -71,6 +94,10 @@ var ( Name: "goredirect_queries", Help: "The total number of queries.", }) + counterNoPath = promauto.NewCounter(prometheus.CounterOpts{ + Name: "goredirect_not_found", + Help: "The total number of queries with unknown slug.", + }) counterInvalidSlug = promauto.NewCounter(prometheus.CounterOpts{ Name: "goredirect_invalid_slug", Help: "The total number of queries that did not match regex.",