DarthSim 7 rokov pred
rodič
commit
9ba634fc35

+ 4 - 2
glide.lock

@@ -1,6 +1,8 @@
-hash: 0ef57dd15f41e8f5181f43ff93b7c420e63c8bb2174a8c879ffd56dd98bed659
-updated: 2017-09-27T13:53:20.123821976+06:00
+hash: 60e6c62171c0ccdba698ee1dee438c2215c6a70ba4f9fb1000046265e53370c3
+updated: 2018-03-15T22:32:53.486809+06:00
 imports:
+- name: github.com/matoous/go-nanoid
+  version: 958d370425a1ea42a4dd3c67d15bf02554a16b82
 - name: golang.org/x/image
   version: 334384d9e19178a0488c9360d94d183c1ef0f711
   subpackages:

+ 1 - 0
glide.yaml

@@ -4,3 +4,4 @@ import:
 - package: golang.org/x/net
   subpackages:
   - netutil
+- package: github.com/matoous/go-nanoid

+ 12 - 8
server.go

@@ -12,6 +12,8 @@ import (
 	"strconv"
 	"strings"
 	"time"
+
+	nanoid "github.com/matoous/go-nanoid"
 )
 
 var mimes = map[imageType]string{
@@ -103,7 +105,7 @@ func logResponse(status int, msg string) {
 	log.Printf("|\033[7;%dm %d \033[0m| %s\n", color, status, msg)
 }
 
-func respondWithImage(r *http.Request, rw http.ResponseWriter, data []byte, imgURL string, po processingOptions, duration time.Duration) {
+func respondWithImage(reqID string, r *http.Request, rw http.ResponseWriter, data []byte, imgURL string, po processingOptions, duration time.Duration) {
 	gzipped := strings.Contains(r.Header.Get("Accept-Encoding"), "gzip") && conf.GZipCompression > 0
 
 	rw.Header().Set("Expires", time.Now().Add(time.Second*time.Duration(conf.TTL)).Format(http.TimeFormat))
@@ -124,11 +126,11 @@ func respondWithImage(r *http.Request, rw http.ResponseWriter, data []byte, imgU
 		rw.Write(data)
 	}
 
-	logResponse(200, fmt.Sprintf("Processed in %s: %s; %+v", duration, imgURL, po))
+	logResponse(200, fmt.Sprintf("[%s] Processed in %s: %s; %+v", reqID, duration, imgURL, po))
 }
 
-func respondWithError(rw http.ResponseWriter, err imgproxyError) {
-	logResponse(err.StatusCode, err.Message)
+func respondWithError(reqID string, rw http.ResponseWriter, err imgproxyError) {
+	logResponse(err.StatusCode, fmt.Sprintf("[%s] %s", reqID, err.Message))
 
 	rw.WriteHeader(err.StatusCode)
 	rw.Write([]byte(err.PublicMessage))
@@ -157,14 +159,16 @@ func (h *httpHandler) unlock() {
 }
 
 func (h *httpHandler) ServeHTTP(rw http.ResponseWriter, r *http.Request) {
-	log.Printf("GET: %s\n", r.URL.RequestURI())
+	reqID, _ := nanoid.Nanoid()
+
+	log.Printf("[%s] GET: %s\n", reqID, r.URL.RequestURI())
 
 	defer func() {
 		if r := recover(); r != nil {
 			if err, ok := r.(imgproxyError); ok {
-				respondWithError(rw, err)
+				respondWithError(reqID, rw, err)
 			} else {
-				respondWithError(rw, newUnexpectedError(r.(error), 4))
+				respondWithError(reqID, rw, newUnexpectedError(r.(error), 4))
 			}
 		}
 	}()
@@ -218,5 +222,5 @@ func (h *httpHandler) ServeHTTP(rw http.ResponseWriter, r *http.Request) {
 
 	t.Check()
 
-	respondWithImage(r, rw, b, imgURL, procOpt, t.Since())
+	respondWithImage(reqID, r, rw, b, imgURL, procOpt, t.Since())
 }

+ 1 - 0
vendor/github.com/matoous/go-nanoid/.gitignore

@@ -0,0 +1 @@
+.idea

+ 8 - 0
vendor/github.com/matoous/go-nanoid/.travis.yml

@@ -0,0 +1,8 @@
+language: go
+
+go:
+  - 1.8
+  - 1.9
+  - release
+
+script: go test -v -bench=.

+ 21 - 0
vendor/github.com/matoous/go-nanoid/LICENSE

@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) 2018 Matous Dzivjak <dzivjak@matous.me>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.

+ 50 - 0
vendor/github.com/matoous/go-nanoid/README.md

@@ -0,0 +1,50 @@
+# Go Nanoid
+
+[![Build Status](https://travis-ci.org/matoous/go-nanoid.svg?branch=master)](https://travis-ci.org/matoous/go-nanoid) [![GoDoc](https://godoc.org/github.com/matoous/go-nanoid?status.svg)](https://godoc.org/github.com/matoous/go-nanoid) [![Go Report Card](https://goreportcard.com/badge/github.com/matoous/go-nanoid)](https://goreportcard.com/report/github.com/matoous/go-nanoid) [![GitHub issues](https://img.shields.io/github/issues/matoous/go-nanoid.svg)](https://github.com/matoous/go-nanoid/issues) [![License](https://img.shields.io/badge/license-MIT%20License-blue.svg)](https://github.com/matoous/go-nanoid/LICENSE)
+
+
+This package is Go implementation of [ai's](https://github.com/ai) [nanoid](https://github.com/ai/nanoid)!
+
+**Safe.** It uses cryptographically strong random generator.
+
+**Compact.** It uses more symbols than UUID (`A-Za-z0-9_~`)
+and has the same number of unique options in just 22 symbols instead of 36.
+
+**Fast.** Nanoid is as fast as UUID but can be used in URLs.
+
+## Install
+
+Via go get tool
+
+``` bash
+$ go get github.com/matoous/go-nanoid
+```
+
+## Usage
+
+Generate ID
+
+``` go
+id, err := gonanoid.Nanoid()
+```
+
+## Testing
+
+``` bash
+$ go test -c -i -o /tmp/TestGenerate_in_gonanoid_test_gogo gonanoid
+```
+
+## Notice
+
+If you use Go Nanoid in your project, please let me know!
+
+If you have any issues, just feel free and open it in this repository, thanks!
+
+## Credits
+
+- [ai](https://github.com/ai) - [nanoid](https://github.com/ai/nanoid)
+- icza - his tutorial on [random strings in Go](https://stackoverflow.com/questions/22892120/how-to-generate-a-random-string-of-a-fixed-length-in-golang)
+
+## License
+
+The MIT License (MIT). Please see [License File](LICENSE.md) for more information.

+ 14 - 0
vendor/github.com/matoous/go-nanoid/examples/simple_example.go

@@ -0,0 +1,14 @@
+package main
+
+import (
+	"fmt"
+	"github.com/matoous/go-nanoid"
+)
+
+func main() {
+	id, err := gonanoid.Nanoid()
+	if err != nil {
+		panic(err)
+	}
+	fmt.Printf("Generated default id: %s\n", id)
+}

+ 104 - 0
vendor/github.com/matoous/go-nanoid/gonanoid.go

@@ -0,0 +1,104 @@
+package gonanoid
+
+import (
+	"crypto/rand"
+	"math"
+)
+
+// DefaultsType is the type of the default configuration for Nanoid
+type DefaultsType struct {
+	Alphabet string
+	Size     int
+	MaskSize int
+}
+
+// GetDefaults returns the default configuration for Nanoid
+func GetDefaults() *DefaultsType {
+	return &DefaultsType{
+		Alphabet: "_~0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ", // len=64
+		Size:     22,
+		MaskSize: 5,
+	}
+}
+
+var defaults = GetDefaults()
+
+func initMasks(params ...int) []uint {
+	var size int
+	if len(params) == 0 {
+		size = defaults.MaskSize
+	} else {
+		size = params[0]
+	}
+	masks := make([]uint, size)
+	for i := 0; i < size; i++ {
+		shift := 3 + i
+		masks[i] = (2 << uint(shift)) - 1
+	}
+	return masks
+}
+
+func getMask(alphabet string, masks []uint) int {
+	for i := 0; i < len(masks); i++ {
+		curr := int(masks[i])
+		if curr >= len(alphabet)-1 {
+			return curr
+		}
+	}
+	return 0
+}
+
+// Random generates cryptographically strong pseudo-random data.
+// The size argument is a number indicating the number of bytes to generate.
+func Random(size int) ([]byte, error) {
+	var randomBytes = make([]byte, size)
+	_, err := rand.Read(randomBytes)
+	return randomBytes, err
+}
+
+// Generate is a low-level function to change alphabet and ID size.
+func Generate(alphabet string, size int) (string, error) {
+	masks := initMasks(size)
+	mask := getMask(alphabet, masks)
+	ceilArg := 1.6 * float64(mask*size) / float64(len(alphabet))
+	step := int(math.Ceil(ceilArg))
+
+	id := make([]byte, size)
+	bytes := make([]byte, step)
+	for j := 0; ; {
+		_, err := rand.Read(bytes)
+		if err != nil {
+			return "", err
+		}
+		for i := 0; i < step; i++ {
+			currByte := bytes[i] & byte(mask)
+			if currByte < byte(len(alphabet)) {
+				id[j] = alphabet[currByte]
+				j++
+				if j == size {
+					return string(id[:size]), nil
+				}
+			}
+		}
+	}
+}
+
+// Nanoid generates secure URL-friendly unique ID.
+func Nanoid(param ...int) (string, error) {
+	var size int
+	if len(param) == 0 {
+		size = defaults.Size
+	} else {
+		size = param[0]
+	}
+	bytes := make([]byte, size)
+	_, err := rand.Read(bytes)
+	if err != nil {
+		return "", err
+	}
+	id := make([]byte, size)
+	for i := 0; i < size; i++ {
+		id[i] = defaults.Alphabet[bytes[i]&63]
+	}
+	return string(id[:size]), nil
+}

+ 103 - 0
vendor/github.com/matoous/go-nanoid/gonanoid_test.go

@@ -0,0 +1,103 @@
+package gonanoid
+
+import (
+	"math"
+	"strings"
+	"testing"
+)
+
+var urlLength = len(defaults.Alphabet)
+
+// Test that nanoid generates URL friendly IDs
+// it ('generates URL-friendly IDs')
+func TestGeneratesURLFriendlyIDs(t *testing.T) {
+	for i := 0; i < 10; i++ {
+		id, err := Nanoid()
+		if err != nil {
+			t.Errorf("Nanoid error: %v", err)
+		}
+		if len(id) != defaults.Size {
+			t.Errorf(
+				"TestGeneratesURLFriendlyIDs error: length of id %v should be %v, got %v",
+				id,
+				defaults.Size,
+				id,
+			)
+		}
+
+		runeID := []rune(id)
+
+		for j := 0; j < len(runeID); j++ {
+			res := strings.Contains(defaults.Alphabet, string(runeID[j]))
+			if !res {
+				t.Errorf(
+					"GeneratesURLFriendlyIds error: char %v should be contained in %v",
+					string(runeID[j]),
+					defaults.Alphabet,
+				)
+			}
+		}
+	}
+}
+
+// Test that nanoid has no collisions
+// it ('has no collisions')
+func TestHasNoCollisions(t *testing.T) {
+	COUNT := 100 * 1000
+	used := make(map[string]bool)
+	for i := 0; i < COUNT; i++ {
+		id, err := Nanoid()
+		if err != nil {
+			t.Errorf("Nanoid error: %v", err)
+		}
+		if used[id] {
+			t.Errorf("Collision error! Id %v found for test arr %v", id, used)
+		}
+		used[id] = true
+	}
+}
+
+// Test that Nanoid has flat distribution
+// it ('has flat distribution')
+func TestFlatDistribution(t *testing.T) {
+	COUNT := 100 * 1000
+	instance, err := Nanoid()
+	if err != nil {
+		t.Errorf("Nanoid error: %v", err)
+	}
+	LENGTH := len(instance)
+
+	chars := make(map[byte]int)
+
+	for i := 0; i < COUNT; i++ {
+		id, _ := Nanoid()
+		for j := 0; j < LENGTH; j++ {
+			// https://github.com/ai/nanoid/blob/d6ad3412147fa4c2b0d404841ade245a00c2009f/test/index.test.js#L33
+			// if (!chars[char]) chars[char] = 0 is useless since it
+			// is initialized by default to 0 from Golang
+			chars[id[j]]++
+		}
+	}
+
+	for char, k := range chars {
+		distribution := float64(k) * float64(urlLength) / float64(COUNT*LENGTH)
+		if !toBeCloseTo(distribution, 1, 1) {
+			t.Errorf("Distribution error! Distribution %v found for char %v", distribution, char)
+		}
+	}
+}
+
+// utility that replicates jest.toBeCloseTo
+func toBeCloseTo(value, actual, expected float64) bool {
+	precision := 2
+	// https://github.com/facebook/jest/blob/a397abaf9f08e691f8739899819fc4da41c1e476/packages/expect/src/matchers.js#L83
+	pass := math.Abs(expected-actual) < math.Pow10(-precision)/2
+	return pass
+}
+
+// Benchmark nanoid generator
+func BenchmarkNanoid(b *testing.B) {
+	for n := 0; n < b.N; n++ {
+		Nanoid()
+	}
+}