├── README.md ├── cache ├── %2FPure%2F22.jpg100x100 └── 22.jpg.pure.600x300 ├── github.com ├── gin-gonic │ └── gin │ │ ├── .gitignore │ │ ├── .travis.yml │ │ ├── AUTHORS.md │ │ ├── BENCHMARKS.md │ │ ├── CHANGELOG.md │ │ ├── Godeps │ │ └── Godeps.json │ │ ├── LICENSE │ │ ├── README.md │ │ ├── auth.go │ │ ├── auth_test.go │ │ ├── benchmarks_test.go │ │ ├── binding │ │ ├── binding.go │ │ ├── binding_test.go │ │ ├── default_validator.go │ │ ├── example │ │ │ ├── test.pb.go │ │ │ └── test.proto │ │ ├── form.go │ │ ├── form_mapping.go │ │ ├── json.go │ │ ├── protobuf.go │ │ ├── validate_test.go │ │ └── xml.go │ │ ├── context.go │ │ ├── context_test.go │ │ ├── debug.go │ │ ├── debug_test.go │ │ ├── deprecated.go │ │ ├── errors.go │ │ ├── errors_test.go │ │ ├── examples │ │ ├── app-engine │ │ │ ├── README.md │ │ │ ├── app.yaml │ │ │ └── hello.go │ │ ├── basic │ │ │ └── main.go │ │ ├── realtime-advanced │ │ │ ├── main.go │ │ │ ├── resources │ │ │ │ ├── room_login.templ.html │ │ │ │ └── static │ │ │ │ │ ├── epoch.min.css │ │ │ │ │ ├── epoch.min.js │ │ │ │ │ ├── prismjs.min.css │ │ │ │ │ ├── prismjs.min.js │ │ │ │ │ └── realtime.js │ │ │ ├── rooms.go │ │ │ ├── routes.go │ │ │ └── stats.go │ │ └── realtime-chat │ │ │ ├── main.go │ │ │ ├── rooms.go │ │ │ └── template.go │ │ ├── fs.go │ │ ├── gin.go │ │ ├── ginS │ │ ├── README.md │ │ └── gins.go │ │ ├── gin_integration_test.go │ │ ├── gin_test.go │ │ ├── githubapi_test.go │ │ ├── logger.go │ │ ├── logger_test.go │ │ ├── logo.jpg │ │ ├── middleware_test.go │ │ ├── mode.go │ │ ├── mode_test.go │ │ ├── path.go │ │ ├── path_test.go │ │ ├── recovery.go │ │ ├── recovery_test.go │ │ ├── render │ │ ├── data.go │ │ ├── html.go │ │ ├── json.go │ │ ├── redirect.go │ │ ├── render.go │ │ ├── render_test.go │ │ ├── text.go │ │ └── xml.go │ │ ├── response_writer.go │ │ ├── response_writer_test.go │ │ ├── routergroup.go │ │ ├── routergroup_test.go │ │ ├── routes_test.go │ │ ├── test_helpers.go │ │ ├── tree.go │ │ ├── tree_test.go │ │ ├── utils.go │ │ ├── utils_test.go │ │ └── wercker.yml ├── go-playground │ └── validator │ │ ├── .gitignore │ │ ├── LICENSE │ │ ├── README.md │ │ ├── baked_in.go │ │ ├── benchmarks_test.go │ │ ├── cache.go │ │ ├── doc.go │ │ ├── examples │ │ ├── custom │ │ │ └── custom.go │ │ ├── simple │ │ │ └── simple.go │ │ └── struct-level │ │ │ └── struct_level.go │ │ ├── examples_test.go │ │ ├── logo.png │ │ ├── regexes.go │ │ ├── util.go │ │ ├── validator.go │ │ └── validator_test.go ├── golang │ ├── image │ │ ├── riff │ │ │ ├── example_test.go │ │ │ ├── riff.go │ │ │ └── riff_test.go │ │ ├── vp8 │ │ │ ├── decode.go │ │ │ ├── filter.go │ │ │ ├── idct.go │ │ │ ├── partition.go │ │ │ ├── pred.go │ │ │ ├── predfunc.go │ │ │ ├── quant.go │ │ │ ├── reconstruct.go │ │ │ └── token.go │ │ ├── vp8l │ │ │ ├── decode.go │ │ │ ├── huffman.go │ │ │ └── transform.go │ │ └── webp │ │ │ ├── decode.go │ │ │ ├── decode_test.go │ │ │ ├── nycbcra │ │ │ └── nycbcra.go │ │ │ └── webp.go │ ├── net │ │ └── context │ │ │ ├── context.go │ │ │ ├── context_test.go │ │ │ ├── ctxhttp │ │ │ ├── cancelreq.go │ │ │ ├── cancelreq_go14.go │ │ │ ├── ctxhttp.go │ │ │ └── ctxhttp_test.go │ │ │ └── withtimeout_test.go │ └── protobuf │ │ ├── .gitignore │ │ ├── AUTHORS │ │ ├── CONTRIBUTORS │ │ ├── LICENSE │ │ ├── Make.protobuf │ │ ├── Makefile │ │ ├── README.md │ │ ├── jsonpb │ │ ├── jsonpb.go │ │ ├── jsonpb_test.go │ │ └── jsonpb_test_proto │ │ │ ├── Makefile │ │ │ ├── more_test_objects.proto │ │ │ └── test_objects.proto │ │ ├── proto │ │ ├── Makefile │ │ ├── all_test.go │ │ ├── clone.go │ │ ├── clone_test.go │ │ ├── decode.go │ │ ├── encode.go │ │ ├── equal.go │ │ ├── equal_test.go │ │ ├── extensions.go │ │ ├── extensions_test.go │ │ ├── lib.go │ │ ├── message_set.go │ │ ├── message_set_test.go │ │ ├── pointer_reflect.go │ │ ├── pointer_unsafe.go │ │ ├── properties.go │ │ ├── proto3_proto │ │ │ └── proto3.proto │ │ ├── proto3_test.go │ │ ├── size2_test.go │ │ ├── size_test.go │ │ ├── testdata │ │ │ ├── Makefile │ │ │ ├── golden_test.go │ │ │ └── test.proto │ │ ├── text.go │ │ ├── text_parser.go │ │ ├── text_parser_test.go │ │ └── text_test.go │ │ └── protoc-gen-go │ │ ├── Makefile │ │ ├── descriptor │ │ └── Makefile │ │ ├── doc.go │ │ ├── generator │ │ ├── Makefile │ │ ├── generator.go │ │ └── name_test.go │ │ ├── internal │ │ └── grpc │ │ │ └── grpc.go │ │ ├── link_grpc.go │ │ ├── main.go │ │ ├── plugin │ │ ├── Makefile │ │ └── plugin.pb.golden │ │ └── testdata │ │ ├── Makefile │ │ ├── extension_base.proto │ │ ├── extension_extra.proto │ │ ├── extension_test.go │ │ ├── extension_user.proto │ │ ├── grpc.proto │ │ ├── imp.pb.go.golden │ │ ├── imp.proto │ │ ├── imp2.proto │ │ ├── imp3.proto │ │ ├── main_test.go │ │ ├── multi │ │ ├── multi1.proto │ │ ├── multi2.proto │ │ └── multi3.proto │ │ ├── my_test │ │ ├── test.pb.go.golden │ │ └── test.proto │ │ └── proto3.proto ├── manucorporat │ └── sse │ │ ├── .travis.yml │ │ ├── LICENSE │ │ ├── README.md │ │ ├── sse-decoder.go │ │ ├── sse-decoder_test.go │ │ ├── sse-encoder.go │ │ ├── sse_test.go │ │ └── writer.go ├── nfnt │ └── resize │ │ ├── .travis.yml │ │ ├── LICENSE │ │ ├── README.md │ │ ├── converter.go │ │ ├── converter_test.go │ │ ├── filters.go │ │ ├── nearest.go │ │ ├── nearest_test.go │ │ ├── resize.go │ │ ├── resize_test.go │ │ ├── thumbnail.go │ │ ├── thumbnail_test.go │ │ ├── ycc.go │ │ └── ycc_test.go └── oliamb │ └── cutter │ ├── .gitignore │ ├── .travis.yml │ ├── LICENSE │ ├── README.md │ ├── benchmark_test.go │ ├── cutter.go │ ├── cutter │ └── main.go │ ├── cutter_test.go │ ├── example_test.go │ └── fixtures │ └── gopher.jpg ├── main.go ├── public └── pure │ └── 22.jpg └── util ├── cache.go ├── common.go ├── conf.go ├── cookie.go ├── crop.go ├── log.go ├── set.go ├── thumbnail.go └── watermark.go /README.md: -------------------------------------------------------------------------------- 1 | # go-thumbnail 2 | #### 功能描述 3 | 1. 非失真缩略图压缩,支持jpg、png、gif、webp格式 4 | 2. 缓存机制 5 | 3. 在线http服务 6 | 7 | #### 引用公共模块 8 | 1. [gin](https://github.com/gin-gonic/gin.git) 9 | 2. [protobuf](https://github.com/golang/protobuf.git) 10 | 3. [sse](https://github.com/manucorporat/sse.git) 11 | 4. [resize](https://github.com/nfnt/resize.git) 12 | 5. [cutter](https://github.com/oliamb/cutter.git) 13 | 6. [context](https://github.com/golang/net.git) 14 | 7. [validator](https://github.com/go-playground/validator.git) 15 | 8. [image](https://github.com/golang/image.git) 16 | 17 | #### 编译方法 18 | **特别注意:因为解码webp依赖go1.6版本库,因此该项目必须是go1.6以上版本才可以编译。** 19 | 20 | 因为外部模块有部分依赖地址无效,因此修改为有效的依赖地址,并且全部整理在该项目中,该项目代码是完整的,不需要重新下载其他代码,直接可以用的。 21 | ```bash 22 | export GOPATH=$PWD 23 | git clone https://github.com/yalay/go-thumbnail.git src 24 | cd src 25 | go build 26 | ``` 27 | 28 | #### 使用方法 29 | ```bash 30 | http://127.0.0.1:6789/pure/22.jpg?s=100x100 31 | ``` 32 | 33 | #### demo演示 34 | - 原始图片 35 | ![原始图片](https://github.com/yalay/go-thumbnail/blob/master/public/pure/22.jpg) 36 | - 缩略图 37 | ![缩略图](https://github.com/yalay/go-thumbnail/blob/master/cache/%252FPure%252F22.jpg100x100) 38 | -------------------------------------------------------------------------------- /cache/%2FPure%2F22.jpg100x100: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yalay/go-thumbnail/4c72c077e1308a1d176cfba1990200b7dc2d7a52/cache/%2FPure%2F22.jpg100x100 -------------------------------------------------------------------------------- /cache/22.jpg.pure.600x300: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yalay/go-thumbnail/4c72c077e1308a1d176cfba1990200b7dc2d7a52/cache/22.jpg.pure.600x300 -------------------------------------------------------------------------------- /github.com/gin-gonic/gin/.gitignore: -------------------------------------------------------------------------------- 1 | Godeps/* 2 | !Godeps/Godeps.json 3 | coverage.out 4 | count.out 5 | -------------------------------------------------------------------------------- /github.com/gin-gonic/gin/.travis.yml: -------------------------------------------------------------------------------- 1 | language: go 2 | sudo: false 3 | go: 4 | - 1.4 5 | - 1.4.2 6 | - tip 7 | 8 | script: 9 | - go get golang.org/x/tools/cmd/cover 10 | - go get github.com/mattn/goveralls 11 | - go test -v -covermode=count -coverprofile=coverage.out 12 | 13 | after_success: 14 | - goveralls -coverprofile=coverage.out -service=travis-ci -repotoken yFj7FrCeddvBzUaaCyG33jCLfWXeb93eA 15 | 16 | notifications: 17 | webhooks: 18 | urls: 19 | - https://webhooks.gitter.im/e/acc2c57482e94b44f557 20 | on_success: change # options: [always|never|change] default: always 21 | on_failure: always # options: [always|never|change] default: always 22 | on_start: false # default: false 23 | -------------------------------------------------------------------------------- /github.com/gin-gonic/gin/Godeps/Godeps.json: -------------------------------------------------------------------------------- 1 | { 2 | "ImportPath": "github.com/gin-gonic/gin", 3 | "GoVersion": "go1.5.1", 4 | "Deps": [ 5 | { 6 | "ImportPath": "github.com/davecgh/go-spew/spew", 7 | "Rev": "5215b55f46b2b919f50a1df0eaa5886afe4e3b3d" 8 | }, 9 | { 10 | "ImportPath": "github.com/golang/protobuf/proto", 11 | "Rev": "2402d76f3d41f928c7902a765dfc872356dd3aad" 12 | }, 13 | { 14 | "ImportPath": "github.com/manucorporat/sse", 15 | "Rev": "ee05b128a739a0fb76c7ebd3ae4810c1de808d6d" 16 | }, 17 | { 18 | "ImportPath": "github.com/pmezard/go-difflib/difflib", 19 | "Rev": "792786c7400a136282c1664665ae0a8db921c6c2" 20 | }, 21 | { 22 | "ImportPath": "github.com/stretchr/testify/assert", 23 | "Comment": "v1.1.3", 24 | "Rev": "f390dcf405f7b83c997eac1b06768bb9f44dec18" 25 | }, 26 | { 27 | "ImportPath": "golang.org/x/net/context", 28 | "Rev": "f315505cf3349909cdf013ea56690da34e96a451" 29 | }, 30 | { 31 | "ImportPath": "gopkg.in/go-playground/validator.v8", 32 | "Comment": "v8.15.1", 33 | "Rev": "c193cecd124b5cc722d7ee5538e945bdb3348435" 34 | } 35 | ] 36 | } 37 | -------------------------------------------------------------------------------- /github.com/gin-gonic/gin/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Manuel Martínez-Almeida 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /github.com/gin-gonic/gin/auth.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 Manu Martinez-Almeida. All rights reserved. 2 | // Use of this source code is governed by a MIT style 3 | // license that can be found in the LICENSE file. 4 | 5 | package gin 6 | 7 | import ( 8 | "crypto/subtle" 9 | "encoding/base64" 10 | "strconv" 11 | ) 12 | 13 | const AuthUserKey = "user" 14 | 15 | type ( 16 | Accounts map[string]string 17 | authPair struct { 18 | Value string 19 | User string 20 | } 21 | authPairs []authPair 22 | ) 23 | 24 | func (a authPairs) searchCredential(authValue string) (string, bool) { 25 | if len(authValue) == 0 { 26 | return "", false 27 | } 28 | for _, pair := range a { 29 | if pair.Value == authValue { 30 | return pair.User, true 31 | } 32 | } 33 | return "", false 34 | } 35 | 36 | // BasicAuthForRealm returns a Basic HTTP Authorization middleware. It takes as arguments a map[string]string where 37 | // the key is the user name and the value is the password, as well as the name of the Realm. 38 | // If the realm is empty, "Authorization Required" will be used by default. 39 | // (see http://tools.ietf.org/html/rfc2617#section-1.2) 40 | func BasicAuthForRealm(accounts Accounts, realm string) HandlerFunc { 41 | if realm == "" { 42 | realm = "Authorization Required" 43 | } 44 | realm = "Basic realm=" + strconv.Quote(realm) 45 | pairs := processAccounts(accounts) 46 | return func(c *Context) { 47 | // Search user in the slice of allowed credentials 48 | user, found := pairs.searchCredential(c.Request.Header.Get("Authorization")) 49 | if !found { 50 | // Credentials doesn't match, we return 401 and abort handlers chain. 51 | c.Header("WWW-Authenticate", realm) 52 | c.AbortWithStatus(401) 53 | } else { 54 | // The user credentials was found, set user's id to key AuthUserKey in this context, the userId can be read later using 55 | // c.MustGet(gin.AuthUserKey) 56 | c.Set(AuthUserKey, user) 57 | } 58 | } 59 | } 60 | 61 | // BasicAuth returns a Basic HTTP Authorization middleware. It takes as argument a map[string]string where 62 | // the key is the user name and the value is the password. 63 | func BasicAuth(accounts Accounts) HandlerFunc { 64 | return BasicAuthForRealm(accounts, "") 65 | } 66 | 67 | func processAccounts(accounts Accounts) authPairs { 68 | assert1(len(accounts) > 0, "Empty list of authorized credentials") 69 | pairs := make(authPairs, 0, len(accounts)) 70 | for user, password := range accounts { 71 | assert1(len(user) > 0, "User can not be empty") 72 | value := authorizationHeader(user, password) 73 | pairs = append(pairs, authPair{ 74 | Value: value, 75 | User: user, 76 | }) 77 | } 78 | return pairs 79 | } 80 | 81 | func authorizationHeader(user, password string) string { 82 | base := user + ":" + password 83 | return "Basic " + base64.StdEncoding.EncodeToString([]byte(base)) 84 | } 85 | 86 | func secureCompare(given, actual string) bool { 87 | if subtle.ConstantTimeEq(int32(len(given)), int32(len(actual))) == 1 { 88 | return subtle.ConstantTimeCompare([]byte(given), []byte(actual)) == 1 89 | } 90 | /* Securely compare actual to itself to keep constant time, but always return false */ 91 | return subtle.ConstantTimeCompare([]byte(actual), []byte(actual)) == 1 && false 92 | } 93 | -------------------------------------------------------------------------------- /github.com/gin-gonic/gin/binding/binding.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 Manu Martinez-Almeida. All rights reserved. 2 | // Use of this source code is governed by a MIT style 3 | // license that can be found in the LICENSE file. 4 | 5 | package binding 6 | 7 | import "net/http" 8 | 9 | const ( 10 | MIMEJSON = "application/json" 11 | MIMEHTML = "text/html" 12 | MIMEXML = "application/xml" 13 | MIMEXML2 = "text/xml" 14 | MIMEPlain = "text/plain" 15 | MIMEPOSTForm = "application/x-www-form-urlencoded" 16 | MIMEMultipartPOSTForm = "multipart/form-data" 17 | MIMEPROTOBUF = "application/x-protobuf" 18 | ) 19 | 20 | type Binding interface { 21 | Name() string 22 | Bind(*http.Request, interface{}) error 23 | } 24 | 25 | type StructValidator interface { 26 | // ValidateStruct can receive any kind of type and it should never panic, even if the configuration is not right. 27 | // If the received type is not a struct, any validation should be skipped and nil must be returned. 28 | // If the received type is a struct or pointer to a struct, the validation should be performed. 29 | // If the struct is not valid or the validation itself fails, a descriptive error should be returned. 30 | // Otherwise nil must be returned. 31 | ValidateStruct(interface{}) error 32 | } 33 | 34 | var Validator StructValidator = &defaultValidator{} 35 | 36 | var ( 37 | JSON = jsonBinding{} 38 | XML = xmlBinding{} 39 | Form = formBinding{} 40 | FormPost = formPostBinding{} 41 | FormMultipart = formMultipartBinding{} 42 | ProtoBuf = protobufBinding{} 43 | ) 44 | 45 | func Default(method, contentType string) Binding { 46 | if method == "GET" { 47 | return Form 48 | } else { 49 | switch contentType { 50 | case MIMEJSON: 51 | return JSON 52 | case MIMEXML, MIMEXML2: 53 | return XML 54 | case MIMEPROTOBUF: 55 | return ProtoBuf 56 | default: //case MIMEPOSTForm, MIMEMultipartPOSTForm: 57 | return Form 58 | } 59 | } 60 | } 61 | 62 | func validate(obj interface{}) error { 63 | if Validator == nil { 64 | return nil 65 | } 66 | return Validator.ValidateStruct(obj) 67 | } 68 | -------------------------------------------------------------------------------- /github.com/gin-gonic/gin/binding/default_validator.go: -------------------------------------------------------------------------------- 1 | package binding 2 | 3 | import ( 4 | "reflect" 5 | "sync" 6 | 7 | "github.com/go-playground/validator" 8 | ) 9 | 10 | type defaultValidator struct { 11 | once sync.Once 12 | validate *validator.Validate 13 | } 14 | 15 | var _ StructValidator = &defaultValidator{} 16 | 17 | func (v *defaultValidator) ValidateStruct(obj interface{}) error { 18 | if kindOfData(obj) == reflect.Struct { 19 | v.lazyinit() 20 | if err := v.validate.Struct(obj); err != nil { 21 | return error(err) 22 | } 23 | } 24 | return nil 25 | } 26 | 27 | func (v *defaultValidator) lazyinit() { 28 | v.once.Do(func() { 29 | config := &validator.Config{TagName: "binding"} 30 | v.validate = validator.New(config) 31 | }) 32 | } 33 | 34 | func kindOfData(data interface{}) reflect.Kind { 35 | value := reflect.ValueOf(data) 36 | valueType := value.Kind() 37 | if valueType == reflect.Ptr { 38 | valueType = value.Elem().Kind() 39 | } 40 | return valueType 41 | } 42 | -------------------------------------------------------------------------------- /github.com/gin-gonic/gin/binding/example/test.pb.go: -------------------------------------------------------------------------------- 1 | // Code generated by protoc-gen-go. 2 | // source: test.proto 3 | // DO NOT EDIT! 4 | 5 | /* 6 | Package example is a generated protocol buffer package. 7 | 8 | It is generated from these files: 9 | test.proto 10 | 11 | It has these top-level messages: 12 | Test 13 | */ 14 | package example 15 | 16 | import proto "github.com/golang/protobuf/proto" 17 | import math "math" 18 | 19 | // Reference imports to suppress errors if they are not otherwise used. 20 | var _ = proto.Marshal 21 | var _ = math.Inf 22 | 23 | type FOO int32 24 | 25 | const ( 26 | FOO_X FOO = 17 27 | ) 28 | 29 | var FOO_name = map[int32]string{ 30 | 17: "X", 31 | } 32 | var FOO_value = map[string]int32{ 33 | "X": 17, 34 | } 35 | 36 | func (x FOO) Enum() *FOO { 37 | p := new(FOO) 38 | *p = x 39 | return p 40 | } 41 | func (x FOO) String() string { 42 | return proto.EnumName(FOO_name, int32(x)) 43 | } 44 | func (x *FOO) UnmarshalJSON(data []byte) error { 45 | value, err := proto.UnmarshalJSONEnum(FOO_value, data, "FOO") 46 | if err != nil { 47 | return err 48 | } 49 | *x = FOO(value) 50 | return nil 51 | } 52 | 53 | type Test struct { 54 | Label *string `protobuf:"bytes,1,req,name=label" json:"label,omitempty"` 55 | Type *int32 `protobuf:"varint,2,opt,name=type,def=77" json:"type,omitempty"` 56 | Reps []int64 `protobuf:"varint,3,rep,name=reps" json:"reps,omitempty"` 57 | Optionalgroup *Test_OptionalGroup `protobuf:"group,4,opt,name=OptionalGroup" json:"optionalgroup,omitempty"` 58 | XXX_unrecognized []byte `json:"-"` 59 | } 60 | 61 | func (m *Test) Reset() { *m = Test{} } 62 | func (m *Test) String() string { return proto.CompactTextString(m) } 63 | func (*Test) ProtoMessage() {} 64 | 65 | const Default_Test_Type int32 = 77 66 | 67 | func (m *Test) GetLabel() string { 68 | if m != nil && m.Label != nil { 69 | return *m.Label 70 | } 71 | return "" 72 | } 73 | 74 | func (m *Test) GetType() int32 { 75 | if m != nil && m.Type != nil { 76 | return *m.Type 77 | } 78 | return Default_Test_Type 79 | } 80 | 81 | func (m *Test) GetReps() []int64 { 82 | if m != nil { 83 | return m.Reps 84 | } 85 | return nil 86 | } 87 | 88 | func (m *Test) GetOptionalgroup() *Test_OptionalGroup { 89 | if m != nil { 90 | return m.Optionalgroup 91 | } 92 | return nil 93 | } 94 | 95 | type Test_OptionalGroup struct { 96 | RequiredField *string `protobuf:"bytes,5,req" json:"RequiredField,omitempty"` 97 | XXX_unrecognized []byte `json:"-"` 98 | } 99 | 100 | func (m *Test_OptionalGroup) Reset() { *m = Test_OptionalGroup{} } 101 | func (m *Test_OptionalGroup) String() string { return proto.CompactTextString(m) } 102 | func (*Test_OptionalGroup) ProtoMessage() {} 103 | 104 | func (m *Test_OptionalGroup) GetRequiredField() string { 105 | if m != nil && m.RequiredField != nil { 106 | return *m.RequiredField 107 | } 108 | return "" 109 | } 110 | 111 | func init() { 112 | proto.RegisterEnum("example.FOO", FOO_name, FOO_value) 113 | } 114 | -------------------------------------------------------------------------------- /github.com/gin-gonic/gin/binding/example/test.proto: -------------------------------------------------------------------------------- 1 | package example; 2 | 3 | enum FOO {X=17;}; 4 | 5 | message Test { 6 | required string label = 1; 7 | optional int32 type = 2[default=77]; 8 | repeated int64 reps = 3; 9 | optional group OptionalGroup = 4{ 10 | required string RequiredField = 5; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /github.com/gin-gonic/gin/binding/form.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 Manu Martinez-Almeida. All rights reserved. 2 | // Use of this source code is governed by a MIT style 3 | // license that can be found in the LICENSE file. 4 | 5 | package binding 6 | 7 | import "net/http" 8 | 9 | type formBinding struct{} 10 | type formPostBinding struct{} 11 | type formMultipartBinding struct{} 12 | 13 | func (formBinding) Name() string { 14 | return "form" 15 | } 16 | 17 | func (formBinding) Bind(req *http.Request, obj interface{}) error { 18 | if err := req.ParseForm(); err != nil { 19 | return err 20 | } 21 | req.ParseMultipartForm(32 << 10) // 32 MB 22 | if err := mapForm(obj, req.Form); err != nil { 23 | return err 24 | } 25 | return validate(obj) 26 | } 27 | 28 | func (formPostBinding) Name() string { 29 | return "form-urlencoded" 30 | } 31 | 32 | func (formPostBinding) Bind(req *http.Request, obj interface{}) error { 33 | if err := req.ParseForm(); err != nil { 34 | return err 35 | } 36 | if err := mapForm(obj, req.PostForm); err != nil { 37 | return err 38 | } 39 | return validate(obj) 40 | } 41 | 42 | func (formMultipartBinding) Name() string { 43 | return "multipart/form-data" 44 | } 45 | 46 | func (formMultipartBinding) Bind(req *http.Request, obj interface{}) error { 47 | if err := req.ParseMultipartForm(32 << 10); err != nil { 48 | return err 49 | } 50 | if err := mapForm(obj, req.MultipartForm.Value); err != nil { 51 | return err 52 | } 53 | return validate(obj) 54 | } 55 | -------------------------------------------------------------------------------- /github.com/gin-gonic/gin/binding/json.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 Manu Martinez-Almeida. All rights reserved. 2 | // Use of this source code is governed by a MIT style 3 | // license that can be found in the LICENSE file. 4 | 5 | package binding 6 | 7 | import ( 8 | "encoding/json" 9 | 10 | "net/http" 11 | ) 12 | 13 | type jsonBinding struct{} 14 | 15 | func (jsonBinding) Name() string { 16 | return "json" 17 | } 18 | 19 | func (jsonBinding) Bind(req *http.Request, obj interface{}) error { 20 | decoder := json.NewDecoder(req.Body) 21 | if err := decoder.Decode(obj); err != nil { 22 | return err 23 | } 24 | return validate(obj) 25 | } 26 | -------------------------------------------------------------------------------- /github.com/gin-gonic/gin/binding/protobuf.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 Manu Martinez-Almeida. All rights reserved. 2 | // Use of this source code is governed by a MIT style 3 | // license that can be found in the LICENSE file. 4 | 5 | package binding 6 | 7 | import ( 8 | "github.com/golang/protobuf/proto" 9 | 10 | "io/ioutil" 11 | "net/http" 12 | ) 13 | 14 | type protobufBinding struct{} 15 | 16 | func (_ protobufBinding) Name() string { 17 | return "protobuf" 18 | } 19 | 20 | func (_ protobufBinding) Bind(req *http.Request, obj interface{}) error { 21 | 22 | buf, err := ioutil.ReadAll(req.Body) 23 | if err != nil { 24 | return err 25 | } 26 | 27 | if err = proto.Unmarshal(buf, obj.(proto.Message)); err != nil { 28 | return err 29 | } 30 | 31 | //Here it's same to return validate(obj), but util now we cann't add `binding:""` to the struct 32 | //which automatically generate by gen-proto 33 | return nil 34 | //return validate(obj) 35 | } 36 | -------------------------------------------------------------------------------- /github.com/gin-gonic/gin/binding/xml.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 Manu Martinez-Almeida. All rights reserved. 2 | // Use of this source code is governed by a MIT style 3 | // license that can be found in the LICENSE file. 4 | 5 | package binding 6 | 7 | import ( 8 | "encoding/xml" 9 | "net/http" 10 | ) 11 | 12 | type xmlBinding struct{} 13 | 14 | func (xmlBinding) Name() string { 15 | return "xml" 16 | } 17 | 18 | func (xmlBinding) Bind(req *http.Request, obj interface{}) error { 19 | decoder := xml.NewDecoder(req.Body) 20 | if err := decoder.Decode(obj); err != nil { 21 | return err 22 | } 23 | return validate(obj) 24 | } 25 | -------------------------------------------------------------------------------- /github.com/gin-gonic/gin/debug.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 Manu Martinez-Almeida. All rights reserved. 2 | // Use of this source code is governed by a MIT style 3 | // license that can be found in the LICENSE file. 4 | 5 | package gin 6 | 7 | import ( 8 | "bytes" 9 | "html/template" 10 | "log" 11 | ) 12 | 13 | func init() { 14 | log.SetFlags(0) 15 | } 16 | 17 | // IsDebugging returns true if the framework is running in debug mode. 18 | // Use SetMode(gin.Release) to switch to disable the debug mode. 19 | func IsDebugging() bool { 20 | return ginMode == debugCode 21 | } 22 | 23 | func debugPrintRoute(httpMethod, absolutePath string, handlers HandlersChain) { 24 | if IsDebugging() { 25 | nuHandlers := len(handlers) 26 | handlerName := nameOfFunction(handlers.Last()) 27 | debugPrint("%-6s %-25s --> %s (%d handlers)\n", httpMethod, absolutePath, handlerName, nuHandlers) 28 | } 29 | } 30 | 31 | func debugPrintLoadTemplate(tmpl *template.Template) { 32 | if IsDebugging() { 33 | var buf bytes.Buffer 34 | for _, tmpl := range tmpl.Templates() { 35 | buf.WriteString("\t- ") 36 | buf.WriteString(tmpl.Name()) 37 | buf.WriteString("\n") 38 | } 39 | debugPrint("Loaded HTML Templates (%d): \n%s\n", len(tmpl.Templates()), buf.String()) 40 | } 41 | } 42 | 43 | func debugPrint(format string, values ...interface{}) { 44 | if IsDebugging() { 45 | log.Printf("[GIN-debug] "+format, values...) 46 | } 47 | } 48 | 49 | func debugPrintWARNINGNew() { 50 | debugPrint(`[WARNING] Running in "debug" mode. Switch to "release" mode in production. 51 | - using env: export GIN_MODE=release 52 | - using code: gin.SetMode(gin.ReleaseMode) 53 | 54 | `) 55 | } 56 | 57 | func debugPrintWARNINGSetHTMLTemplate() { 58 | debugPrint(`[WARNING] Since SetHTMLTemplate() is NOT thread-safe. It should only be called 59 | at initialization. ie. before any route is registered or the router is listening in a socket: 60 | 61 | router := gin.Default() 62 | router.SetHTMLTemplate(template) // << good place 63 | 64 | `) 65 | } 66 | 67 | func debugPrintError(err error) { 68 | if err != nil { 69 | debugPrint("[ERROR] %v\n", err) 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /github.com/gin-gonic/gin/debug_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 Manu Martinez-Almeida. All rights reserved. 2 | // Use of this source code is governed by a MIT style 3 | // license that can be found in the LICENSE file. 4 | 5 | package gin 6 | 7 | import ( 8 | "bytes" 9 | "errors" 10 | "io" 11 | "log" 12 | "os" 13 | "testing" 14 | 15 | "github.com/stretchr/testify/assert" 16 | ) 17 | 18 | // TODO 19 | // func debugRoute(httpMethod, absolutePath string, handlers HandlersChain) { 20 | // func debugPrint(format string, values ...interface{}) { 21 | 22 | func TestIsDebugging(t *testing.T) { 23 | SetMode(DebugMode) 24 | assert.True(t, IsDebugging()) 25 | SetMode(ReleaseMode) 26 | assert.False(t, IsDebugging()) 27 | SetMode(TestMode) 28 | assert.False(t, IsDebugging()) 29 | } 30 | 31 | func TestDebugPrint(t *testing.T) { 32 | var w bytes.Buffer 33 | setup(&w) 34 | defer teardown() 35 | 36 | SetMode(ReleaseMode) 37 | debugPrint("DEBUG this!") 38 | SetMode(TestMode) 39 | debugPrint("DEBUG this!") 40 | assert.Empty(t, w.String()) 41 | 42 | SetMode(DebugMode) 43 | debugPrint("these are %d %s\n", 2, "error messages") 44 | assert.Equal(t, w.String(), "[GIN-debug] these are 2 error messages\n") 45 | } 46 | 47 | func TestDebugPrintError(t *testing.T) { 48 | var w bytes.Buffer 49 | setup(&w) 50 | defer teardown() 51 | 52 | SetMode(DebugMode) 53 | debugPrintError(nil) 54 | assert.Empty(t, w.String()) 55 | 56 | debugPrintError(errors.New("this is an error")) 57 | assert.Equal(t, w.String(), "[GIN-debug] [ERROR] this is an error\n") 58 | } 59 | 60 | func TestDebugPrintRoutes(t *testing.T) { 61 | var w bytes.Buffer 62 | setup(&w) 63 | defer teardown() 64 | 65 | debugPrintRoute("GET", "/path/to/route/:param", HandlersChain{func(c *Context) {}, handlerNameTest}) 66 | assert.Regexp(t, `^\[GIN-debug\] GET /path/to/route/:param --> (.*/vendor/)?github.com/gin-gonic/gin.handlerNameTest \(2 handlers\)\n$`, w.String()) 67 | } 68 | 69 | func setup(w io.Writer) { 70 | SetMode(DebugMode) 71 | log.SetOutput(w) 72 | } 73 | 74 | func teardown() { 75 | SetMode(TestMode) 76 | log.SetOutput(os.Stdout) 77 | } 78 | -------------------------------------------------------------------------------- /github.com/gin-gonic/gin/deprecated.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 Manu Martinez-Almeida. All rights reserved. 2 | // Use of this source code is governed by a MIT style 3 | // license that can be found in the LICENSE file. 4 | 5 | package gin 6 | 7 | import "log" 8 | 9 | func (c *Context) GetCookie(name string) (string, error) { 10 | log.Println("GetCookie() method is deprecated. Use Cookie() instead.") 11 | return c.Cookie(name) 12 | } 13 | -------------------------------------------------------------------------------- /github.com/gin-gonic/gin/errors_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 Manu Martinez-Almeida. All rights reserved. 2 | // Use of this source code is governed by a MIT style 3 | // license that can be found in the LICENSE file. 4 | 5 | package gin 6 | 7 | import ( 8 | "encoding/json" 9 | "errors" 10 | "testing" 11 | 12 | "github.com/stretchr/testify/assert" 13 | ) 14 | 15 | func TestError(t *testing.T) { 16 | baseError := errors.New("test error") 17 | err := &Error{ 18 | Err: baseError, 19 | Type: ErrorTypePrivate, 20 | } 21 | assert.Equal(t, err.Error(), baseError.Error()) 22 | assert.Equal(t, err.JSON(), H{"error": baseError.Error()}) 23 | 24 | assert.Equal(t, err.SetType(ErrorTypePublic), err) 25 | assert.Equal(t, err.Type, ErrorTypePublic) 26 | 27 | assert.Equal(t, err.SetMeta("some data"), err) 28 | assert.Equal(t, err.Meta, "some data") 29 | assert.Equal(t, err.JSON(), H{ 30 | "error": baseError.Error(), 31 | "meta": "some data", 32 | }) 33 | 34 | jsonBytes, _ := json.Marshal(err) 35 | assert.Equal(t, string(jsonBytes), "{\"error\":\"test error\",\"meta\":\"some data\"}") 36 | 37 | err.SetMeta(H{ 38 | "status": "200", 39 | "data": "some data", 40 | }) 41 | assert.Equal(t, err.JSON(), H{ 42 | "error": baseError.Error(), 43 | "status": "200", 44 | "data": "some data", 45 | }) 46 | 47 | err.SetMeta(H{ 48 | "error": "custom error", 49 | "status": "200", 50 | "data": "some data", 51 | }) 52 | assert.Equal(t, err.JSON(), H{ 53 | "error": "custom error", 54 | "status": "200", 55 | "data": "some data", 56 | }) 57 | } 58 | 59 | func TestErrorSlice(t *testing.T) { 60 | errs := errorMsgs{ 61 | {Err: errors.New("first"), Type: ErrorTypePrivate}, 62 | {Err: errors.New("second"), Type: ErrorTypePrivate, Meta: "some data"}, 63 | {Err: errors.New("third"), Type: ErrorTypePublic, Meta: H{"status": "400"}}, 64 | } 65 | 66 | assert.Equal(t, errs, errs.ByType(ErrorTypeAny)) 67 | assert.Equal(t, errs.Last().Error(), "third") 68 | assert.Equal(t, errs.Errors(), []string{"first", "second", "third"}) 69 | assert.Equal(t, errs.ByType(ErrorTypePublic).Errors(), []string{"third"}) 70 | assert.Equal(t, errs.ByType(ErrorTypePrivate).Errors(), []string{"first", "second"}) 71 | assert.Equal(t, errs.ByType(ErrorTypePublic|ErrorTypePrivate).Errors(), []string{"first", "second", "third"}) 72 | assert.Empty(t, errs.ByType(ErrorTypeBind)) 73 | assert.Empty(t, errs.ByType(ErrorTypeBind).String()) 74 | 75 | assert.Equal(t, errs.String(), `Error #01: first 76 | Error #02: second 77 | Meta: some data 78 | Error #03: third 79 | Meta: map[status:400] 80 | `) 81 | assert.Equal(t, errs.JSON(), []interface{}{ 82 | H{"error": "first"}, 83 | H{"error": "second", "meta": "some data"}, 84 | H{"error": "third", "status": "400"}, 85 | }) 86 | jsonBytes, _ := json.Marshal(errs) 87 | assert.Equal(t, string(jsonBytes), "[{\"error\":\"first\"},{\"error\":\"second\",\"meta\":\"some data\"},{\"error\":\"third\",\"status\":\"400\"}]") 88 | errs = errorMsgs{ 89 | {Err: errors.New("first"), Type: ErrorTypePrivate}, 90 | } 91 | assert.Equal(t, errs.JSON(), H{"error": "first"}) 92 | jsonBytes, _ = json.Marshal(errs) 93 | assert.Equal(t, string(jsonBytes), "{\"error\":\"first\"}") 94 | 95 | errs = errorMsgs{} 96 | assert.Nil(t, errs.Last()) 97 | assert.Nil(t, errs.JSON()) 98 | assert.Empty(t, errs.String()) 99 | } 100 | -------------------------------------------------------------------------------- /github.com/gin-gonic/gin/examples/app-engine/README.md: -------------------------------------------------------------------------------- 1 | # Guide to run Gin under App Engine LOCAL Development Server 2 | 3 | 1. Download, install and setup Go in your computer. (That includes setting your `$GOPATH`.) 4 | 2. Download SDK for your platform from here: `https://developers.google.com/appengine/downloads?hl=es#Google_App_Engine_SDK_for_Go` 5 | 3. Download Gin source code using: `$ go get github.com/gin-gonic/gin` 6 | 4. Navigate to examples folder: `$ cd $GOPATH/src/github.com/gin-gonic/gin/examples/` 7 | 5. Run it: `$ goapp serve app-engine/` -------------------------------------------------------------------------------- /github.com/gin-gonic/gin/examples/app-engine/app.yaml: -------------------------------------------------------------------------------- 1 | application: hello 2 | version: 1 3 | runtime: go 4 | api_version: go1 5 | 6 | handlers: 7 | - url: /.* 8 | script: _go_app -------------------------------------------------------------------------------- /github.com/gin-gonic/gin/examples/app-engine/hello.go: -------------------------------------------------------------------------------- 1 | package hello 2 | 3 | import ( 4 | "net/http" 5 | "github.com/gin-gonic/gin" 6 | ) 7 | 8 | // This function's name is a must. App Engine uses it to drive the requests properly. 9 | func init() { 10 | // Starts a new Gin instance with no middle-ware 11 | r := gin.New() 12 | 13 | // Define your handlers 14 | r.GET("/", func(c *gin.Context){ 15 | c.String(200, "Hello World!") 16 | }) 17 | r.GET("/ping", func(c *gin.Context){ 18 | c.String(200, "pong") 19 | }) 20 | 21 | // Handle all requests using net/http 22 | http.Handle("/", r) 23 | } -------------------------------------------------------------------------------- /github.com/gin-gonic/gin/examples/basic/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "github.com/gin-gonic/gin" 5 | ) 6 | 7 | var DB = make(map[string]string) 8 | 9 | func main() { 10 | r := gin.Default() 11 | 12 | // Ping test 13 | r.GET("/ping", func(c *gin.Context) { 14 | c.String(200, "pong") 15 | }) 16 | 17 | // Get user value 18 | r.GET("/user/:name", func(c *gin.Context) { 19 | user := c.Params.ByName("name") 20 | value, ok := DB[user] 21 | if ok { 22 | c.JSON(200, gin.H{"user": user, "value": value}) 23 | } else { 24 | c.JSON(200, gin.H{"user": user, "status": "no value"}) 25 | } 26 | }) 27 | 28 | // Authorized group (uses gin.BasicAuth() middleware) 29 | // Same than: 30 | // authorized := r.Group("/") 31 | // authorized.Use(gin.BasicAuth(gin.Credentials{ 32 | // "foo": "bar", 33 | // "manu": "123", 34 | //})) 35 | authorized := r.Group("/", gin.BasicAuth(gin.Accounts{ 36 | "foo": "bar", // user:foo password:bar 37 | "manu": "123", // user:manu password:123 38 | })) 39 | 40 | authorized.POST("admin", func(c *gin.Context) { 41 | user := c.MustGet(gin.AuthUserKey).(string) 42 | 43 | // Parse JSON 44 | var json struct { 45 | Value string `json:"value" binding:"required"` 46 | } 47 | 48 | if c.Bind(&json) == nil { 49 | DB[user] = json.Value 50 | c.JSON(200, gin.H{"status": "ok"}) 51 | } 52 | }) 53 | 54 | // Listen and Server in 0.0.0.0:8080 55 | r.Run(":8080") 56 | } 57 | -------------------------------------------------------------------------------- /github.com/gin-gonic/gin/examples/realtime-advanced/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "runtime" 6 | 7 | "github.com/gin-gonic/gin" 8 | ) 9 | 10 | func main() { 11 | ConfigRuntime() 12 | StartWorkers() 13 | StartGin() 14 | } 15 | 16 | func ConfigRuntime() { 17 | nuCPU := runtime.NumCPU() 18 | runtime.GOMAXPROCS(nuCPU) 19 | fmt.Printf("Running with %d CPUs\n", nuCPU) 20 | } 21 | 22 | func StartWorkers() { 23 | go statsWorker() 24 | } 25 | 26 | func StartGin() { 27 | gin.SetMode(gin.ReleaseMode) 28 | 29 | router := gin.New() 30 | router.Use(rateLimit, gin.Recovery()) 31 | router.LoadHTMLGlob("resources/*.templ.html") 32 | router.Static("/static", "resources/static") 33 | router.GET("/", index) 34 | router.GET("/room/:roomid", roomGET) 35 | router.POST("/room-post/:roomid", roomPOST) 36 | router.GET("/stream/:roomid", streamRoom) 37 | 38 | router.Run(":80") 39 | } 40 | -------------------------------------------------------------------------------- /github.com/gin-gonic/gin/examples/realtime-advanced/resources/static/prismjs.min.css: -------------------------------------------------------------------------------- 1 | /* http://prismjs.com/download.html?themes=prism&languages=clike+javascript+go */ 2 | /** 3 | * prism.js default theme for JavaScript, CSS and HTML 4 | * Based on dabblet (http://dabblet.com) 5 | * @author Lea Verou 6 | */ 7 | 8 | code[class*="language-"], 9 | pre[class*="language-"] { 10 | color: black; 11 | text-shadow: 0 1px white; 12 | font-family: Consolas, Monaco, 'Andale Mono', monospace; 13 | direction: ltr; 14 | text-align: left; 15 | white-space: pre; 16 | word-spacing: normal; 17 | word-break: normal; 18 | line-height: 1.5; 19 | 20 | -moz-tab-size: 4; 21 | -o-tab-size: 4; 22 | tab-size: 4; 23 | 24 | -webkit-hyphens: none; 25 | -moz-hyphens: none; 26 | -ms-hyphens: none; 27 | hyphens: none; 28 | } 29 | 30 | pre[class*="language-"]::-moz-selection, pre[class*="language-"] ::-moz-selection, 31 | code[class*="language-"]::-moz-selection, code[class*="language-"] ::-moz-selection { 32 | text-shadow: none; 33 | background: #b3d4fc; 34 | } 35 | 36 | pre[class*="language-"]::selection, pre[class*="language-"] ::selection, 37 | code[class*="language-"]::selection, code[class*="language-"] ::selection { 38 | text-shadow: none; 39 | background: #b3d4fc; 40 | } 41 | 42 | @media print { 43 | code[class*="language-"], 44 | pre[class*="language-"] { 45 | text-shadow: none; 46 | } 47 | } 48 | 49 | /* Code blocks */ 50 | pre[class*="language-"] { 51 | padding: 1em; 52 | margin: .5em 0; 53 | overflow: auto; 54 | } 55 | 56 | :not(pre) > code[class*="language-"], 57 | pre[class*="language-"] { 58 | background: #f5f2f0; 59 | } 60 | 61 | /* Inline code */ 62 | :not(pre) > code[class*="language-"] { 63 | padding: .1em; 64 | border-radius: .3em; 65 | } 66 | 67 | .token.comment, 68 | .token.prolog, 69 | .token.doctype, 70 | .token.cdata { 71 | color: slategray; 72 | } 73 | 74 | .token.punctuation { 75 | color: #999; 76 | } 77 | 78 | .namespace { 79 | opacity: .7; 80 | } 81 | 82 | .token.property, 83 | .token.tag, 84 | .token.boolean, 85 | .token.number, 86 | .token.constant, 87 | .token.symbol, 88 | .token.deleted { 89 | color: #905; 90 | } 91 | 92 | .token.selector, 93 | .token.attr-name, 94 | .token.string, 95 | .token.char, 96 | .token.builtin, 97 | .token.inserted { 98 | color: #690; 99 | } 100 | 101 | .token.operator, 102 | .token.entity, 103 | .token.url, 104 | .language-css .token.string, 105 | .style .token.string { 106 | color: #a67f59; 107 | background: hsla(0, 0%, 100%, .5); 108 | } 109 | 110 | .token.atrule, 111 | .token.attr-value, 112 | .token.keyword { 113 | color: #07a; 114 | } 115 | 116 | .token.function { 117 | color: #DD4A68; 118 | } 119 | 120 | .token.regex, 121 | .token.important, 122 | .token.variable { 123 | color: #e90; 124 | } 125 | 126 | .token.important, 127 | .token.bold { 128 | font-weight: bold; 129 | } 130 | .token.italic { 131 | font-style: italic; 132 | } 133 | 134 | .token.entity { 135 | cursor: help; 136 | } 137 | 138 | -------------------------------------------------------------------------------- /github.com/gin-gonic/gin/examples/realtime-advanced/rooms.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "github.com/dustin/go-broadcast" 4 | 5 | var roomChannels = make(map[string]broadcast.Broadcaster) 6 | 7 | func openListener(roomid string) chan interface{} { 8 | listener := make(chan interface{}) 9 | room(roomid).Register(listener) 10 | return listener 11 | } 12 | 13 | func closeListener(roomid string, listener chan interface{}) { 14 | room(roomid).Unregister(listener) 15 | close(listener) 16 | } 17 | 18 | func room(roomid string) broadcast.Broadcaster { 19 | b, ok := roomChannels[roomid] 20 | if !ok { 21 | b = broadcast.NewBroadcaster(10) 22 | roomChannels[roomid] = b 23 | } 24 | return b 25 | } 26 | -------------------------------------------------------------------------------- /github.com/gin-gonic/gin/examples/realtime-advanced/routes.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "html" 6 | "io" 7 | "strings" 8 | "time" 9 | 10 | "github.com/gin-gonic/gin" 11 | ) 12 | 13 | func rateLimit(c *gin.Context) { 14 | 15 | ip := c.ClientIP() 16 | value := int(ips.Add(ip, 1)) 17 | if value%50 == 0 { 18 | fmt.Printf("ip: %s, count: %d\n", ip, value) 19 | } 20 | if value >= 200 { 21 | if value%200 == 0 { 22 | fmt.Println("ip blocked") 23 | } 24 | c.Abort() 25 | c.String(503, "you were automatically banned :)") 26 | } 27 | } 28 | 29 | func index(c *gin.Context) { 30 | c.Redirect(301, "/room/hn") 31 | } 32 | 33 | func roomGET(c *gin.Context) { 34 | roomid := c.Param("roomid") 35 | nick := c.Query("nick") 36 | if len(nick) < 2 { 37 | nick = "" 38 | } 39 | if len(nick) > 13 { 40 | nick = nick[0:12] + "..." 41 | } 42 | c.HTML(200, "room_login.templ.html", gin.H{ 43 | "roomid": roomid, 44 | "nick": nick, 45 | "timestamp": time.Now().Unix(), 46 | }) 47 | 48 | } 49 | 50 | func roomPOST(c *gin.Context) { 51 | roomid := c.Param("roomid") 52 | nick := c.Query("nick") 53 | message := c.PostForm("message") 54 | message = strings.TrimSpace(message) 55 | 56 | validMessage := len(message) > 1 && len(message) < 200 57 | validNick := len(nick) > 1 && len(nick) < 14 58 | if !validMessage || !validNick { 59 | c.JSON(400, gin.H{ 60 | "status": "failed", 61 | "error": "the message or nickname is too long", 62 | }) 63 | return 64 | } 65 | 66 | post := gin.H{ 67 | "nick": html.EscapeString(nick), 68 | "message": html.EscapeString(message), 69 | } 70 | messages.Add("inbound", 1) 71 | room(roomid).Submit(post) 72 | c.JSON(200, post) 73 | } 74 | 75 | func streamRoom(c *gin.Context) { 76 | roomid := c.Param("roomid") 77 | listener := openListener(roomid) 78 | ticker := time.NewTicker(1 * time.Second) 79 | users.Add("connected", 1) 80 | defer func() { 81 | closeListener(roomid, listener) 82 | ticker.Stop() 83 | users.Add("disconnected", 1) 84 | }() 85 | 86 | c.Stream(func(w io.Writer) bool { 87 | select { 88 | case msg := <-listener: 89 | messages.Add("outbound", 1) 90 | c.SSEvent("message", msg) 91 | case <-ticker.C: 92 | c.SSEvent("stats", Stats()) 93 | } 94 | return true 95 | }) 96 | } 97 | -------------------------------------------------------------------------------- /github.com/gin-gonic/gin/examples/realtime-advanced/stats.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "runtime" 5 | "sync" 6 | "time" 7 | 8 | "github.com/manucorporat/stats" 9 | ) 10 | 11 | var ips = stats.New() 12 | var messages = stats.New() 13 | var users = stats.New() 14 | var mutexStats sync.RWMutex 15 | var savedStats map[string]uint64 16 | 17 | func statsWorker() { 18 | c := time.Tick(1 * time.Second) 19 | var lastMallocs uint64 = 0 20 | var lastFrees uint64 = 0 21 | for _ = range c { 22 | var stats runtime.MemStats 23 | runtime.ReadMemStats(&stats) 24 | 25 | mutexStats.Lock() 26 | savedStats = map[string]uint64{ 27 | "timestamp": uint64(time.Now().Unix()), 28 | "HeapInuse": stats.HeapInuse, 29 | "StackInuse": stats.StackInuse, 30 | "Mallocs": (stats.Mallocs - lastMallocs), 31 | "Frees": (stats.Frees - lastFrees), 32 | "Inbound": uint64(messages.Get("inbound")), 33 | "Outbound": uint64(messages.Get("outbound")), 34 | "Connected": connectedUsers(), 35 | } 36 | lastMallocs = stats.Mallocs 37 | lastFrees = stats.Frees 38 | messages.Reset() 39 | mutexStats.Unlock() 40 | } 41 | } 42 | 43 | func connectedUsers() uint64 { 44 | connected := users.Get("connected") - users.Get("disconnected") 45 | if connected < 0 { 46 | return 0 47 | } 48 | return uint64(connected) 49 | } 50 | 51 | func Stats() map[string]uint64 { 52 | mutexStats.RLock() 53 | defer mutexStats.RUnlock() 54 | 55 | return savedStats 56 | } 57 | -------------------------------------------------------------------------------- /github.com/gin-gonic/gin/examples/realtime-chat/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "io" 6 | "math/rand" 7 | 8 | "github.com/gin-gonic/gin" 9 | ) 10 | 11 | func main() { 12 | router := gin.Default() 13 | router.SetHTMLTemplate(html) 14 | 15 | router.GET("/room/:roomid", roomGET) 16 | router.POST("/room/:roomid", roomPOST) 17 | router.DELETE("/room/:roomid", roomDELETE) 18 | router.GET("/stream/:roomid", stream) 19 | 20 | router.Run(":8080") 21 | } 22 | 23 | func stream(c *gin.Context) { 24 | roomid := c.Param("roomid") 25 | listener := openListener(roomid) 26 | defer closeListener(roomid, listener) 27 | 28 | c.Stream(func(w io.Writer) bool { 29 | c.SSEvent("message", <-listener) 30 | return true 31 | }) 32 | } 33 | 34 | func roomGET(c *gin.Context) { 35 | roomid := c.Param("roomid") 36 | userid := fmt.Sprint(rand.Int31()) 37 | c.HTML(200, "chat_room", gin.H{ 38 | "roomid": roomid, 39 | "userid": userid, 40 | }) 41 | } 42 | 43 | func roomPOST(c *gin.Context) { 44 | roomid := c.Param("roomid") 45 | userid := c.PostForm("user") 46 | message := c.PostForm("message") 47 | room(roomid).Submit(userid + ": " + message) 48 | 49 | c.JSON(200, gin.H{ 50 | "status": "success", 51 | "message": message, 52 | }) 53 | } 54 | 55 | func roomDELETE(c *gin.Context) { 56 | roomid := c.Param("roomid") 57 | deleteBroadcast(roomid) 58 | } 59 | -------------------------------------------------------------------------------- /github.com/gin-gonic/gin/examples/realtime-chat/rooms.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "github.com/dustin/go-broadcast" 4 | 5 | var roomChannels = make(map[string]broadcast.Broadcaster) 6 | 7 | func openListener(roomid string) chan interface{} { 8 | listener := make(chan interface{}) 9 | room(roomid).Register(listener) 10 | return listener 11 | } 12 | 13 | func closeListener(roomid string, listener chan interface{}) { 14 | room(roomid).Unregister(listener) 15 | close(listener) 16 | } 17 | 18 | func deleteBroadcast(roomid string) { 19 | b, ok := roomChannels[roomid] 20 | if ok { 21 | b.Close() 22 | delete(roomChannels, roomid) 23 | } 24 | } 25 | 26 | func room(roomid string) broadcast.Broadcaster { 27 | b, ok := roomChannels[roomid] 28 | if !ok { 29 | b = broadcast.NewBroadcaster(10) 30 | roomChannels[roomid] = b 31 | } 32 | return b 33 | } 34 | -------------------------------------------------------------------------------- /github.com/gin-gonic/gin/examples/realtime-chat/template.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "html/template" 4 | 5 | var html = template.Must(template.New("chat_room").Parse(` 6 | 7 | 8 | {{.roomid}} 9 | 10 | 11 | 12 | 33 | 34 | 35 |

Welcome to {{.roomid}} room

36 |
37 |
38 | User: 39 | Message: 40 | 41 |
42 | 43 | 44 | `)) 45 | -------------------------------------------------------------------------------- /github.com/gin-gonic/gin/fs.go: -------------------------------------------------------------------------------- 1 | package gin 2 | 3 | import ( 4 | "net/http" 5 | "os" 6 | ) 7 | 8 | type ( 9 | onlyfilesFS struct { 10 | fs http.FileSystem 11 | } 12 | neuteredReaddirFile struct { 13 | http.File 14 | } 15 | ) 16 | 17 | // Dir returns a http.Filesystem that can be used by http.FileServer(). It is used interally 18 | // in router.Static(). 19 | // if listDirectory == true, then it works the same as http.Dir() otherwise it returns 20 | // a filesystem that prevents http.FileServer() to list the directory files. 21 | func Dir(root string, listDirectory bool) http.FileSystem { 22 | fs := http.Dir(root) 23 | if listDirectory { 24 | return fs 25 | } 26 | return &onlyfilesFS{fs} 27 | } 28 | 29 | // Conforms to http.Filesystem 30 | func (fs onlyfilesFS) Open(name string) (http.File, error) { 31 | f, err := fs.fs.Open(name) 32 | if err != nil { 33 | return nil, err 34 | } 35 | return neuteredReaddirFile{f}, nil 36 | } 37 | 38 | // Overrides the http.File default implementation 39 | func (f neuteredReaddirFile) Readdir(count int) ([]os.FileInfo, error) { 40 | // this disables directory listing 41 | return nil, nil 42 | } 43 | -------------------------------------------------------------------------------- /github.com/gin-gonic/gin/ginS/README.md: -------------------------------------------------------------------------------- 1 | #Gin Default Server 2 | 3 | This is API experiment for Gin. 4 | 5 | ```go 6 | package main 7 | 8 | import ( 9 | "github.com/gin-gonic/gin" 10 | "github.com/gin-gonic/gin/ginS" 11 | ) 12 | 13 | func main() { 14 | ginS.GET("/", func(c *gin.Context) { c.String("Hello World") }) 15 | ginS.Run() 16 | } 17 | ``` 18 | -------------------------------------------------------------------------------- /github.com/gin-gonic/gin/gin_integration_test.go: -------------------------------------------------------------------------------- 1 | package gin 2 | 3 | import ( 4 | "bufio" 5 | "fmt" 6 | "io/ioutil" 7 | "net" 8 | "net/http" 9 | "os" 10 | "testing" 11 | "time" 12 | 13 | "github.com/stretchr/testify/assert" 14 | ) 15 | 16 | func testRequest(t *testing.T, url string) { 17 | resp, err := http.Get(url) 18 | defer resp.Body.Close() 19 | assert.NoError(t, err) 20 | 21 | body, ioerr := ioutil.ReadAll(resp.Body) 22 | assert.NoError(t, ioerr) 23 | assert.Equal(t, "it worked", string(body), "resp body should match") 24 | assert.Equal(t, "200 OK", resp.Status, "should get a 200") 25 | } 26 | 27 | func TestRunEmpty(t *testing.T) { 28 | os.Setenv("PORT", "") 29 | router := New() 30 | go func() { 31 | router.GET("/example", func(c *Context) { c.String(http.StatusOK, "it worked") }) 32 | assert.NoError(t, router.Run()) 33 | }() 34 | // have to wait for the goroutine to start and run the server 35 | // otherwise the main thread will complete 36 | time.Sleep(5 * time.Millisecond) 37 | 38 | assert.Error(t, router.Run(":8080")) 39 | testRequest(t, "http://localhost:8080/example") 40 | } 41 | 42 | func TestRunEmptyWithEnv(t *testing.T) { 43 | os.Setenv("PORT", "3123") 44 | router := New() 45 | go func() { 46 | router.GET("/example", func(c *Context) { c.String(http.StatusOK, "it worked") }) 47 | assert.NoError(t, router.Run()) 48 | }() 49 | // have to wait for the goroutine to start and run the server 50 | // otherwise the main thread will complete 51 | time.Sleep(5 * time.Millisecond) 52 | 53 | assert.Error(t, router.Run(":3123")) 54 | testRequest(t, "http://localhost:3123/example") 55 | } 56 | 57 | func TestRunTooMuchParams(t *testing.T) { 58 | router := New() 59 | assert.Panics(t, func() { 60 | router.Run("2", "2") 61 | }) 62 | } 63 | 64 | func TestRunWithPort(t *testing.T) { 65 | router := New() 66 | go func() { 67 | router.GET("/example", func(c *Context) { c.String(http.StatusOK, "it worked") }) 68 | assert.NoError(t, router.Run(":5150")) 69 | }() 70 | // have to wait for the goroutine to start and run the server 71 | // otherwise the main thread will complete 72 | time.Sleep(5 * time.Millisecond) 73 | 74 | assert.Error(t, router.Run(":5150")) 75 | testRequest(t, "http://localhost:5150/example") 76 | } 77 | 78 | func TestUnixSocket(t *testing.T) { 79 | router := New() 80 | 81 | go func() { 82 | router.GET("/example", func(c *Context) { c.String(http.StatusOK, "it worked") }) 83 | assert.NoError(t, router.RunUnix("/tmp/unix_unit_test")) 84 | }() 85 | // have to wait for the goroutine to start and run the server 86 | // otherwise the main thread will complete 87 | time.Sleep(5 * time.Millisecond) 88 | 89 | c, err := net.Dial("unix", "/tmp/unix_unit_test") 90 | assert.NoError(t, err) 91 | 92 | fmt.Fprintf(c, "GET /example HTTP/1.0\r\n\r\n") 93 | scanner := bufio.NewScanner(c) 94 | var response string 95 | for scanner.Scan() { 96 | response += scanner.Text() 97 | } 98 | assert.Contains(t, response, "HTTP/1.0 200", "should get a 200") 99 | assert.Contains(t, response, "it worked", "resp body should match") 100 | } 101 | 102 | func TestBadUnixSocket(t *testing.T) { 103 | router := New() 104 | assert.Error(t, router.RunUnix("#/tmp/unix_unit_test")) 105 | } 106 | -------------------------------------------------------------------------------- /github.com/gin-gonic/gin/logger.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 Manu Martinez-Almeida. All rights reserved. 2 | // Use of this source code is governed by a MIT style 3 | // license that can be found in the LICENSE file. 4 | 5 | package gin 6 | 7 | import ( 8 | "fmt" 9 | "io" 10 | "time" 11 | ) 12 | 13 | var ( 14 | green = string([]byte{27, 91, 57, 55, 59, 52, 50, 109}) 15 | white = string([]byte{27, 91, 57, 48, 59, 52, 55, 109}) 16 | yellow = string([]byte{27, 91, 57, 55, 59, 52, 51, 109}) 17 | red = string([]byte{27, 91, 57, 55, 59, 52, 49, 109}) 18 | blue = string([]byte{27, 91, 57, 55, 59, 52, 52, 109}) 19 | magenta = string([]byte{27, 91, 57, 55, 59, 52, 53, 109}) 20 | cyan = string([]byte{27, 91, 57, 55, 59, 52, 54, 109}) 21 | reset = string([]byte{27, 91, 48, 109}) 22 | ) 23 | 24 | func ErrorLogger() HandlerFunc { 25 | return ErrorLoggerT(ErrorTypeAny) 26 | } 27 | 28 | func ErrorLoggerT(typ ErrorType) HandlerFunc { 29 | return func(c *Context) { 30 | c.Next() 31 | // avoid writting if we already wrote into the response body 32 | if !c.Writer.Written() { 33 | errors := c.Errors.ByType(typ) 34 | if len(errors) > 0 { 35 | c.JSON(-1, errors) 36 | } 37 | } 38 | } 39 | } 40 | 41 | // Instances a Logger middleware that will write the logs to gin.DefaultWriter 42 | // By default gin.DefaultWriter = os.Stdout 43 | func Logger() HandlerFunc { 44 | return LoggerWithWriter(DefaultWriter) 45 | } 46 | 47 | // Instance a Logger middleware with the specified writter buffer. 48 | // Example: os.Stdout, a file opened in write mode, a socket... 49 | func LoggerWithWriter(out io.Writer, notlogged ...string) HandlerFunc { 50 | var skip map[string]struct{} 51 | 52 | if length := len(notlogged); length > 0 { 53 | skip = make(map[string]struct{}, length) 54 | 55 | for _, path := range notlogged { 56 | skip[path] = struct{}{} 57 | } 58 | } 59 | 60 | return func(c *Context) { 61 | // Start timer 62 | start := time.Now() 63 | path := c.Request.URL.Path 64 | 65 | // Process request 66 | c.Next() 67 | 68 | // Log only when path is not being skipped 69 | if _, ok := skip[path]; !ok { 70 | // Stop timer 71 | end := time.Now() 72 | latency := end.Sub(start) 73 | 74 | clientIP := c.ClientIP() 75 | method := c.Request.Method 76 | statusCode := c.Writer.Status() 77 | statusColor := colorForStatus(statusCode) 78 | methodColor := colorForMethod(method) 79 | comment := c.Errors.ByType(ErrorTypePrivate).String() 80 | 81 | fmt.Fprintf(out, "[GIN] %v |%s %3d %s| %13v | %s |%s %s %-7s %s\n%s", 82 | end.Format("2006/01/02 - 15:04:05"), 83 | statusColor, statusCode, reset, 84 | latency, 85 | clientIP, 86 | methodColor, reset, method, 87 | path, 88 | comment, 89 | ) 90 | } 91 | } 92 | } 93 | 94 | func colorForStatus(code int) string { 95 | switch { 96 | case code >= 200 && code < 300: 97 | return green 98 | case code >= 300 && code < 400: 99 | return white 100 | case code >= 400 && code < 500: 101 | return yellow 102 | default: 103 | return red 104 | } 105 | } 106 | 107 | func colorForMethod(method string) string { 108 | switch method { 109 | case "GET": 110 | return blue 111 | case "POST": 112 | return cyan 113 | case "PUT": 114 | return yellow 115 | case "DELETE": 116 | return red 117 | case "PATCH": 118 | return green 119 | case "HEAD": 120 | return magenta 121 | case "OPTIONS": 122 | return white 123 | default: 124 | return reset 125 | } 126 | } 127 | -------------------------------------------------------------------------------- /github.com/gin-gonic/gin/logo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yalay/go-thumbnail/4c72c077e1308a1d176cfba1990200b7dc2d7a52/github.com/gin-gonic/gin/logo.jpg -------------------------------------------------------------------------------- /github.com/gin-gonic/gin/mode.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 Manu Martinez-Almeida. All rights reserved. 2 | // Use of this source code is governed by a MIT style 3 | // license that can be found in the LICENSE file. 4 | 5 | package gin 6 | 7 | import ( 8 | "io" 9 | "os" 10 | 11 | "github.com/gin-gonic/gin/binding" 12 | ) 13 | 14 | const ENV_GIN_MODE = "GIN_MODE" 15 | 16 | const ( 17 | DebugMode string = "debug" 18 | ReleaseMode string = "release" 19 | TestMode string = "test" 20 | ) 21 | const ( 22 | debugCode = iota 23 | releaseCode = iota 24 | testCode = iota 25 | ) 26 | 27 | // DefaultWriter is the default io.Writer used the Gin for debug output and 28 | // middleware output like Logger() or Recovery(). 29 | // Note that both Logger and Recovery provides custom ways to configure their 30 | // output io.Writer. 31 | // To support coloring in Windows use: 32 | // import "github.com/mattn/go-colorable" 33 | // gin.DefaultWriter = colorable.NewColorableStdout() 34 | var DefaultWriter io.Writer = os.Stdout 35 | var DefaultErrorWriter io.Writer = os.Stderr 36 | 37 | var ginMode int = debugCode 38 | var modeName string = DebugMode 39 | 40 | func init() { 41 | mode := os.Getenv(ENV_GIN_MODE) 42 | if len(mode) == 0 { 43 | SetMode(DebugMode) 44 | } else { 45 | SetMode(mode) 46 | } 47 | } 48 | 49 | func SetMode(value string) { 50 | switch value { 51 | case DebugMode: 52 | ginMode = debugCode 53 | case ReleaseMode: 54 | ginMode = releaseCode 55 | case TestMode: 56 | ginMode = testCode 57 | default: 58 | panic("gin mode unknown: " + value) 59 | } 60 | modeName = value 61 | } 62 | 63 | func DisableBindValidation() { 64 | binding.Validator = nil 65 | } 66 | 67 | func Mode() string { 68 | return modeName 69 | } 70 | -------------------------------------------------------------------------------- /github.com/gin-gonic/gin/mode_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 Manu Martinez-Almeida. All rights reserved. 2 | // Use of this source code is governed by a MIT style 3 | // license that can be found in the LICENSE file. 4 | 5 | package gin 6 | 7 | import ( 8 | "testing" 9 | 10 | "github.com/stretchr/testify/assert" 11 | ) 12 | 13 | func init() { 14 | SetMode(TestMode) 15 | } 16 | 17 | func TestSetMode(t *testing.T) { 18 | SetMode(DebugMode) 19 | assert.Equal(t, ginMode, debugCode) 20 | assert.Equal(t, Mode(), DebugMode) 21 | 22 | SetMode(ReleaseMode) 23 | assert.Equal(t, ginMode, releaseCode) 24 | assert.Equal(t, Mode(), ReleaseMode) 25 | 26 | SetMode(TestMode) 27 | assert.Equal(t, ginMode, testCode) 28 | assert.Equal(t, Mode(), TestMode) 29 | 30 | assert.Panics(t, func() { SetMode("unknown") }) 31 | } 32 | -------------------------------------------------------------------------------- /github.com/gin-gonic/gin/path.go: -------------------------------------------------------------------------------- 1 | // Copyright 2013 Julien Schmidt. All rights reserved. 2 | // Based on the path package, Copyright 2009 The Go Authors. 3 | // Use of this source code is governed by a BSD-style license that can be found 4 | // in the LICENSE file. 5 | 6 | package gin 7 | 8 | // CleanPath is the URL version of path.Clean, it returns a canonical URL path 9 | // for p, eliminating . and .. elements. 10 | // 11 | // The following rules are applied iteratively until no further processing can 12 | // be done: 13 | // 1. Replace multiple slashes with a single slash. 14 | // 2. Eliminate each . path name element (the current directory). 15 | // 3. Eliminate each inner .. path name element (the parent directory) 16 | // along with the non-.. element that precedes it. 17 | // 4. Eliminate .. elements that begin a rooted path: 18 | // that is, replace "/.." by "/" at the beginning of a path. 19 | // 20 | // If the result of this process is an empty string, "/" is returned 21 | func cleanPath(p string) string { 22 | // Turn empty string into "/" 23 | if p == "" { 24 | return "/" 25 | } 26 | 27 | n := len(p) 28 | var buf []byte 29 | 30 | // Invariants: 31 | // reading from path; r is index of next byte to process. 32 | // writing to buf; w is index of next byte to write. 33 | 34 | // path must start with '/' 35 | r := 1 36 | w := 1 37 | 38 | if p[0] != '/' { 39 | r = 0 40 | buf = make([]byte, n+1) 41 | buf[0] = '/' 42 | } 43 | 44 | trailing := n > 2 && p[n-1] == '/' 45 | 46 | // A bit more clunky without a 'lazybuf' like the path package, but the loop 47 | // gets completely inlined (bufApp). So in contrast to the path package this 48 | // loop has no expensive function calls (except 1x make) 49 | 50 | for r < n { 51 | switch { 52 | case p[r] == '/': 53 | // empty path element, trailing slash is added after the end 54 | r++ 55 | 56 | case p[r] == '.' && r+1 == n: 57 | trailing = true 58 | r++ 59 | 60 | case p[r] == '.' && p[r+1] == '/': 61 | // . element 62 | r++ 63 | 64 | case p[r] == '.' && p[r+1] == '.' && (r+2 == n || p[r+2] == '/'): 65 | // .. element: remove to last / 66 | r += 2 67 | 68 | if w > 1 { 69 | // can backtrack 70 | w-- 71 | 72 | if buf == nil { 73 | for w > 1 && p[w] != '/' { 74 | w-- 75 | } 76 | } else { 77 | for w > 1 && buf[w] != '/' { 78 | w-- 79 | } 80 | } 81 | } 82 | 83 | default: 84 | // real path element. 85 | // add slash if needed 86 | if w > 1 { 87 | bufApp(&buf, p, w, '/') 88 | w++ 89 | } 90 | 91 | // copy element 92 | for r < n && p[r] != '/' { 93 | bufApp(&buf, p, w, p[r]) 94 | w++ 95 | r++ 96 | } 97 | } 98 | } 99 | 100 | // re-append trailing slash 101 | if trailing && w > 1 { 102 | bufApp(&buf, p, w, '/') 103 | w++ 104 | } 105 | 106 | if buf == nil { 107 | return p[:w] 108 | } 109 | return string(buf[:w]) 110 | } 111 | 112 | // internal helper to lazily create a buffer if necessary 113 | func bufApp(buf *[]byte, s string, w int, c byte) { 114 | if *buf == nil { 115 | if s[w] == c { 116 | return 117 | } 118 | 119 | *buf = make([]byte, len(s)) 120 | copy(*buf, s[:w]) 121 | } 122 | (*buf)[w] = c 123 | } 124 | -------------------------------------------------------------------------------- /github.com/gin-gonic/gin/path_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2013 Julien Schmidt. All rights reserved. 2 | // Based on the path package, Copyright 2009 The Go Authors. 3 | // Use of this source code is governed by a BSD-style license that can be found 4 | // in the LICENSE file. 5 | 6 | package gin 7 | 8 | import ( 9 | "runtime" 10 | "testing" 11 | 12 | "github.com/stretchr/testify/assert" 13 | ) 14 | 15 | var cleanTests = []struct { 16 | path, result string 17 | }{ 18 | // Already clean 19 | {"/", "/"}, 20 | {"/abc", "/abc"}, 21 | {"/a/b/c", "/a/b/c"}, 22 | {"/abc/", "/abc/"}, 23 | {"/a/b/c/", "/a/b/c/"}, 24 | 25 | // missing root 26 | {"", "/"}, 27 | {"abc", "/abc"}, 28 | {"abc/def", "/abc/def"}, 29 | {"a/b/c", "/a/b/c"}, 30 | 31 | // Remove doubled slash 32 | {"//", "/"}, 33 | {"/abc//", "/abc/"}, 34 | {"/abc/def//", "/abc/def/"}, 35 | {"/a/b/c//", "/a/b/c/"}, 36 | {"/abc//def//ghi", "/abc/def/ghi"}, 37 | {"//abc", "/abc"}, 38 | {"///abc", "/abc"}, 39 | {"//abc//", "/abc/"}, 40 | 41 | // Remove . elements 42 | {".", "/"}, 43 | {"./", "/"}, 44 | {"/abc/./def", "/abc/def"}, 45 | {"/./abc/def", "/abc/def"}, 46 | {"/abc/.", "/abc/"}, 47 | 48 | // Remove .. elements 49 | {"..", "/"}, 50 | {"../", "/"}, 51 | {"../../", "/"}, 52 | {"../..", "/"}, 53 | {"../../abc", "/abc"}, 54 | {"/abc/def/ghi/../jkl", "/abc/def/jkl"}, 55 | {"/abc/def/../ghi/../jkl", "/abc/jkl"}, 56 | {"/abc/def/..", "/abc"}, 57 | {"/abc/def/../..", "/"}, 58 | {"/abc/def/../../..", "/"}, 59 | {"/abc/def/../../..", "/"}, 60 | {"/abc/def/../../../ghi/jkl/../../../mno", "/mno"}, 61 | 62 | // Combinations 63 | {"abc/./../def", "/def"}, 64 | {"abc//./../def", "/def"}, 65 | {"abc/../../././../def", "/def"}, 66 | } 67 | 68 | func TestPathClean(t *testing.T) { 69 | for _, test := range cleanTests { 70 | assert.Equal(t, cleanPath(test.path), test.result) 71 | assert.Equal(t, cleanPath(test.result), test.result) 72 | } 73 | } 74 | 75 | func TestPathCleanMallocs(t *testing.T) { 76 | if testing.Short() { 77 | t.Skip("skipping malloc count in short mode") 78 | } 79 | if runtime.GOMAXPROCS(0) > 1 { 80 | t.Log("skipping AllocsPerRun checks; GOMAXPROCS>1") 81 | return 82 | } 83 | 84 | for _, test := range cleanTests { 85 | allocs := testing.AllocsPerRun(100, func() { cleanPath(test.result) }) 86 | assert.EqualValues(t, allocs, 0) 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /github.com/gin-gonic/gin/recovery.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 Manu Martinez-Almeida. All rights reserved. 2 | // Use of this source code is governed by a MIT style 3 | // license that can be found in the LICENSE file. 4 | 5 | package gin 6 | 7 | import ( 8 | "bytes" 9 | "fmt" 10 | "io" 11 | "io/ioutil" 12 | "log" 13 | "net/http/httputil" 14 | "runtime" 15 | ) 16 | 17 | var ( 18 | dunno = []byte("???") 19 | centerDot = []byte("·") 20 | dot = []byte(".") 21 | slash = []byte("/") 22 | ) 23 | 24 | // Recovery returns a middleware that recovers from any panics and writes a 500 if there was one. 25 | func Recovery() HandlerFunc { 26 | return RecoveryWithWriter(DefaultErrorWriter) 27 | } 28 | 29 | func RecoveryWithWriter(out io.Writer) HandlerFunc { 30 | var logger *log.Logger 31 | if out != nil { 32 | logger = log.New(out, "\n\n\x1b[31m", log.LstdFlags) 33 | } 34 | return func(c *Context) { 35 | defer func() { 36 | if err := recover(); err != nil { 37 | if logger != nil { 38 | stack := stack(3) 39 | httprequest, _ := httputil.DumpRequest(c.Request, false) 40 | logger.Printf("[Recovery] panic recovered:\n%s\n%s\n%s%s", string(httprequest), err, stack, reset) 41 | } 42 | c.AbortWithStatus(500) 43 | } 44 | }() 45 | c.Next() 46 | } 47 | } 48 | 49 | // stack returns a nicely formated stack frame, skipping skip frames 50 | func stack(skip int) []byte { 51 | buf := new(bytes.Buffer) // the returned data 52 | // As we loop, we open files and read them. These variables record the currently 53 | // loaded file. 54 | var lines [][]byte 55 | var lastFile string 56 | for i := skip; ; i++ { // Skip the expected number of frames 57 | pc, file, line, ok := runtime.Caller(i) 58 | if !ok { 59 | break 60 | } 61 | // Print this much at least. If we can't find the source, it won't show. 62 | fmt.Fprintf(buf, "%s:%d (0x%x)\n", file, line, pc) 63 | if file != lastFile { 64 | data, err := ioutil.ReadFile(file) 65 | if err != nil { 66 | continue 67 | } 68 | lines = bytes.Split(data, []byte{'\n'}) 69 | lastFile = file 70 | } 71 | fmt.Fprintf(buf, "\t%s: %s\n", function(pc), source(lines, line)) 72 | } 73 | return buf.Bytes() 74 | } 75 | 76 | // source returns a space-trimmed slice of the n'th line. 77 | func source(lines [][]byte, n int) []byte { 78 | n-- // in stack trace, lines are 1-indexed but our array is 0-indexed 79 | if n < 0 || n >= len(lines) { 80 | return dunno 81 | } 82 | return bytes.TrimSpace(lines[n]) 83 | } 84 | 85 | // function returns, if possible, the name of the function containing the PC. 86 | func function(pc uintptr) []byte { 87 | fn := runtime.FuncForPC(pc) 88 | if fn == nil { 89 | return dunno 90 | } 91 | name := []byte(fn.Name()) 92 | // The name includes the path name to the package, which is unnecessary 93 | // since the file name is already included. Plus, it has center dots. 94 | // That is, we see 95 | // runtime/debug.*T·ptrmethod 96 | // and want 97 | // *T.ptrmethod 98 | // Also the package path might contains dot (e.g. code.google.com/...), 99 | // so first eliminate the path prefix 100 | if lastslash := bytes.LastIndex(name, slash); lastslash >= 0 { 101 | name = name[lastslash+1:] 102 | } 103 | if period := bytes.Index(name, dot); period >= 0 { 104 | name = name[period+1:] 105 | } 106 | name = bytes.Replace(name, centerDot, dot, -1) 107 | return name 108 | } 109 | -------------------------------------------------------------------------------- /github.com/gin-gonic/gin/recovery_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 Manu Martinez-Almeida. All rights reserved. 2 | // Use of this source code is governed by a MIT style 3 | // license that can be found in the LICENSE file. 4 | 5 | package gin 6 | 7 | import ( 8 | "bytes" 9 | "testing" 10 | 11 | "github.com/stretchr/testify/assert" 12 | ) 13 | 14 | // TestPanicInHandler assert that panic has been recovered. 15 | func TestPanicInHandler(t *testing.T) { 16 | buffer := new(bytes.Buffer) 17 | router := New() 18 | router.Use(RecoveryWithWriter(buffer)) 19 | router.GET("/recovery", func(_ *Context) { 20 | panic("Oupps, Houston, we have a problem") 21 | }) 22 | // RUN 23 | w := performRequest(router, "GET", "/recovery") 24 | // TEST 25 | assert.Equal(t, w.Code, 500) 26 | assert.Contains(t, buffer.String(), "GET /recovery") 27 | assert.Contains(t, buffer.String(), "Oupps, Houston, we have a problem") 28 | assert.Contains(t, buffer.String(), "TestPanicInHandler") 29 | } 30 | 31 | // TestPanicWithAbort assert that panic has been recovered even if context.Abort was used. 32 | func TestPanicWithAbort(t *testing.T) { 33 | router := New() 34 | router.Use(RecoveryWithWriter(nil)) 35 | router.GET("/recovery", func(c *Context) { 36 | c.AbortWithStatus(400) 37 | panic("Oupps, Houston, we have a problem") 38 | }) 39 | // RUN 40 | w := performRequest(router, "GET", "/recovery") 41 | // TEST 42 | assert.Equal(t, w.Code, 500) // NOT SURE 43 | } 44 | -------------------------------------------------------------------------------- /github.com/gin-gonic/gin/render/data.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 Manu Martinez-Almeida. All rights reserved. 2 | // Use of this source code is governed by a MIT style 3 | // license that can be found in the LICENSE file. 4 | 5 | package render 6 | 7 | import "net/http" 8 | 9 | type Data struct { 10 | ContentType string 11 | Data []byte 12 | } 13 | 14 | func (r Data) Render(w http.ResponseWriter) error { 15 | if len(r.ContentType) > 0 { 16 | w.Header()["Content-Type"] = []string{r.ContentType} 17 | } 18 | w.Write(r.Data) 19 | return nil 20 | } 21 | -------------------------------------------------------------------------------- /github.com/gin-gonic/gin/render/html.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 Manu Martinez-Almeida. All rights reserved. 2 | // Use of this source code is governed by a MIT style 3 | // license that can be found in the LICENSE file. 4 | 5 | package render 6 | 7 | import ( 8 | "html/template" 9 | "net/http" 10 | ) 11 | 12 | type ( 13 | HTMLRender interface { 14 | Instance(string, interface{}) Render 15 | } 16 | 17 | HTMLProduction struct { 18 | Template *template.Template 19 | } 20 | 21 | HTMLDebug struct { 22 | Files []string 23 | Glob string 24 | } 25 | 26 | HTML struct { 27 | Template *template.Template 28 | Name string 29 | Data interface{} 30 | } 31 | ) 32 | 33 | var htmlContentType = []string{"text/html; charset=utf-8"} 34 | 35 | func (r HTMLProduction) Instance(name string, data interface{}) Render { 36 | return HTML{ 37 | Template: r.Template, 38 | Name: name, 39 | Data: data, 40 | } 41 | } 42 | 43 | func (r HTMLDebug) Instance(name string, data interface{}) Render { 44 | return HTML{ 45 | Template: r.loadTemplate(), 46 | Name: name, 47 | Data: data, 48 | } 49 | } 50 | func (r HTMLDebug) loadTemplate() *template.Template { 51 | if len(r.Files) > 0 { 52 | return template.Must(template.ParseFiles(r.Files...)) 53 | } 54 | if len(r.Glob) > 0 { 55 | return template.Must(template.ParseGlob(r.Glob)) 56 | } 57 | panic("the HTML debug render was created without files or glob pattern") 58 | } 59 | 60 | func (r HTML) Render(w http.ResponseWriter) error { 61 | writeContentType(w, htmlContentType) 62 | if len(r.Name) == 0 { 63 | return r.Template.Execute(w, r.Data) 64 | } else { 65 | return r.Template.ExecuteTemplate(w, r.Name, r.Data) 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /github.com/gin-gonic/gin/render/json.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 Manu Martinez-Almeida. All rights reserved. 2 | // Use of this source code is governed by a MIT style 3 | // license that can be found in the LICENSE file. 4 | 5 | package render 6 | 7 | import ( 8 | "encoding/json" 9 | "net/http" 10 | ) 11 | 12 | type ( 13 | JSON struct { 14 | Data interface{} 15 | } 16 | 17 | IndentedJSON struct { 18 | Data interface{} 19 | } 20 | ) 21 | 22 | var jsonContentType = []string{"application/json; charset=utf-8"} 23 | 24 | func (r JSON) Render(w http.ResponseWriter) error { 25 | return WriteJSON(w, r.Data) 26 | } 27 | 28 | func (r IndentedJSON) Render(w http.ResponseWriter) error { 29 | writeContentType(w, jsonContentType) 30 | jsonBytes, err := json.MarshalIndent(r.Data, "", " ") 31 | if err != nil { 32 | return err 33 | } 34 | w.Write(jsonBytes) 35 | return nil 36 | } 37 | 38 | func WriteJSON(w http.ResponseWriter, obj interface{}) error { 39 | writeContentType(w, jsonContentType) 40 | return json.NewEncoder(w).Encode(obj) 41 | } 42 | -------------------------------------------------------------------------------- /github.com/gin-gonic/gin/render/redirect.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 Manu Martinez-Almeida. All rights reserved. 2 | // Use of this source code is governed by a MIT style 3 | // license that can be found in the LICENSE file. 4 | 5 | package render 6 | 7 | import ( 8 | "fmt" 9 | "net/http" 10 | ) 11 | 12 | type Redirect struct { 13 | Code int 14 | Request *http.Request 15 | Location string 16 | } 17 | 18 | func (r Redirect) Render(w http.ResponseWriter) error { 19 | if (r.Code < 300 || r.Code > 308) && r.Code != 201 { 20 | panic(fmt.Sprintf("Cannot redirect with status code %d", r.Code)) 21 | } 22 | http.Redirect(w, r.Request, r.Location, r.Code) 23 | return nil 24 | } 25 | -------------------------------------------------------------------------------- /github.com/gin-gonic/gin/render/render.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 Manu Martinez-Almeida. All rights reserved. 2 | // Use of this source code is governed by a MIT style 3 | // license that can be found in the LICENSE file. 4 | 5 | package render 6 | 7 | import "net/http" 8 | 9 | type Render interface { 10 | Render(http.ResponseWriter) error 11 | } 12 | 13 | var ( 14 | _ Render = JSON{} 15 | _ Render = IndentedJSON{} 16 | _ Render = XML{} 17 | _ Render = String{} 18 | _ Render = Redirect{} 19 | _ Render = Data{} 20 | _ Render = HTML{} 21 | _ HTMLRender = HTMLDebug{} 22 | _ HTMLRender = HTMLProduction{} 23 | ) 24 | 25 | func writeContentType(w http.ResponseWriter, value []string) { 26 | header := w.Header() 27 | if val := header["Content-Type"]; len(val) == 0 { 28 | header["Content-Type"] = value 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /github.com/gin-gonic/gin/render/render_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 Manu Martinez-Almeida. All rights reserved. 2 | // Use of this source code is governed by a MIT style 3 | // license that can be found in the LICENSE file. 4 | 5 | package render 6 | 7 | import ( 8 | "encoding/xml" 9 | "html/template" 10 | "net/http/httptest" 11 | "testing" 12 | 13 | "github.com/stretchr/testify/assert" 14 | ) 15 | 16 | // TODO unit tests 17 | // test errors 18 | 19 | func TestRenderJSON(t *testing.T) { 20 | w := httptest.NewRecorder() 21 | data := map[string]interface{}{ 22 | "foo": "bar", 23 | } 24 | 25 | err := (JSON{data}).Render(w) 26 | 27 | assert.NoError(t, err) 28 | assert.Equal(t, w.Body.String(), "{\"foo\":\"bar\"}\n") 29 | assert.Equal(t, w.Header().Get("Content-Type"), "application/json; charset=utf-8") 30 | } 31 | 32 | func TestRenderIndentedJSON(t *testing.T) { 33 | w := httptest.NewRecorder() 34 | data := map[string]interface{}{ 35 | "foo": "bar", 36 | "bar": "foo", 37 | } 38 | 39 | err := (IndentedJSON{data}).Render(w) 40 | 41 | assert.NoError(t, err) 42 | assert.Equal(t, w.Body.String(), "{\n \"bar\": \"foo\",\n \"foo\": \"bar\"\n}") 43 | assert.Equal(t, w.Header().Get("Content-Type"), "application/json; charset=utf-8") 44 | } 45 | 46 | type xmlmap map[string]interface{} 47 | 48 | // Allows type H to be used with xml.Marshal 49 | func (h xmlmap) MarshalXML(e *xml.Encoder, start xml.StartElement) error { 50 | start.Name = xml.Name{ 51 | Space: "", 52 | Local: "map", 53 | } 54 | if err := e.EncodeToken(start); err != nil { 55 | return err 56 | } 57 | for key, value := range h { 58 | elem := xml.StartElement{ 59 | Name: xml.Name{Space: "", Local: key}, 60 | Attr: []xml.Attr{}, 61 | } 62 | if err := e.EncodeElement(value, elem); err != nil { 63 | return err 64 | } 65 | } 66 | if err := e.EncodeToken(xml.EndElement{Name: start.Name}); err != nil { 67 | return err 68 | } 69 | return nil 70 | } 71 | 72 | func TestRenderXML(t *testing.T) { 73 | w := httptest.NewRecorder() 74 | data := xmlmap{ 75 | "foo": "bar", 76 | } 77 | 78 | err := (XML{data}).Render(w) 79 | 80 | assert.NoError(t, err) 81 | assert.Equal(t, w.Body.String(), "bar") 82 | assert.Equal(t, w.Header().Get("Content-Type"), "application/xml; charset=utf-8") 83 | } 84 | 85 | func TestRenderRedirect(t *testing.T) { 86 | // TODO 87 | } 88 | 89 | func TestRenderData(t *testing.T) { 90 | w := httptest.NewRecorder() 91 | data := []byte("#!PNG some raw data") 92 | 93 | err := (Data{ 94 | ContentType: "image/png", 95 | Data: data, 96 | }).Render(w) 97 | 98 | assert.NoError(t, err) 99 | assert.Equal(t, w.Body.String(), "#!PNG some raw data") 100 | assert.Equal(t, w.Header().Get("Content-Type"), "image/png") 101 | } 102 | 103 | func TestRenderString(t *testing.T) { 104 | w := httptest.NewRecorder() 105 | 106 | err := (String{ 107 | Format: "hola %s %d", 108 | Data: []interface{}{"manu", 2}, 109 | }).Render(w) 110 | 111 | assert.NoError(t, err) 112 | assert.Equal(t, w.Body.String(), "hola manu 2") 113 | assert.Equal(t, w.Header().Get("Content-Type"), "text/plain; charset=utf-8") 114 | } 115 | 116 | func TestRenderHTMLTemplate(t *testing.T) { 117 | w := httptest.NewRecorder() 118 | templ := template.Must(template.New("t").Parse(`Hello {{.name}}`)) 119 | 120 | htmlRender := HTMLProduction{Template: templ} 121 | instance := htmlRender.Instance("t", map[string]interface{}{ 122 | "name": "alexandernyquist", 123 | }) 124 | 125 | err := instance.Render(w) 126 | 127 | assert.NoError(t, err) 128 | assert.Equal(t, w.Body.String(), "Hello alexandernyquist") 129 | assert.Equal(t, w.Header().Get("Content-Type"), "text/html; charset=utf-8") 130 | } 131 | -------------------------------------------------------------------------------- /github.com/gin-gonic/gin/render/text.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 Manu Martinez-Almeida. All rights reserved. 2 | // Use of this source code is governed by a MIT style 3 | // license that can be found in the LICENSE file. 4 | 5 | package render 6 | 7 | import ( 8 | "fmt" 9 | "io" 10 | "net/http" 11 | ) 12 | 13 | type String struct { 14 | Format string 15 | Data []interface{} 16 | } 17 | 18 | var plainContentType = []string{"text/plain; charset=utf-8"} 19 | 20 | func (r String) Render(w http.ResponseWriter) error { 21 | WriteString(w, r.Format, r.Data) 22 | return nil 23 | } 24 | 25 | func WriteString(w http.ResponseWriter, format string, data []interface{}) { 26 | writeContentType(w, plainContentType) 27 | 28 | if len(data) > 0 { 29 | fmt.Fprintf(w, format, data...) 30 | } else { 31 | io.WriteString(w, format) 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /github.com/gin-gonic/gin/render/xml.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 Manu Martinez-Almeida. All rights reserved. 2 | // Use of this source code is governed by a MIT style 3 | // license that can be found in the LICENSE file. 4 | 5 | package render 6 | 7 | import ( 8 | "encoding/xml" 9 | "net/http" 10 | ) 11 | 12 | type XML struct { 13 | Data interface{} 14 | } 15 | 16 | var xmlContentType = []string{"application/xml; charset=utf-8"} 17 | 18 | func (r XML) Render(w http.ResponseWriter) error { 19 | writeContentType(w, xmlContentType) 20 | return xml.NewEncoder(w).Encode(r.Data) 21 | } 22 | -------------------------------------------------------------------------------- /github.com/gin-gonic/gin/response_writer.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 Manu Martinez-Almeida. All rights reserved. 2 | // Use of this source code is governed by a MIT style 3 | // license that can be found in the LICENSE file. 4 | 5 | package gin 6 | 7 | import ( 8 | "bufio" 9 | "io" 10 | "net" 11 | "net/http" 12 | ) 13 | 14 | const ( 15 | noWritten = -1 16 | defaultStatus = 200 17 | ) 18 | 19 | type ( 20 | ResponseWriter interface { 21 | http.ResponseWriter 22 | http.Hijacker 23 | http.Flusher 24 | http.CloseNotifier 25 | 26 | // Returns the HTTP response status code of the current request. 27 | Status() int 28 | 29 | // Returns the number of bytes already written into the response http body. 30 | // See Written() 31 | Size() int 32 | 33 | // Writes the string into the response body. 34 | WriteString(string) (int, error) 35 | 36 | // Returns true if the response body was already written. 37 | Written() bool 38 | 39 | // Forces to write the http header (status code + headers). 40 | WriteHeaderNow() 41 | } 42 | 43 | responseWriter struct { 44 | http.ResponseWriter 45 | size int 46 | status int 47 | } 48 | ) 49 | 50 | var _ ResponseWriter = &responseWriter{} 51 | 52 | func (w *responseWriter) reset(writer http.ResponseWriter) { 53 | w.ResponseWriter = writer 54 | w.size = noWritten 55 | w.status = defaultStatus 56 | } 57 | 58 | func (w *responseWriter) WriteHeader(code int) { 59 | if code > 0 && w.status != code { 60 | if w.Written() { 61 | debugPrint("[WARNING] Headers were already written. Wanted to override status code %d with %d", w.status, code) 62 | } 63 | w.status = code 64 | } 65 | } 66 | 67 | func (w *responseWriter) WriteHeaderNow() { 68 | if !w.Written() { 69 | w.size = 0 70 | w.ResponseWriter.WriteHeader(w.status) 71 | } 72 | } 73 | 74 | func (w *responseWriter) Write(data []byte) (n int, err error) { 75 | w.WriteHeaderNow() 76 | n, err = w.ResponseWriter.Write(data) 77 | w.size += n 78 | return 79 | } 80 | 81 | func (w *responseWriter) WriteString(s string) (n int, err error) { 82 | w.WriteHeaderNow() 83 | n, err = io.WriteString(w.ResponseWriter, s) 84 | w.size += n 85 | return 86 | } 87 | 88 | func (w *responseWriter) Status() int { 89 | return w.status 90 | } 91 | 92 | func (w *responseWriter) Size() int { 93 | return w.size 94 | } 95 | 96 | func (w *responseWriter) Written() bool { 97 | return w.size != noWritten 98 | } 99 | 100 | // Implements the http.Hijacker interface 101 | func (w *responseWriter) Hijack() (net.Conn, *bufio.ReadWriter, error) { 102 | if w.size < 0 { 103 | w.size = 0 104 | } 105 | return w.ResponseWriter.(http.Hijacker).Hijack() 106 | } 107 | 108 | // Implements the http.CloseNotify interface 109 | func (w *responseWriter) CloseNotify() <-chan bool { 110 | return w.ResponseWriter.(http.CloseNotifier).CloseNotify() 111 | } 112 | 113 | // Implements the http.Flush interface 114 | func (w *responseWriter) Flush() { 115 | w.ResponseWriter.(http.Flusher).Flush() 116 | } 117 | -------------------------------------------------------------------------------- /github.com/gin-gonic/gin/response_writer_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 Manu Martinez-Almeida. All rights reserved. 2 | // Use of this source code is governed by a MIT style 3 | // license that can be found in the LICENSE file. 4 | 5 | package gin 6 | 7 | import ( 8 | "net/http" 9 | "net/http/httptest" 10 | "testing" 11 | 12 | "github.com/stretchr/testify/assert" 13 | ) 14 | 15 | // TODO 16 | // func (w *responseWriter) Hijack() (net.Conn, *bufio.ReadWriter, error) { 17 | // func (w *responseWriter) CloseNotify() <-chan bool { 18 | // func (w *responseWriter) Flush() { 19 | 20 | var _ ResponseWriter = &responseWriter{} 21 | var _ http.ResponseWriter = &responseWriter{} 22 | var _ http.ResponseWriter = ResponseWriter(&responseWriter{}) 23 | var _ http.Hijacker = ResponseWriter(&responseWriter{}) 24 | var _ http.Flusher = ResponseWriter(&responseWriter{}) 25 | var _ http.CloseNotifier = ResponseWriter(&responseWriter{}) 26 | 27 | func init() { 28 | SetMode(TestMode) 29 | } 30 | 31 | func TestResponseWriterReset(t *testing.T) { 32 | testWritter := httptest.NewRecorder() 33 | writer := &responseWriter{} 34 | var w ResponseWriter = writer 35 | 36 | writer.reset(testWritter) 37 | assert.Equal(t, writer.size, -1) 38 | assert.Equal(t, writer.status, 200) 39 | assert.Equal(t, writer.ResponseWriter, testWritter) 40 | assert.Equal(t, w.Size(), -1) 41 | assert.Equal(t, w.Status(), 200) 42 | assert.False(t, w.Written()) 43 | } 44 | 45 | func TestResponseWriterWriteHeader(t *testing.T) { 46 | testWritter := httptest.NewRecorder() 47 | writer := &responseWriter{} 48 | writer.reset(testWritter) 49 | w := ResponseWriter(writer) 50 | 51 | w.WriteHeader(300) 52 | assert.False(t, w.Written()) 53 | assert.Equal(t, w.Status(), 300) 54 | assert.NotEqual(t, testWritter.Code, 300) 55 | 56 | w.WriteHeader(-1) 57 | assert.Equal(t, w.Status(), 300) 58 | } 59 | 60 | func TestResponseWriterWriteHeadersNow(t *testing.T) { 61 | testWritter := httptest.NewRecorder() 62 | writer := &responseWriter{} 63 | writer.reset(testWritter) 64 | w := ResponseWriter(writer) 65 | 66 | w.WriteHeader(300) 67 | w.WriteHeaderNow() 68 | 69 | assert.True(t, w.Written()) 70 | assert.Equal(t, w.Size(), 0) 71 | assert.Equal(t, testWritter.Code, 300) 72 | 73 | writer.size = 10 74 | w.WriteHeaderNow() 75 | assert.Equal(t, w.Size(), 10) 76 | } 77 | 78 | func TestResponseWriterWrite(t *testing.T) { 79 | testWritter := httptest.NewRecorder() 80 | writer := &responseWriter{} 81 | writer.reset(testWritter) 82 | w := ResponseWriter(writer) 83 | 84 | n, err := w.Write([]byte("hola")) 85 | assert.Equal(t, n, 4) 86 | assert.Equal(t, w.Size(), 4) 87 | assert.Equal(t, w.Status(), 200) 88 | assert.Equal(t, testWritter.Code, 200) 89 | assert.Equal(t, testWritter.Body.String(), "hola") 90 | assert.NoError(t, err) 91 | 92 | n, err = w.Write([]byte(" adios")) 93 | assert.Equal(t, n, 6) 94 | assert.Equal(t, w.Size(), 10) 95 | assert.Equal(t, testWritter.Body.String(), "hola adios") 96 | assert.NoError(t, err) 97 | } 98 | 99 | func TestResponseWriterHijack(t *testing.T) { 100 | testWritter := httptest.NewRecorder() 101 | writer := &responseWriter{} 102 | writer.reset(testWritter) 103 | w := ResponseWriter(writer) 104 | 105 | assert.Panics(t, func() { 106 | w.Hijack() 107 | }) 108 | assert.True(t, w.Written()) 109 | 110 | assert.Panics(t, func() { 111 | w.CloseNotify() 112 | }) 113 | 114 | w.Flush() 115 | } 116 | -------------------------------------------------------------------------------- /github.com/gin-gonic/gin/test_helpers.go: -------------------------------------------------------------------------------- 1 | package gin 2 | 3 | import ( 4 | "net/http/httptest" 5 | ) 6 | 7 | func CreateTestContext() (c *Context, w *httptest.ResponseRecorder, r *Engine) { 8 | w = httptest.NewRecorder() 9 | r = New() 10 | c = r.allocateContext() 11 | c.reset() 12 | c.writermem.reset(w) 13 | return 14 | } 15 | -------------------------------------------------------------------------------- /github.com/gin-gonic/gin/wercker.yml: -------------------------------------------------------------------------------- 1 | box: wercker/default -------------------------------------------------------------------------------- /github.com/go-playground/validator/.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled Object files, Static and Dynamic libs (Shared Objects) 2 | *.o 3 | *.a 4 | *.so 5 | 6 | # Folders 7 | _obj 8 | _test 9 | 10 | # Architecture specific extensions/prefixes 11 | *.[568vq] 12 | [568vq].out 13 | 14 | *.cgo1.go 15 | *.cgo2.c 16 | _cgo_defun.c 17 | _cgo_gotypes.go 18 | _cgo_export.* 19 | 20 | _testmain.go 21 | 22 | *.exe 23 | *.test 24 | *.prof 25 | *.test 26 | *.out 27 | *.txt 28 | cover.html 29 | README.html -------------------------------------------------------------------------------- /github.com/go-playground/validator/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Dean Karn 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /github.com/go-playground/validator/cache.go: -------------------------------------------------------------------------------- 1 | package validator 2 | 3 | import ( 4 | "reflect" 5 | "sync" 6 | ) 7 | 8 | type cachedField struct { 9 | Idx int 10 | Name string 11 | AltName string 12 | CachedTag *cachedTag 13 | } 14 | 15 | type cachedStruct struct { 16 | Name string 17 | fields map[int]cachedField 18 | } 19 | 20 | type structCacheMap struct { 21 | lock sync.RWMutex 22 | m map[reflect.Type]*cachedStruct 23 | } 24 | 25 | func (s *structCacheMap) Get(key reflect.Type) (*cachedStruct, bool) { 26 | s.lock.RLock() 27 | value, ok := s.m[key] 28 | s.lock.RUnlock() 29 | return value, ok 30 | } 31 | 32 | func (s *structCacheMap) Set(key reflect.Type, value *cachedStruct) { 33 | s.lock.Lock() 34 | s.m[key] = value 35 | s.lock.Unlock() 36 | } 37 | 38 | type cachedTag struct { 39 | tag string 40 | isOmitEmpty bool 41 | isNoStructLevel bool 42 | isStructOnly bool 43 | diveTag string 44 | tags []*tagVals 45 | } 46 | 47 | type tagVals struct { 48 | tagVals [][]string 49 | isOrVal bool 50 | isAlias bool 51 | tag string 52 | } 53 | 54 | type tagCacheMap struct { 55 | lock sync.RWMutex 56 | m map[string]*cachedTag 57 | } 58 | 59 | func (s *tagCacheMap) Get(key string) (*cachedTag, bool) { 60 | s.lock.RLock() 61 | value, ok := s.m[key] 62 | s.lock.RUnlock() 63 | 64 | return value, ok 65 | } 66 | 67 | func (s *tagCacheMap) Set(key string, value *cachedTag) { 68 | s.lock.Lock() 69 | s.m[key] = value 70 | s.lock.Unlock() 71 | } 72 | -------------------------------------------------------------------------------- /github.com/go-playground/validator/examples/custom/custom.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "database/sql" 5 | "database/sql/driver" 6 | "fmt" 7 | "reflect" 8 | 9 | "gopkg.in/go-playground/validator.v8" 10 | ) 11 | 12 | // DbBackedUser User struct 13 | type DbBackedUser struct { 14 | Name sql.NullString `validate:"required"` 15 | Age sql.NullInt64 `validate:"required"` 16 | } 17 | 18 | func main() { 19 | 20 | config := &validator.Config{TagName: "validate"} 21 | 22 | validate := validator.New(config) 23 | 24 | // register all sql.Null* types to use the ValidateValuer CustomTypeFunc 25 | validate.RegisterCustomTypeFunc(ValidateValuer, sql.NullString{}, sql.NullInt64{}, sql.NullBool{}, sql.NullFloat64{}) 26 | 27 | x := DbBackedUser{Name: sql.NullString{String: "", Valid: true}, Age: sql.NullInt64{Int64: 0, Valid: false}} 28 | errs := validate.Struct(x) 29 | 30 | if errs != nil { 31 | fmt.Printf("Errs:\n%+v\n", errs) 32 | } 33 | } 34 | 35 | // ValidateValuer implements validator.CustomTypeFunc 36 | func ValidateValuer(field reflect.Value) interface{} { 37 | if valuer, ok := field.Interface().(driver.Valuer); ok { 38 | val, err := valuer.Value() 39 | if err == nil { 40 | return val 41 | } 42 | // handle the error how you want 43 | } 44 | return nil 45 | } 46 | -------------------------------------------------------------------------------- /github.com/go-playground/validator/examples/struct-level/struct_level.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "reflect" 6 | 7 | "gopkg.in/go-playground/validator.v8" 8 | ) 9 | 10 | // User contains user information 11 | type User struct { 12 | FirstName string `json:"fname"` 13 | LastName string `json:"lname"` 14 | Age uint8 `validate:"gte=0,lte=130"` 15 | Email string `validate:"required,email"` 16 | FavouriteColor string `validate:"hexcolor|rgb|rgba"` 17 | Addresses []*Address `validate:"required,dive,required"` // a person can have a home and cottage... 18 | } 19 | 20 | // Address houses a users address information 21 | type Address struct { 22 | Street string `validate:"required"` 23 | City string `validate:"required"` 24 | Planet string `validate:"required"` 25 | Phone string `validate:"required"` 26 | } 27 | 28 | var validate *validator.Validate 29 | 30 | func main() { 31 | 32 | config := &validator.Config{TagName: "validate"} 33 | 34 | validate = validator.New(config) 35 | validate.RegisterStructValidation(UserStructLevelValidation, User{}) 36 | 37 | validateStruct() 38 | } 39 | 40 | // UserStructLevelValidation contains custom struct level validations that don't always 41 | // make sense at the field validation level. For Example this function validates that either 42 | // FirstName or LastName exist; could have done that with a custom field validation but then 43 | // would have had to add it to both fields duplicating the logic + overhead, this way it's 44 | // only validated once. 45 | // 46 | // NOTE: you may ask why wouldn't I just do this outside of validator, because doing this way 47 | // hooks right into validator and you can combine with validation tags and still have a 48 | // common error output format. 49 | func UserStructLevelValidation(v *validator.Validate, structLevel *validator.StructLevel) { 50 | 51 | user := structLevel.CurrentStruct.Interface().(User) 52 | 53 | if len(user.FirstName) == 0 && len(user.LastName) == 0 { 54 | structLevel.ReportError(reflect.ValueOf(user.FirstName), "FirstName", "fname", "fnameorlname") 55 | structLevel.ReportError(reflect.ValueOf(user.LastName), "LastName", "lname", "fnameorlname") 56 | } 57 | 58 | // plus can to more, even with different tag than "fnameorlname" 59 | } 60 | 61 | func validateStruct() { 62 | 63 | address := &Address{ 64 | Street: "Eavesdown Docks", 65 | Planet: "Persphone", 66 | Phone: "none", 67 | City: "Unknown", 68 | } 69 | 70 | user := &User{ 71 | FirstName: "", 72 | LastName: "", 73 | Age: 45, 74 | Email: "Badger.Smith@gmail.com", 75 | FavouriteColor: "#000", 76 | Addresses: []*Address{address}, 77 | } 78 | 79 | // returns nil or ValidationErrors ( map[string]*FieldError ) 80 | errs := validate.Struct(user) 81 | 82 | if errs != nil { 83 | 84 | fmt.Println(errs) // output: Key: 'User.LastName' Error:Field validation for 'LastName' failed on the 'fnameorlname' tag 85 | // Key: 'User.FirstName' Error:Field validation for 'FirstName' failed on the 'fnameorlname' tag 86 | err := errs.(validator.ValidationErrors)["User.FirstName"] 87 | fmt.Println(err.Field) // output: FirstName 88 | fmt.Println(err.Tag) // output: fnameorlname 89 | fmt.Println(err.Kind) // output: string 90 | fmt.Println(err.Type) // output: string 91 | fmt.Println(err.Param) // output: 92 | fmt.Println(err.Value) // output: 93 | 94 | // from here you can create your own error messages in whatever language you wish 95 | return 96 | } 97 | 98 | // save user to database 99 | } 100 | -------------------------------------------------------------------------------- /github.com/go-playground/validator/examples_test.go: -------------------------------------------------------------------------------- 1 | package validator_test 2 | 3 | import ( 4 | "fmt" 5 | 6 | "gopkg.in/go-playground/validator.v8" 7 | ) 8 | 9 | func ExampleValidate_new() { 10 | config := &validator.Config{TagName: "validate"} 11 | 12 | validator.New(config) 13 | } 14 | 15 | func ExampleValidate_field() { 16 | // This should be stored somewhere globally 17 | var validate *validator.Validate 18 | 19 | config := &validator.Config{TagName: "validate"} 20 | 21 | validate = validator.New(config) 22 | 23 | i := 0 24 | errs := validate.Field(i, "gt=1,lte=10") 25 | err := errs.(validator.ValidationErrors)[""] 26 | fmt.Println(err.Field) 27 | fmt.Println(err.Tag) 28 | fmt.Println(err.Kind) // NOTE: Kind and Type can be different i.e. time Kind=struct and Type=time.Time 29 | fmt.Println(err.Type) 30 | fmt.Println(err.Param) 31 | fmt.Println(err.Value) 32 | //Output: 33 | // 34 | //gt 35 | //int 36 | //int 37 | //1 38 | //0 39 | } 40 | 41 | func ExampleValidate_struct() { 42 | // This should be stored somewhere globally 43 | var validate *validator.Validate 44 | 45 | config := &validator.Config{TagName: "validate"} 46 | 47 | validate = validator.New(config) 48 | 49 | type ContactInformation struct { 50 | Phone string `validate:"required"` 51 | Street string `validate:"required"` 52 | City string `validate:"required"` 53 | } 54 | 55 | type User struct { 56 | Name string `validate:"required,excludesall=!@#$%^&*()_+-=:;?/0x2C"` // 0x2C = comma (,) 57 | Age int8 `validate:"required,gt=0,lt=150"` 58 | Email string `validate:"email"` 59 | ContactInformation []*ContactInformation 60 | } 61 | 62 | contactInfo := &ContactInformation{ 63 | Street: "26 Here Blvd.", 64 | City: "Paradeso", 65 | } 66 | 67 | user := &User{ 68 | Name: "Joey Bloggs", 69 | Age: 31, 70 | Email: "joeybloggs@gmail.com", 71 | ContactInformation: []*ContactInformation{contactInfo}, 72 | } 73 | 74 | errs := validate.Struct(user) 75 | for _, v := range errs.(validator.ValidationErrors) { 76 | fmt.Println(v.Field) // Phone 77 | fmt.Println(v.Tag) // required 78 | //... and so forth 79 | //Output: 80 | //Phone 81 | //required 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /github.com/go-playground/validator/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yalay/go-thumbnail/4c72c077e1308a1d176cfba1990200b7dc2d7a52/github.com/go-playground/validator/logo.png -------------------------------------------------------------------------------- /github.com/golang/image/riff/example_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package riff_test 6 | 7 | import ( 8 | "fmt" 9 | "io" 10 | "io/ioutil" 11 | "log" 12 | "strings" 13 | 14 | "golang.org/x/image/riff" 15 | ) 16 | 17 | func ExampleReader() { 18 | formType, r, err := riff.NewReader(strings.NewReader(data)) 19 | if err != nil { 20 | log.Fatal(err) 21 | } 22 | fmt.Printf("RIFF(%s)\n", formType) 23 | if err := dump(r, ".\t"); err != nil { 24 | log.Fatal(err) 25 | } 26 | // Output: 27 | // RIFF(ROOT) 28 | // . ZERO "" 29 | // . ONE "a" 30 | // . LIST(META) 31 | // . . LIST(GOOD) 32 | // . . . ONE "a" 33 | // . . . FIVE "klmno" 34 | // . . ZERO "" 35 | // . . LIST(BAD ) 36 | // . . . THRE "def" 37 | // . TWO "bc" 38 | // . LIST(UGLY) 39 | // . . FOUR "ghij" 40 | // . . SIX "pqrstu" 41 | } 42 | 43 | func dump(r *riff.Reader, indent string) error { 44 | for { 45 | chunkID, chunkLen, chunkData, err := r.Next() 46 | if err == io.EOF { 47 | return nil 48 | } 49 | if err != nil { 50 | return err 51 | } 52 | if chunkID == riff.LIST { 53 | listType, list, err := riff.NewListReader(chunkLen, chunkData) 54 | if err != nil { 55 | return err 56 | } 57 | fmt.Printf("%sLIST(%s)\n", indent, listType) 58 | if err := dump(list, indent+".\t"); err != nil { 59 | return err 60 | } 61 | continue 62 | } 63 | b, err := ioutil.ReadAll(chunkData) 64 | if err != nil { 65 | return err 66 | } 67 | fmt.Printf("%s%s %q\n", indent, chunkID, b) 68 | } 69 | } 70 | 71 | func encodeU32(u uint32) string { 72 | return string([]byte{ 73 | byte(u >> 0), 74 | byte(u >> 8), 75 | byte(u >> 16), 76 | byte(u >> 24), 77 | }) 78 | } 79 | 80 | func encode(chunkID, contents string) string { 81 | n := len(contents) 82 | if n&1 == 1 { 83 | contents += "\x00" 84 | } 85 | return chunkID + encodeU32(uint32(n)) + contents 86 | } 87 | 88 | func encodeMulti(typ0, typ1 string, chunks ...string) string { 89 | n := 4 90 | for _, c := range chunks { 91 | n += len(c) 92 | } 93 | s := typ0 + encodeU32(uint32(n)) + typ1 94 | for _, c := range chunks { 95 | s += c 96 | } 97 | return s 98 | } 99 | 100 | var ( 101 | d0 = encode("ZERO", "") 102 | d1 = encode("ONE ", "a") 103 | d2 = encode("TWO ", "bc") 104 | d3 = encode("THRE", "def") 105 | d4 = encode("FOUR", "ghij") 106 | d5 = encode("FIVE", "klmno") 107 | d6 = encode("SIX ", "pqrstu") 108 | l0 = encodeMulti("LIST", "GOOD", d1, d5) 109 | l1 = encodeMulti("LIST", "BAD ", d3) 110 | l2 = encodeMulti("LIST", "UGLY", d4, d6) 111 | l01 = encodeMulti("LIST", "META", l0, d0, l1) 112 | data = encodeMulti("RIFF", "ROOT", d0, d1, l01, d2, l2) 113 | ) 114 | -------------------------------------------------------------------------------- /github.com/golang/image/riff/riff_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2016 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package riff 6 | 7 | import ( 8 | "bytes" 9 | "testing" 10 | ) 11 | 12 | func encodeU32(u uint32) []byte { 13 | return []byte{ 14 | byte(u >> 0), 15 | byte(u >> 8), 16 | byte(u >> 16), 17 | byte(u >> 24), 18 | } 19 | } 20 | 21 | func TestShortChunks(t *testing.T) { 22 | // s is a RIFF(ABCD) with allegedly 256 bytes of data (excluding the 23 | // leading 8-byte "RIFF\x00\x01\x00\x00"). The first chunk of that ABCD 24 | // list is an abcd chunk of length m followed by n zeroes. 25 | for _, m := range []uint32{0, 8, 15, 200, 300} { 26 | for _, n := range []int{0, 1, 2, 7} { 27 | s := []byte("RIFF\x00\x01\x00\x00ABCDabcd") 28 | s = append(s, encodeU32(m)...) 29 | s = append(s, make([]byte, n)...) 30 | _, r, err := NewReader(bytes.NewReader(s)) 31 | if err != nil { 32 | t.Errorf("m=%d, n=%d: NewReader: %v", m, n, err) 33 | continue 34 | } 35 | 36 | _, _, _, err0 := r.Next() 37 | // The total "ABCD" list length is 256 bytes, of which the first 12 38 | // bytes are "ABCDabcd" plus the 4-byte encoding of m. If the 39 | // "abcd" subchunk length (m) plus those 12 bytes is greater than 40 | // the total list length, we have an invalid RIFF, and we expect an 41 | // errListSubchunkTooLong error. 42 | if m+12 > 256 { 43 | if err0 != errListSubchunkTooLong { 44 | t.Errorf("m=%d, n=%d: Next #0: got %v, want %v", m, n, err0, errListSubchunkTooLong) 45 | } 46 | continue 47 | } 48 | // Otherwise, we expect a nil error. 49 | if err0 != nil { 50 | t.Errorf("m=%d, n=%d: Next #0: %v", m, n, err0) 51 | continue 52 | } 53 | 54 | _, _, _, err1 := r.Next() 55 | // If m > 0, then m > n, so that "abcd" subchunk doesn't have m 56 | // bytes of data. If m == 0, then that "abcd" subchunk is OK in 57 | // that it has 0 extra bytes of data, but the next subchunk (8 byte 58 | // header plus body) is missing, as we only have n < 8 more bytes. 59 | want := errShortChunkData 60 | if m == 0 { 61 | want = errShortChunkHeader 62 | } 63 | if err1 != want { 64 | t.Errorf("m=%d, n=%d: Next #1: got %v, want %v", m, n, err1, want) 65 | continue 66 | } 67 | } 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /github.com/golang/image/vp8/idct.go: -------------------------------------------------------------------------------- 1 | // Copyright 2011 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package vp8 6 | 7 | // This file implements the inverse Discrete Cosine Transform and the inverse 8 | // Walsh Hadamard Transform (WHT), as specified in sections 14.3 and 14.4. 9 | 10 | func clip8(i int32) uint8 { 11 | if i < 0 { 12 | return 0 13 | } 14 | if i > 255 { 15 | return 255 16 | } 17 | return uint8(i) 18 | } 19 | 20 | func (z *Decoder) inverseDCT4(y, x, coeffBase int) { 21 | const ( 22 | c1 = 85627 // 65536 * cos(pi/8) * sqrt(2). 23 | c2 = 35468 // 65536 * sin(pi/8) * sqrt(2). 24 | ) 25 | var m [4][4]int32 26 | for i := 0; i < 4; i++ { 27 | a := int32(z.coeff[coeffBase+0]) + int32(z.coeff[coeffBase+8]) 28 | b := int32(z.coeff[coeffBase+0]) - int32(z.coeff[coeffBase+8]) 29 | c := (int32(z.coeff[coeffBase+4])*c2)>>16 - (int32(z.coeff[coeffBase+12])*c1)>>16 30 | d := (int32(z.coeff[coeffBase+4])*c1)>>16 + (int32(z.coeff[coeffBase+12])*c2)>>16 31 | m[i][0] = a + d 32 | m[i][1] = b + c 33 | m[i][2] = b - c 34 | m[i][3] = a - d 35 | coeffBase++ 36 | } 37 | for j := 0; j < 4; j++ { 38 | dc := m[0][j] + 4 39 | a := dc + m[2][j] 40 | b := dc - m[2][j] 41 | c := (m[1][j]*c2)>>16 - (m[3][j]*c1)>>16 42 | d := (m[1][j]*c1)>>16 + (m[3][j]*c2)>>16 43 | z.ybr[y+j][x+0] = clip8(int32(z.ybr[y+j][x+0]) + (a+d)>>3) 44 | z.ybr[y+j][x+1] = clip8(int32(z.ybr[y+j][x+1]) + (b+c)>>3) 45 | z.ybr[y+j][x+2] = clip8(int32(z.ybr[y+j][x+2]) + (b-c)>>3) 46 | z.ybr[y+j][x+3] = clip8(int32(z.ybr[y+j][x+3]) + (a-d)>>3) 47 | } 48 | } 49 | 50 | func (z *Decoder) inverseDCT4DCOnly(y, x, coeffBase int) { 51 | dc := (int32(z.coeff[coeffBase+0]) + 4) >> 3 52 | for j := 0; j < 4; j++ { 53 | for i := 0; i < 4; i++ { 54 | z.ybr[y+j][x+i] = clip8(int32(z.ybr[y+j][x+i]) + dc) 55 | } 56 | } 57 | } 58 | 59 | func (z *Decoder) inverseDCT8(y, x, coeffBase int) { 60 | z.inverseDCT4(y+0, x+0, coeffBase+0*16) 61 | z.inverseDCT4(y+0, x+4, coeffBase+1*16) 62 | z.inverseDCT4(y+4, x+0, coeffBase+2*16) 63 | z.inverseDCT4(y+4, x+4, coeffBase+3*16) 64 | } 65 | 66 | func (z *Decoder) inverseDCT8DCOnly(y, x, coeffBase int) { 67 | z.inverseDCT4DCOnly(y+0, x+0, coeffBase+0*16) 68 | z.inverseDCT4DCOnly(y+0, x+4, coeffBase+1*16) 69 | z.inverseDCT4DCOnly(y+4, x+0, coeffBase+2*16) 70 | z.inverseDCT4DCOnly(y+4, x+4, coeffBase+3*16) 71 | } 72 | 73 | func (d *Decoder) inverseWHT16() { 74 | var m [16]int32 75 | for i := 0; i < 4; i++ { 76 | a0 := int32(d.coeff[384+0+i]) + int32(d.coeff[384+12+i]) 77 | a1 := int32(d.coeff[384+4+i]) + int32(d.coeff[384+8+i]) 78 | a2 := int32(d.coeff[384+4+i]) - int32(d.coeff[384+8+i]) 79 | a3 := int32(d.coeff[384+0+i]) - int32(d.coeff[384+12+i]) 80 | m[0+i] = a0 + a1 81 | m[8+i] = a0 - a1 82 | m[4+i] = a3 + a2 83 | m[12+i] = a3 - a2 84 | } 85 | out := 0 86 | for i := 0; i < 4; i++ { 87 | dc := m[0+i*4] + 3 88 | a0 := dc + m[3+i*4] 89 | a1 := m[1+i*4] + m[2+i*4] 90 | a2 := m[1+i*4] - m[2+i*4] 91 | a3 := dc - m[3+i*4] 92 | d.coeff[out+0] = int16((a0 + a1) >> 3) 93 | d.coeff[out+16] = int16((a3 + a2) >> 3) 94 | d.coeff[out+32] = int16((a0 - a1) >> 3) 95 | d.coeff[out+48] = int16((a3 - a2) >> 3) 96 | out += 64 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /github.com/golang/image/vp8/quant.go: -------------------------------------------------------------------------------- 1 | // Copyright 2011 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package vp8 6 | 7 | // This file implements parsing the quantization factors. 8 | 9 | // quant are DC/AC quantization factors. 10 | type quant struct { 11 | y1 [2]uint16 12 | y2 [2]uint16 13 | uv [2]uint16 14 | } 15 | 16 | // clip clips x to the range [min, max] inclusive. 17 | func clip(x, min, max int32) int32 { 18 | if x < min { 19 | return min 20 | } 21 | if x > max { 22 | return max 23 | } 24 | return x 25 | } 26 | 27 | // parseQuant parses the quantization factors, as specified in section 9.6. 28 | func (d *Decoder) parseQuant() { 29 | baseQ0 := d.fp.readUint(uniformProb, 7) 30 | dqy1DC := d.fp.readOptionalInt(uniformProb, 4) 31 | const dqy1AC = 0 32 | dqy2DC := d.fp.readOptionalInt(uniformProb, 4) 33 | dqy2AC := d.fp.readOptionalInt(uniformProb, 4) 34 | dquvDC := d.fp.readOptionalInt(uniformProb, 4) 35 | dquvAC := d.fp.readOptionalInt(uniformProb, 4) 36 | for i := 0; i < nSegment; i++ { 37 | q := int32(baseQ0) 38 | if d.segmentHeader.useSegment { 39 | if d.segmentHeader.relativeDelta { 40 | q += int32(d.segmentHeader.quantizer[i]) 41 | } else { 42 | q = int32(d.segmentHeader.quantizer[i]) 43 | } 44 | } 45 | d.quant[i].y1[0] = dequantTableDC[clip(q+dqy1DC, 0, 127)] 46 | d.quant[i].y1[1] = dequantTableAC[clip(q+dqy1AC, 0, 127)] 47 | d.quant[i].y2[0] = dequantTableDC[clip(q+dqy2DC, 0, 127)] * 2 48 | d.quant[i].y2[1] = dequantTableAC[clip(q+dqy2AC, 0, 127)] * 155 / 100 49 | if d.quant[i].y2[1] < 8 { 50 | d.quant[i].y2[1] = 8 51 | } 52 | // The 117 is not a typo. The dequant_init function in the spec's Reference 53 | // Decoder Source Code (http://tools.ietf.org/html/rfc6386#section-9.6 Page 145) 54 | // says to clamp the LHS value at 132, which is equal to dequantTableDC[117]. 55 | d.quant[i].uv[0] = dequantTableDC[clip(q+dquvDC, 0, 117)] 56 | d.quant[i].uv[1] = dequantTableAC[clip(q+dquvAC, 0, 127)] 57 | } 58 | } 59 | 60 | // The dequantization tables are specified in section 14.1. 61 | var ( 62 | dequantTableDC = [128]uint16{ 63 | 4, 5, 6, 7, 8, 9, 10, 10, 64 | 11, 12, 13, 14, 15, 16, 17, 17, 65 | 18, 19, 20, 20, 21, 21, 22, 22, 66 | 23, 23, 24, 25, 25, 26, 27, 28, 67 | 29, 30, 31, 32, 33, 34, 35, 36, 68 | 37, 37, 38, 39, 40, 41, 42, 43, 69 | 44, 45, 46, 46, 47, 48, 49, 50, 70 | 51, 52, 53, 54, 55, 56, 57, 58, 71 | 59, 60, 61, 62, 63, 64, 65, 66, 72 | 67, 68, 69, 70, 71, 72, 73, 74, 73 | 75, 76, 76, 77, 78, 79, 80, 81, 74 | 82, 83, 84, 85, 86, 87, 88, 89, 75 | 91, 93, 95, 96, 98, 100, 101, 102, 76 | 104, 106, 108, 110, 112, 114, 116, 118, 77 | 122, 124, 126, 128, 130, 132, 134, 136, 78 | 138, 140, 143, 145, 148, 151, 154, 157, 79 | } 80 | dequantTableAC = [128]uint16{ 81 | 4, 5, 6, 7, 8, 9, 10, 11, 82 | 12, 13, 14, 15, 16, 17, 18, 19, 83 | 20, 21, 22, 23, 24, 25, 26, 27, 84 | 28, 29, 30, 31, 32, 33, 34, 35, 85 | 36, 37, 38, 39, 40, 41, 42, 43, 86 | 44, 45, 46, 47, 48, 49, 50, 51, 87 | 52, 53, 54, 55, 56, 57, 58, 60, 88 | 62, 64, 66, 68, 70, 72, 74, 76, 89 | 78, 80, 82, 84, 86, 88, 90, 92, 90 | 94, 96, 98, 100, 102, 104, 106, 108, 91 | 110, 112, 114, 116, 119, 122, 125, 128, 92 | 131, 134, 137, 140, 143, 146, 149, 152, 93 | 155, 158, 161, 164, 167, 170, 173, 177, 94 | 181, 185, 189, 193, 197, 201, 205, 209, 95 | 213, 217, 221, 225, 229, 234, 239, 245, 96 | 249, 254, 259, 264, 269, 274, 279, 284, 97 | } 98 | ) 99 | -------------------------------------------------------------------------------- /github.com/golang/image/webp/webp.go: -------------------------------------------------------------------------------- 1 | // Copyright 2016 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // Package webp implements a decoder for WEBP images. 6 | // 7 | // WEBP is defined at: 8 | // https://developers.google.com/speed/webp/docs/riff_container 9 | // 10 | // It requires Go 1.6 or later. 11 | package webp 12 | 13 | // This blank Go file, other than the package clause, exists so that this 14 | // package can be built for Go 1.5 and earlier. (The other files in this 15 | // package are all marked "+build go1.6" for the NYCbCrA types introduced in Go 16 | // 1.6). There is no functionality in a blank package, but some image 17 | // manipulation programs might still underscore import this package for the 18 | // side effect of registering the WEBP format with the standard library's 19 | // image.RegisterFormat and image.Decode functions. For example, that program 20 | // might contain: 21 | // 22 | // // Underscore imports to register some formats for image.Decode. 23 | // import _ "image/gif" 24 | // import _ "image/jpeg" 25 | // import _ "image/png" 26 | // import _ "golang.org/x/image/webp" 27 | // 28 | // Such a program will still compile for Go 1.5 (due to this placeholder Go 29 | // file). It will simply not be able to recognize and decode WEBP (but still 30 | // handle GIF, JPEG and PNG). 31 | -------------------------------------------------------------------------------- /github.com/golang/net/context/ctxhttp/cancelreq.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build go1.5 6 | 7 | package ctxhttp 8 | 9 | import "net/http" 10 | 11 | func canceler(client *http.Client, req *http.Request) func() { 12 | // TODO(djd): Respect any existing value of req.Cancel. 13 | ch := make(chan struct{}) 14 | req.Cancel = ch 15 | 16 | return func() { 17 | close(ch) 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /github.com/golang/net/context/ctxhttp/cancelreq_go14.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build !go1.5 6 | 7 | package ctxhttp 8 | 9 | import "net/http" 10 | 11 | type requestCanceler interface { 12 | CancelRequest(*http.Request) 13 | } 14 | 15 | func canceler(client *http.Client, req *http.Request) func() { 16 | rc, ok := client.Transport.(requestCanceler) 17 | if !ok { 18 | return func() {} 19 | } 20 | return func() { 21 | rc.CancelRequest(req) 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /github.com/golang/net/context/withtimeout_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package context_test 6 | 7 | import ( 8 | "fmt" 9 | "time" 10 | 11 | "golang.org/x/net/context" 12 | ) 13 | 14 | func ExampleWithTimeout() { 15 | // Pass a context with a timeout to tell a blocking function that it 16 | // should abandon its work after the timeout elapses. 17 | ctx, _ := context.WithTimeout(context.Background(), 100*time.Millisecond) 18 | select { 19 | case <-time.After(200 * time.Millisecond): 20 | fmt.Println("overslept") 21 | case <-ctx.Done(): 22 | fmt.Println(ctx.Err()) // prints "context deadline exceeded" 23 | } 24 | // Output: 25 | // context deadline exceeded 26 | } 27 | -------------------------------------------------------------------------------- /github.com/golang/protobuf/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | *.[568ao] 3 | *.pb.go 4 | *.ao 5 | *.so 6 | *.pyc 7 | ._* 8 | .nfs.* 9 | [568a].out 10 | *~ 11 | *.orig 12 | core 13 | _obj 14 | _test 15 | _testmain.go 16 | compiler/protoc-gen-go 17 | compiler/testdata/extension_test 18 | -------------------------------------------------------------------------------- /github.com/golang/protobuf/AUTHORS: -------------------------------------------------------------------------------- 1 | # This source code refers to The Go Authors for copyright purposes. 2 | # The master list of authors is in the main Go distribution, 3 | # visible at http://tip.golang.org/AUTHORS. 4 | -------------------------------------------------------------------------------- /github.com/golang/protobuf/CONTRIBUTORS: -------------------------------------------------------------------------------- 1 | # This source code was written by the Go contributors. 2 | # The master list of contributors is in the main Go distribution, 3 | # visible at http://tip.golang.org/CONTRIBUTORS. 4 | -------------------------------------------------------------------------------- /github.com/golang/protobuf/LICENSE: -------------------------------------------------------------------------------- 1 | Go support for Protocol Buffers - Google's data interchange format 2 | 3 | Copyright 2010 The Go Authors. All rights reserved. 4 | https://github.com/golang/protobuf 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are 8 | met: 9 | 10 | * Redistributions of source code must retain the above copyright 11 | notice, this list of conditions and the following disclaimer. 12 | * Redistributions in binary form must reproduce the above 13 | copyright notice, this list of conditions and the following disclaimer 14 | in the documentation and/or other materials provided with the 15 | distribution. 16 | * Neither the name of Google Inc. nor the names of its 17 | contributors may be used to endorse or promote products derived from 18 | this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | 32 | -------------------------------------------------------------------------------- /github.com/golang/protobuf/Make.protobuf: -------------------------------------------------------------------------------- 1 | # Go support for Protocol Buffers - Google's data interchange format 2 | # 3 | # Copyright 2010 The Go Authors. All rights reserved. 4 | # https://github.com/golang/protobuf 5 | # 6 | # Redistribution and use in source and binary forms, with or without 7 | # modification, are permitted provided that the following conditions are 8 | # met: 9 | # 10 | # * Redistributions of source code must retain the above copyright 11 | # notice, this list of conditions and the following disclaimer. 12 | # * Redistributions in binary form must reproduce the above 13 | # copyright notice, this list of conditions and the following disclaimer 14 | # in the documentation and/or other materials provided with the 15 | # distribution. 16 | # * Neither the name of Google Inc. nor the names of its 17 | # contributors may be used to endorse or promote products derived from 18 | # this software without specific prior written permission. 19 | # 20 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 | # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 | # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 | # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 | # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 | # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 | # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 | # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 | # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 | # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | 32 | # Includable Makefile to add a rule for generating .pb.go files from .proto files 33 | # (Google protocol buffer descriptions). 34 | # Typical use if myproto.proto is a file in package mypackage in this directory: 35 | # 36 | # include $(GOROOT)/src/pkg/github.com/golang/protobuf/Make.protobuf 37 | 38 | %.pb.go: %.proto 39 | protoc --go_out=. $< 40 | 41 | -------------------------------------------------------------------------------- /github.com/golang/protobuf/Makefile: -------------------------------------------------------------------------------- 1 | # Go support for Protocol Buffers - Google's data interchange format 2 | # 3 | # Copyright 2010 The Go Authors. All rights reserved. 4 | # https://github.com/golang/protobuf 5 | # 6 | # Redistribution and use in source and binary forms, with or without 7 | # modification, are permitted provided that the following conditions are 8 | # met: 9 | # 10 | # * Redistributions of source code must retain the above copyright 11 | # notice, this list of conditions and the following disclaimer. 12 | # * Redistributions in binary form must reproduce the above 13 | # copyright notice, this list of conditions and the following disclaimer 14 | # in the documentation and/or other materials provided with the 15 | # distribution. 16 | # * Neither the name of Google Inc. nor the names of its 17 | # contributors may be used to endorse or promote products derived from 18 | # this software without specific prior written permission. 19 | # 20 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 | # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 | # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 | # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 | # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 | # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 | # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 | # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 | # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 | # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | 32 | 33 | all: install 34 | 35 | install: 36 | go install ./proto 37 | go install ./jsonpb 38 | go install ./protoc-gen-go 39 | 40 | test: 41 | go test ./proto 42 | go test ./jsonpb 43 | make -C protoc-gen-go/testdata test 44 | 45 | clean: 46 | go clean ./... 47 | 48 | nuke: 49 | go clean -i ./... 50 | 51 | regenerate: 52 | make -C protoc-gen-go/descriptor regenerate 53 | make -C protoc-gen-go/plugin regenerate 54 | make -C protoc-gen-go/testdata regenerate 55 | make -C proto/testdata regenerate 56 | make -C jsonpb/jsonpb_test_proto regenerate 57 | -------------------------------------------------------------------------------- /github.com/golang/protobuf/jsonpb/jsonpb_test_proto/Makefile: -------------------------------------------------------------------------------- 1 | # Go support for Protocol Buffers - Google's data interchange format 2 | # 3 | # Copyright 2015 The Go Authors. All rights reserved. 4 | # https://github.com/golang/protobuf 5 | # 6 | # Redistribution and use in source and binary forms, with or without 7 | # modification, are permitted provided that the following conditions are 8 | # met: 9 | # 10 | # * Redistributions of source code must retain the above copyright 11 | # notice, this list of conditions and the following disclaimer. 12 | # * Redistributions in binary form must reproduce the above 13 | # copyright notice, this list of conditions and the following disclaimer 14 | # in the documentation and/or other materials provided with the 15 | # distribution. 16 | # * Neither the name of Google Inc. nor the names of its 17 | # contributors may be used to endorse or promote products derived from 18 | # this software without specific prior written permission. 19 | # 20 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 | # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 | # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 | # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 | # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 | # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 | # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 | # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 | # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 | # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | 32 | regenerate: 33 | protoc --go_out=. *.proto 34 | -------------------------------------------------------------------------------- /github.com/golang/protobuf/jsonpb/jsonpb_test_proto/more_test_objects.proto: -------------------------------------------------------------------------------- 1 | // Go support for Protocol Buffers - Google's data interchange format 2 | // 3 | // Copyright 2015 The Go Authors. All rights reserved. 4 | // https://github.com/golang/protobuf 5 | // 6 | // Redistribution and use in source and binary forms, with or without 7 | // modification, are permitted provided that the following conditions are 8 | // met: 9 | // 10 | // * Redistributions of source code must retain the above copyright 11 | // notice, this list of conditions and the following disclaimer. 12 | // * Redistributions in binary form must reproduce the above 13 | // copyright notice, this list of conditions and the following disclaimer 14 | // in the documentation and/or other materials provided with the 15 | // distribution. 16 | // * Neither the name of Google Inc. nor the names of its 17 | // contributors may be used to endorse or promote products derived from 18 | // this software without specific prior written permission. 19 | // 20 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | 32 | syntax = "proto3"; 33 | 34 | package jsonpb; 35 | 36 | message Simple3 { 37 | double dub = 1; 38 | } 39 | 40 | message Mappy { 41 | map nummy = 1; 42 | map strry = 2; 43 | map objjy = 3; 44 | map buggy = 4; 45 | map booly = 5; 46 | } 47 | -------------------------------------------------------------------------------- /github.com/golang/protobuf/proto/Makefile: -------------------------------------------------------------------------------- 1 | # Go support for Protocol Buffers - Google's data interchange format 2 | # 3 | # Copyright 2010 The Go Authors. All rights reserved. 4 | # https://github.com/golang/protobuf 5 | # 6 | # Redistribution and use in source and binary forms, with or without 7 | # modification, are permitted provided that the following conditions are 8 | # met: 9 | # 10 | # * Redistributions of source code must retain the above copyright 11 | # notice, this list of conditions and the following disclaimer. 12 | # * Redistributions in binary form must reproduce the above 13 | # copyright notice, this list of conditions and the following disclaimer 14 | # in the documentation and/or other materials provided with the 15 | # distribution. 16 | # * Neither the name of Google Inc. nor the names of its 17 | # contributors may be used to endorse or promote products derived from 18 | # this software without specific prior written permission. 19 | # 20 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 | # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 | # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 | # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 | # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 | # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 | # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 | # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 | # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 | # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | 32 | install: 33 | go install 34 | 35 | test: install generate-test-pbs 36 | go test 37 | 38 | 39 | generate-test-pbs: 40 | make install 41 | make -C testdata 42 | protoc --go_out=Mtestdata/test.proto=github.com/golang/protobuf/proto/testdata:. proto3_proto/proto3.proto 43 | make 44 | -------------------------------------------------------------------------------- /github.com/golang/protobuf/proto/message_set_test.go: -------------------------------------------------------------------------------- 1 | // Go support for Protocol Buffers - Google's data interchange format 2 | // 3 | // Copyright 2014 The Go Authors. All rights reserved. 4 | // https://github.com/golang/protobuf 5 | // 6 | // Redistribution and use in source and binary forms, with or without 7 | // modification, are permitted provided that the following conditions are 8 | // met: 9 | // 10 | // * Redistributions of source code must retain the above copyright 11 | // notice, this list of conditions and the following disclaimer. 12 | // * Redistributions in binary form must reproduce the above 13 | // copyright notice, this list of conditions and the following disclaimer 14 | // in the documentation and/or other materials provided with the 15 | // distribution. 16 | // * Neither the name of Google Inc. nor the names of its 17 | // contributors may be used to endorse or promote products derived from 18 | // this software without specific prior written permission. 19 | // 20 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | 32 | package proto 33 | 34 | import ( 35 | "bytes" 36 | "testing" 37 | ) 38 | 39 | func TestUnmarshalMessageSetWithDuplicate(t *testing.T) { 40 | // Check that a repeated message set entry will be concatenated. 41 | in := &messageSet{ 42 | Item: []*_MessageSet_Item{ 43 | {TypeId: Int32(12345), Message: []byte("hoo")}, 44 | {TypeId: Int32(12345), Message: []byte("hah")}, 45 | }, 46 | } 47 | b, err := Marshal(in) 48 | if err != nil { 49 | t.Fatalf("Marshal: %v", err) 50 | } 51 | t.Logf("Marshaled bytes: %q", b) 52 | 53 | m := make(map[int32]Extension) 54 | if err := UnmarshalMessageSet(b, m); err != nil { 55 | t.Fatalf("UnmarshalMessageSet: %v", err) 56 | } 57 | ext, ok := m[12345] 58 | if !ok { 59 | t.Fatalf("Didn't retrieve extension 12345; map is %v", m) 60 | } 61 | // Skip wire type/field number and length varints. 62 | got := skipVarint(skipVarint(ext.enc)) 63 | if want := []byte("hoohah"); !bytes.Equal(got, want) { 64 | t.Errorf("Combined extension is %q, want %q", got, want) 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /github.com/golang/protobuf/proto/proto3_proto/proto3.proto: -------------------------------------------------------------------------------- 1 | // Go support for Protocol Buffers - Google's data interchange format 2 | // 3 | // Copyright 2014 The Go Authors. All rights reserved. 4 | // https://github.com/golang/protobuf 5 | // 6 | // Redistribution and use in source and binary forms, with or without 7 | // modification, are permitted provided that the following conditions are 8 | // met: 9 | // 10 | // * Redistributions of source code must retain the above copyright 11 | // notice, this list of conditions and the following disclaimer. 12 | // * Redistributions in binary form must reproduce the above 13 | // copyright notice, this list of conditions and the following disclaimer 14 | // in the documentation and/or other materials provided with the 15 | // distribution. 16 | // * Neither the name of Google Inc. nor the names of its 17 | // contributors may be used to endorse or promote products derived from 18 | // this software without specific prior written permission. 19 | // 20 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | 32 | syntax = "proto3"; 33 | 34 | import "testdata/test.proto"; 35 | 36 | package proto3_proto; 37 | 38 | message Message { 39 | enum Humour { 40 | UNKNOWN = 0; 41 | PUNS = 1; 42 | SLAPSTICK = 2; 43 | BILL_BAILEY = 3; 44 | } 45 | 46 | string name = 1; 47 | Humour hilarity = 2; 48 | uint32 height_in_cm = 3; 49 | bytes data = 4; 50 | int64 result_count = 7; 51 | bool true_scotsman = 8; 52 | float score = 9; 53 | 54 | repeated uint64 key = 5; 55 | Nested nested = 6; 56 | 57 | map terrain = 10; 58 | testdata.SubDefaults proto2_field = 11; 59 | map proto2_value = 13; 60 | } 61 | 62 | message Nested { 63 | string bunny = 1; 64 | } 65 | 66 | message MessageWithMap { 67 | map byte_mapping = 1; 68 | } 69 | -------------------------------------------------------------------------------- /github.com/golang/protobuf/proto/size2_test.go: -------------------------------------------------------------------------------- 1 | // Go support for Protocol Buffers - Google's data interchange format 2 | // 3 | // Copyright 2012 The Go Authors. All rights reserved. 4 | // https://github.com/golang/protobuf 5 | // 6 | // Redistribution and use in source and binary forms, with or without 7 | // modification, are permitted provided that the following conditions are 8 | // met: 9 | // 10 | // * Redistributions of source code must retain the above copyright 11 | // notice, this list of conditions and the following disclaimer. 12 | // * Redistributions in binary form must reproduce the above 13 | // copyright notice, this list of conditions and the following disclaimer 14 | // in the documentation and/or other materials provided with the 15 | // distribution. 16 | // * Neither the name of Google Inc. nor the names of its 17 | // contributors may be used to endorse or promote products derived from 18 | // this software without specific prior written permission. 19 | // 20 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | 32 | package proto 33 | 34 | import ( 35 | "testing" 36 | ) 37 | 38 | // This is a separate file and package from size_test.go because that one uses 39 | // generated messages and thus may not be in package proto without having a circular 40 | // dependency, whereas this file tests unexported details of size.go. 41 | 42 | func TestVarintSize(t *testing.T) { 43 | // Check the edge cases carefully. 44 | testCases := []struct { 45 | n uint64 46 | size int 47 | }{ 48 | {0, 1}, 49 | {1, 1}, 50 | {127, 1}, 51 | {128, 2}, 52 | {16383, 2}, 53 | {16384, 3}, 54 | {1<<63 - 1, 9}, 55 | {1 << 63, 10}, 56 | } 57 | for _, tc := range testCases { 58 | size := sizeVarint(tc.n) 59 | if size != tc.size { 60 | t.Errorf("sizeVarint(%d) = %d, want %d", tc.n, size, tc.size) 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /github.com/golang/protobuf/proto/testdata/Makefile: -------------------------------------------------------------------------------- 1 | # Go support for Protocol Buffers - Google's data interchange format 2 | # 3 | # Copyright 2010 The Go Authors. All rights reserved. 4 | # https://github.com/golang/protobuf 5 | # 6 | # Redistribution and use in source and binary forms, with or without 7 | # modification, are permitted provided that the following conditions are 8 | # met: 9 | # 10 | # * Redistributions of source code must retain the above copyright 11 | # notice, this list of conditions and the following disclaimer. 12 | # * Redistributions in binary form must reproduce the above 13 | # copyright notice, this list of conditions and the following disclaimer 14 | # in the documentation and/or other materials provided with the 15 | # distribution. 16 | # * Neither the name of Google Inc. nor the names of its 17 | # contributors may be used to endorse or promote products derived from 18 | # this software without specific prior written permission. 19 | # 20 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 | # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 | # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 | # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 | # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 | # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 | # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 | # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 | # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 | # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | 32 | 33 | include ../../Make.protobuf 34 | 35 | all: regenerate 36 | 37 | regenerate: 38 | rm -f test.pb.go 39 | make test.pb.go 40 | 41 | # The following rules are just aids to development. Not needed for typical testing. 42 | 43 | diff: regenerate 44 | git diff test.pb.go 45 | 46 | restore: 47 | cp test.pb.go.golden test.pb.go 48 | 49 | preserve: 50 | cp test.pb.go test.pb.go.golden 51 | -------------------------------------------------------------------------------- /github.com/golang/protobuf/proto/testdata/golden_test.go: -------------------------------------------------------------------------------- 1 | // Go support for Protocol Buffers - Google's data interchange format 2 | // 3 | // Copyright 2012 The Go Authors. All rights reserved. 4 | // https://github.com/golang/protobuf 5 | // 6 | // Redistribution and use in source and binary forms, with or without 7 | // modification, are permitted provided that the following conditions are 8 | // met: 9 | // 10 | // * Redistributions of source code must retain the above copyright 11 | // notice, this list of conditions and the following disclaimer. 12 | // * Redistributions in binary form must reproduce the above 13 | // copyright notice, this list of conditions and the following disclaimer 14 | // in the documentation and/or other materials provided with the 15 | // distribution. 16 | // * Neither the name of Google Inc. nor the names of its 17 | // contributors may be used to endorse or promote products derived from 18 | // this software without specific prior written permission. 19 | // 20 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | 32 | // Verify that the compiler output for test.proto is unchanged. 33 | 34 | package testdata 35 | 36 | import ( 37 | "crypto/sha1" 38 | "fmt" 39 | "io/ioutil" 40 | "os" 41 | "os/exec" 42 | "path/filepath" 43 | "testing" 44 | ) 45 | 46 | // sum returns in string form (for easy comparison) the SHA-1 hash of the named file. 47 | func sum(t *testing.T, name string) string { 48 | data, err := ioutil.ReadFile(name) 49 | if err != nil { 50 | t.Fatal(err) 51 | } 52 | t.Logf("sum(%q): length is %d", name, len(data)) 53 | hash := sha1.New() 54 | _, err = hash.Write(data) 55 | if err != nil { 56 | t.Fatal(err) 57 | } 58 | return fmt.Sprintf("% x", hash.Sum(nil)) 59 | } 60 | 61 | func run(t *testing.T, name string, args ...string) { 62 | cmd := exec.Command(name, args...) 63 | cmd.Stdin = os.Stdin 64 | cmd.Stdout = os.Stdout 65 | cmd.Stderr = os.Stderr 66 | err := cmd.Run() 67 | if err != nil { 68 | t.Fatal(err) 69 | } 70 | } 71 | 72 | func TestGolden(t *testing.T) { 73 | // Compute the original checksum. 74 | goldenSum := sum(t, "test.pb.go") 75 | // Run the proto compiler. 76 | run(t, "protoc", "--go_out="+os.TempDir(), "test.proto") 77 | newFile := filepath.Join(os.TempDir(), "test.pb.go") 78 | defer os.Remove(newFile) 79 | // Compute the new checksum. 80 | newSum := sum(t, newFile) 81 | // Verify 82 | if newSum != goldenSum { 83 | run(t, "diff", "-u", "test.pb.go", newFile) 84 | t.Fatal("Code generated by protoc-gen-go has changed; update test.pb.go") 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /github.com/golang/protobuf/protoc-gen-go/Makefile: -------------------------------------------------------------------------------- 1 | # Go support for Protocol Buffers - Google's data interchange format 2 | # 3 | # Copyright 2010 The Go Authors. All rights reserved. 4 | # https://github.com/golang/protobuf 5 | # 6 | # Redistribution and use in source and binary forms, with or without 7 | # modification, are permitted provided that the following conditions are 8 | # met: 9 | # 10 | # * Redistributions of source code must retain the above copyright 11 | # notice, this list of conditions and the following disclaimer. 12 | # * Redistributions in binary form must reproduce the above 13 | # copyright notice, this list of conditions and the following disclaimer 14 | # in the documentation and/or other materials provided with the 15 | # distribution. 16 | # * Neither the name of Google Inc. nor the names of its 17 | # contributors may be used to endorse or promote products derived from 18 | # this software without specific prior written permission. 19 | # 20 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 | # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 | # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 | # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 | # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 | # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 | # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 | # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 | # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 | # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | 32 | test: 33 | cd testdata && make test 34 | -------------------------------------------------------------------------------- /github.com/golang/protobuf/protoc-gen-go/descriptor/Makefile: -------------------------------------------------------------------------------- 1 | # Go support for Protocol Buffers - Google's data interchange format 2 | # 3 | # Copyright 2010 The Go Authors. All rights reserved. 4 | # https://github.com/golang/protobuf 5 | # 6 | # Redistribution and use in source and binary forms, with or without 7 | # modification, are permitted provided that the following conditions are 8 | # met: 9 | # 10 | # * Redistributions of source code must retain the above copyright 11 | # notice, this list of conditions and the following disclaimer. 12 | # * Redistributions in binary form must reproduce the above 13 | # copyright notice, this list of conditions and the following disclaimer 14 | # in the documentation and/or other materials provided with the 15 | # distribution. 16 | # * Neither the name of Google Inc. nor the names of its 17 | # contributors may be used to endorse or promote products derived from 18 | # this software without specific prior written permission. 19 | # 20 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 | # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 | # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 | # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 | # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 | # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 | # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 | # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 | # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 | # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | 32 | # Not stored here, but descriptor.proto is in https://github.com/google/protobuf/ 33 | # at src/google/protobuf/descriptor.proto 34 | regenerate: 35 | echo WARNING! THIS RULE IS PROBABLY NOT RIGHT FOR YOUR INSTALLATION 36 | protoc --go_out=. -I$(HOME)/src/protobuf/src $(HOME)/src/protobuf/src/google/protobuf/descriptor.proto && \ 37 | sed 's,^package google_protobuf,package descriptor,' google/protobuf/descriptor.pb.go > \ 38 | $(GOPATH)/src/github.com/golang/protobuf/protoc-gen-go/descriptor/descriptor.pb.go && \ 39 | rm -f google/protobuf/descriptor.pb.go 40 | -------------------------------------------------------------------------------- /github.com/golang/protobuf/protoc-gen-go/doc.go: -------------------------------------------------------------------------------- 1 | // Go support for Protocol Buffers - Google's data interchange format 2 | // 3 | // Copyright 2010 The Go Authors. All rights reserved. 4 | // https://github.com/golang/protobuf 5 | // 6 | // Redistribution and use in source and binary forms, with or without 7 | // modification, are permitted provided that the following conditions are 8 | // met: 9 | // 10 | // * Redistributions of source code must retain the above copyright 11 | // notice, this list of conditions and the following disclaimer. 12 | // * Redistributions in binary form must reproduce the above 13 | // copyright notice, this list of conditions and the following disclaimer 14 | // in the documentation and/or other materials provided with the 15 | // distribution. 16 | // * Neither the name of Google Inc. nor the names of its 17 | // contributors may be used to endorse or promote products derived from 18 | // this software without specific prior written permission. 19 | // 20 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | 32 | /* 33 | A plugin for the Google protocol buffer compiler to generate Go code. 34 | Run it by building this program and putting it in your path with the name 35 | protoc-gen-go 36 | That word 'go' at the end becomes part of the option string set for the 37 | protocol compiler, so once the protocol compiler (protoc) is installed 38 | you can run 39 | protoc --go_out=output_directory input_directory/file.proto 40 | to generate Go bindings for the protocol defined by file.proto. 41 | With that input, the output will be written to 42 | output_directory/file.pb.go 43 | 44 | The generated code is documented in the package comment for 45 | the library. 46 | 47 | See the README and documentation for protocol buffers to learn more: 48 | https://developers.google.com/protocol-buffers/ 49 | 50 | */ 51 | package documentation 52 | -------------------------------------------------------------------------------- /github.com/golang/protobuf/protoc-gen-go/generator/Makefile: -------------------------------------------------------------------------------- 1 | # Go support for Protocol Buffers - Google's data interchange format 2 | # 3 | # Copyright 2010 The Go Authors. All rights reserved. 4 | # https://github.com/golang/protobuf 5 | # 6 | # Redistribution and use in source and binary forms, with or without 7 | # modification, are permitted provided that the following conditions are 8 | # met: 9 | # 10 | # * Redistributions of source code must retain the above copyright 11 | # notice, this list of conditions and the following disclaimer. 12 | # * Redistributions in binary form must reproduce the above 13 | # copyright notice, this list of conditions and the following disclaimer 14 | # in the documentation and/or other materials provided with the 15 | # distribution. 16 | # * Neither the name of Google Inc. nor the names of its 17 | # contributors may be used to endorse or promote products derived from 18 | # this software without specific prior written permission. 19 | # 20 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 | # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 | # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 | # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 | # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 | # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 | # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 | # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 | # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 | # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | 32 | include $(GOROOT)/src/Make.inc 33 | 34 | TARG=github.com/golang/protobuf/compiler/generator 35 | GOFILES=\ 36 | generator.go\ 37 | 38 | DEPS=../descriptor ../plugin ../../proto 39 | 40 | include $(GOROOT)/src/Make.pkg 41 | -------------------------------------------------------------------------------- /github.com/golang/protobuf/protoc-gen-go/generator/name_test.go: -------------------------------------------------------------------------------- 1 | // Go support for Protocol Buffers - Google's data interchange format 2 | // 3 | // Copyright 2013 The Go Authors. All rights reserved. 4 | // https://github.com/golang/protobuf 5 | // 6 | // Redistribution and use in source and binary forms, with or without 7 | // modification, are permitted provided that the following conditions are 8 | // met: 9 | // 10 | // * Redistributions of source code must retain the above copyright 11 | // notice, this list of conditions and the following disclaimer. 12 | // * Redistributions in binary form must reproduce the above 13 | // copyright notice, this list of conditions and the following disclaimer 14 | // in the documentation and/or other materials provided with the 15 | // distribution. 16 | // * Neither the name of Google Inc. nor the names of its 17 | // contributors may be used to endorse or promote products derived from 18 | // this software without specific prior written permission. 19 | // 20 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | 32 | package generator 33 | 34 | import ( 35 | "testing" 36 | ) 37 | 38 | func TestCamelCase(t *testing.T) { 39 | tests := []struct { 40 | in, want string 41 | }{ 42 | {"one", "One"}, 43 | {"one_two", "OneTwo"}, 44 | {"_my_field_name_2", "XMyFieldName_2"}, 45 | {"Something_Capped", "Something_Capped"}, 46 | {"my_Name", "My_Name"}, 47 | {"OneTwo", "OneTwo"}, 48 | {"_", "X"}, 49 | {"_a_", "XA_"}, 50 | } 51 | for _, tc := range tests { 52 | if got := CamelCase(tc.in); got != tc.want { 53 | t.Errorf("CamelCase(%q) = %q, want %q", tc.in, got, tc.want) 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /github.com/golang/protobuf/protoc-gen-go/link_grpc.go: -------------------------------------------------------------------------------- 1 | // Go support for Protocol Buffers - Google's data interchange format 2 | // 3 | // Copyright 2015 The Go Authors. All rights reserved. 4 | // https://github.com/golang/protobuf 5 | // 6 | // Redistribution and use in source and binary forms, with or without 7 | // modification, are permitted provided that the following conditions are 8 | // met: 9 | // 10 | // * Redistributions of source code must retain the above copyright 11 | // notice, this list of conditions and the following disclaimer. 12 | // * Redistributions in binary form must reproduce the above 13 | // copyright notice, this list of conditions and the following disclaimer 14 | // in the documentation and/or other materials provided with the 15 | // distribution. 16 | // * Neither the name of Google Inc. nor the names of its 17 | // contributors may be used to endorse or promote products derived from 18 | // this software without specific prior written permission. 19 | // 20 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | 32 | package main 33 | 34 | import _ "github.com/golang/protobuf/protoc-gen-go/internal/grpc" 35 | -------------------------------------------------------------------------------- /github.com/golang/protobuf/protoc-gen-go/plugin/Makefile: -------------------------------------------------------------------------------- 1 | # Go support for Protocol Buffers - Google's data interchange format 2 | # 3 | # Copyright 2010 The Go Authors. All rights reserved. 4 | # https://github.com/golang/protobuf 5 | # 6 | # Redistribution and use in source and binary forms, with or without 7 | # modification, are permitted provided that the following conditions are 8 | # met: 9 | # 10 | # * Redistributions of source code must retain the above copyright 11 | # notice, this list of conditions and the following disclaimer. 12 | # * Redistributions in binary form must reproduce the above 13 | # copyright notice, this list of conditions and the following disclaimer 14 | # in the documentation and/or other materials provided with the 15 | # distribution. 16 | # * Neither the name of Google Inc. nor the names of its 17 | # contributors may be used to endorse or promote products derived from 18 | # this software without specific prior written permission. 19 | # 20 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 | # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 | # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 | # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 | # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 | # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 | # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 | # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 | # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 | # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | 32 | # Not stored here, but plugin.proto is in https://github.com/google/protobuf/ 33 | # at src/google/protobuf/compiler/plugin.proto 34 | # Also we need to fix an import. 35 | regenerate: 36 | echo WARNING! THIS RULE IS PROBABLY NOT RIGHT FOR YOUR INSTALLATION 37 | protoc --go_out=Mgoogle/protobuf/descriptor.proto=github.com/golang/protobuf/protoc-gen-go/descriptor:. \ 38 | -I$(HOME)/src/protobuf/src $(HOME)/src/protobuf/src/google/protobuf/compiler/plugin.proto && \ 39 | mv google/protobuf/compiler/plugin.pb.go $(GOPATH)/src/github.com/golang/protobuf/protoc-gen-go/plugin 40 | 41 | restore: 42 | cp plugin.pb.golden plugin.pb.go 43 | 44 | preserve: 45 | cp plugin.pb.go plugin.pb.golden 46 | -------------------------------------------------------------------------------- /github.com/golang/protobuf/protoc-gen-go/plugin/plugin.pb.golden: -------------------------------------------------------------------------------- 1 | // Code generated by protoc-gen-go. 2 | // source: google/protobuf/compiler/plugin.proto 3 | // DO NOT EDIT! 4 | 5 | package google_protobuf_compiler 6 | 7 | import proto "github.com/golang/protobuf/proto" 8 | import "math" 9 | import google_protobuf "github.com/golang/protobuf/protoc-gen-go/descriptor" 10 | 11 | // Reference proto and math imports to suppress error if they are not otherwise used. 12 | var _ = proto.GetString 13 | var _ = math.Inf 14 | 15 | type CodeGeneratorRequest struct { 16 | FileToGenerate []string `protobuf:"bytes,1,rep,name=file_to_generate" json:"file_to_generate,omitempty"` 17 | Parameter *string `protobuf:"bytes,2,opt,name=parameter" json:"parameter,omitempty"` 18 | ProtoFile []*google_protobuf.FileDescriptorProto `protobuf:"bytes,15,rep,name=proto_file" json:"proto_file,omitempty"` 19 | XXX_unrecognized []byte `json:"-"` 20 | } 21 | 22 | func (this *CodeGeneratorRequest) Reset() { *this = CodeGeneratorRequest{} } 23 | func (this *CodeGeneratorRequest) String() string { return proto.CompactTextString(this) } 24 | func (*CodeGeneratorRequest) ProtoMessage() {} 25 | 26 | func (this *CodeGeneratorRequest) GetParameter() string { 27 | if this != nil && this.Parameter != nil { 28 | return *this.Parameter 29 | } 30 | return "" 31 | } 32 | 33 | type CodeGeneratorResponse struct { 34 | Error *string `protobuf:"bytes,1,opt,name=error" json:"error,omitempty"` 35 | File []*CodeGeneratorResponse_File `protobuf:"bytes,15,rep,name=file" json:"file,omitempty"` 36 | XXX_unrecognized []byte `json:"-"` 37 | } 38 | 39 | func (this *CodeGeneratorResponse) Reset() { *this = CodeGeneratorResponse{} } 40 | func (this *CodeGeneratorResponse) String() string { return proto.CompactTextString(this) } 41 | func (*CodeGeneratorResponse) ProtoMessage() {} 42 | 43 | func (this *CodeGeneratorResponse) GetError() string { 44 | if this != nil && this.Error != nil { 45 | return *this.Error 46 | } 47 | return "" 48 | } 49 | 50 | type CodeGeneratorResponse_File struct { 51 | Name *string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` 52 | InsertionPoint *string `protobuf:"bytes,2,opt,name=insertion_point" json:"insertion_point,omitempty"` 53 | Content *string `protobuf:"bytes,15,opt,name=content" json:"content,omitempty"` 54 | XXX_unrecognized []byte `json:"-"` 55 | } 56 | 57 | func (this *CodeGeneratorResponse_File) Reset() { *this = CodeGeneratorResponse_File{} } 58 | func (this *CodeGeneratorResponse_File) String() string { return proto.CompactTextString(this) } 59 | func (*CodeGeneratorResponse_File) ProtoMessage() {} 60 | 61 | func (this *CodeGeneratorResponse_File) GetName() string { 62 | if this != nil && this.Name != nil { 63 | return *this.Name 64 | } 65 | return "" 66 | } 67 | 68 | func (this *CodeGeneratorResponse_File) GetInsertionPoint() string { 69 | if this != nil && this.InsertionPoint != nil { 70 | return *this.InsertionPoint 71 | } 72 | return "" 73 | } 74 | 75 | func (this *CodeGeneratorResponse_File) GetContent() string { 76 | if this != nil && this.Content != nil { 77 | return *this.Content 78 | } 79 | return "" 80 | } 81 | 82 | func init() { 83 | } 84 | -------------------------------------------------------------------------------- /github.com/golang/protobuf/protoc-gen-go/testdata/Makefile: -------------------------------------------------------------------------------- 1 | # Go support for Protocol Buffers - Google's data interchange format 2 | # 3 | # Copyright 2010 The Go Authors. All rights reserved. 4 | # https://github.com/golang/protobuf 5 | # 6 | # Redistribution and use in source and binary forms, with or without 7 | # modification, are permitted provided that the following conditions are 8 | # met: 9 | # 10 | # * Redistributions of source code must retain the above copyright 11 | # notice, this list of conditions and the following disclaimer. 12 | # * Redistributions in binary form must reproduce the above 13 | # copyright notice, this list of conditions and the following disclaimer 14 | # in the documentation and/or other materials provided with the 15 | # distribution. 16 | # * Neither the name of Google Inc. nor the names of its 17 | # contributors may be used to endorse or promote products derived from 18 | # this software without specific prior written permission. 19 | # 20 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 | # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 | # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 | # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 | # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 | # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 | # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 | # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 | # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 | # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | 32 | all: 33 | @echo run make test 34 | 35 | include ../../Make.protobuf 36 | 37 | test: golden testbuild 38 | 39 | #test: golden testbuild extension_test 40 | # ./extension_test 41 | # @echo PASS 42 | 43 | my_test/test.pb.go: my_test/test.proto 44 | protoc --go_out=Mmulti/multi1.proto=github.com/golang/protobuf/protoc-gen-go/testdata/multi:. $< 45 | 46 | golden: 47 | make -B my_test/test.pb.go 48 | sed -i '/return.*fileDescriptor/d' my_test/test.pb.go 49 | sed -i '/^var fileDescriptor/,/^}/d' my_test/test.pb.go 50 | gofmt -w my_test/test.pb.go 51 | diff -w my_test/test.pb.go my_test/test.pb.go.golden 52 | 53 | nuke: clean 54 | 55 | testbuild: regenerate 56 | go test 57 | 58 | regenerate: 59 | # Invoke protoc once to generate three independent .pb.go files in the same package. 60 | protoc --go_out=. multi/multi{1,2,3}.proto 61 | 62 | #extension_test: extension_test.$O 63 | # $(LD) -L. -o $@ $< 64 | 65 | #multi.a: multi3.pb.$O multi2.pb.$O multi1.pb.$O 66 | # rm -f multi.a 67 | # $(QUOTED_GOBIN)/gopack grc $@ $< 68 | 69 | #test.pb.go: imp.pb.go 70 | #multi1.pb.go: multi2.pb.go multi3.pb.go 71 | #main.$O: imp.pb.$O test.pb.$O multi.a 72 | #extension_test.$O: extension_base.pb.$O extension_extra.pb.$O extension_user.pb.$O 73 | -------------------------------------------------------------------------------- /github.com/golang/protobuf/protoc-gen-go/testdata/extension_base.proto: -------------------------------------------------------------------------------- 1 | // Go support for Protocol Buffers - Google's data interchange format 2 | // 3 | // Copyright 2010 The Go Authors. All rights reserved. 4 | // https://github.com/golang/protobuf 5 | // 6 | // Redistribution and use in source and binary forms, with or without 7 | // modification, are permitted provided that the following conditions are 8 | // met: 9 | // 10 | // * Redistributions of source code must retain the above copyright 11 | // notice, this list of conditions and the following disclaimer. 12 | // * Redistributions in binary form must reproduce the above 13 | // copyright notice, this list of conditions and the following disclaimer 14 | // in the documentation and/or other materials provided with the 15 | // distribution. 16 | // * Neither the name of Google Inc. nor the names of its 17 | // contributors may be used to endorse or promote products derived from 18 | // this software without specific prior written permission. 19 | // 20 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | 32 | syntax = "proto2"; 33 | 34 | package extension_base; 35 | 36 | message BaseMessage { 37 | optional int32 height = 1; 38 | extensions 4 to 9; 39 | extensions 16 to max; 40 | } 41 | 42 | // Another message that may be extended, using message_set_wire_format. 43 | message OldStyleMessage { 44 | option message_set_wire_format = true; 45 | extensions 100 to max; 46 | } 47 | -------------------------------------------------------------------------------- /github.com/golang/protobuf/protoc-gen-go/testdata/extension_extra.proto: -------------------------------------------------------------------------------- 1 | // Go support for Protocol Buffers - Google's data interchange format 2 | // 3 | // Copyright 2011 The Go Authors. All rights reserved. 4 | // https://github.com/golang/protobuf 5 | // 6 | // Redistribution and use in source and binary forms, with or without 7 | // modification, are permitted provided that the following conditions are 8 | // met: 9 | // 10 | // * Redistributions of source code must retain the above copyright 11 | // notice, this list of conditions and the following disclaimer. 12 | // * Redistributions in binary form must reproduce the above 13 | // copyright notice, this list of conditions and the following disclaimer 14 | // in the documentation and/or other materials provided with the 15 | // distribution. 16 | // * Neither the name of Google Inc. nor the names of its 17 | // contributors may be used to endorse or promote products derived from 18 | // this software without specific prior written permission. 19 | // 20 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | 32 | syntax = "proto2"; 33 | 34 | package extension_extra; 35 | 36 | message ExtraMessage { 37 | optional int32 width = 1; 38 | } 39 | -------------------------------------------------------------------------------- /github.com/golang/protobuf/protoc-gen-go/testdata/extension_user.proto: -------------------------------------------------------------------------------- 1 | // Go support for Protocol Buffers - Google's data interchange format 2 | // 3 | // Copyright 2010 The Go Authors. All rights reserved. 4 | // https://github.com/golang/protobuf 5 | // 6 | // Redistribution and use in source and binary forms, with or without 7 | // modification, are permitted provided that the following conditions are 8 | // met: 9 | // 10 | // * Redistributions of source code must retain the above copyright 11 | // notice, this list of conditions and the following disclaimer. 12 | // * Redistributions in binary form must reproduce the above 13 | // copyright notice, this list of conditions and the following disclaimer 14 | // in the documentation and/or other materials provided with the 15 | // distribution. 16 | // * Neither the name of Google Inc. nor the names of its 17 | // contributors may be used to endorse or promote products derived from 18 | // this software without specific prior written permission. 19 | // 20 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | 32 | syntax = "proto2"; 33 | 34 | import "extension_base.proto"; 35 | import "extension_extra.proto"; 36 | 37 | package extension_user; 38 | 39 | message UserMessage { 40 | optional string name = 1; 41 | optional string rank = 2; 42 | } 43 | 44 | // Extend with a message 45 | extend extension_base.BaseMessage { 46 | optional UserMessage user_message = 5; 47 | } 48 | 49 | // Extend with a foreign message 50 | extend extension_base.BaseMessage { 51 | optional extension_extra.ExtraMessage extra_message = 9; 52 | } 53 | 54 | // Extend with some primitive types 55 | extend extension_base.BaseMessage { 56 | optional int32 width = 6; 57 | optional int64 area = 7; 58 | } 59 | 60 | // Extend inside the scope of another type 61 | message LoudMessage { 62 | extend extension_base.BaseMessage { 63 | optional uint32 volume = 8; 64 | } 65 | extensions 100 to max; 66 | } 67 | 68 | // Extend inside the scope of another type, using a message. 69 | message LoginMessage { 70 | extend extension_base.BaseMessage { 71 | optional UserMessage user_message = 16; 72 | } 73 | } 74 | 75 | // Extend with a repeated field 76 | extend extension_base.BaseMessage { 77 | repeated Detail detail = 17; 78 | } 79 | 80 | message Detail { 81 | optional string color = 1; 82 | } 83 | 84 | // An extension of an extension 85 | message Announcement { 86 | optional string words = 1; 87 | extend LoudMessage { 88 | optional Announcement loud_ext = 100; 89 | } 90 | } 91 | 92 | // Something that can be put in a message set. 93 | message OldStyleParcel { 94 | extend extension_base.OldStyleMessage { 95 | optional OldStyleParcel message_set_extension = 2001; 96 | } 97 | 98 | required string name = 1; 99 | optional int32 height = 2; 100 | } 101 | -------------------------------------------------------------------------------- /github.com/golang/protobuf/protoc-gen-go/testdata/grpc.proto: -------------------------------------------------------------------------------- 1 | // Go support for Protocol Buffers - Google's data interchange format 2 | // 3 | // Copyright 2015 The Go Authors. All rights reserved. 4 | // https://github.com/golang/protobuf 5 | // 6 | // Redistribution and use in source and binary forms, with or without 7 | // modification, are permitted provided that the following conditions are 8 | // met: 9 | // 10 | // * Redistributions of source code must retain the above copyright 11 | // notice, this list of conditions and the following disclaimer. 12 | // * Redistributions in binary form must reproduce the above 13 | // copyright notice, this list of conditions and the following disclaimer 14 | // in the documentation and/or other materials provided with the 15 | // distribution. 16 | // * Neither the name of Google Inc. nor the names of its 17 | // contributors may be used to endorse or promote products derived from 18 | // this software without specific prior written permission. 19 | // 20 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | 32 | syntax = "proto3"; 33 | 34 | package grpc.testing; 35 | 36 | message SimpleRequest { 37 | } 38 | 39 | message SimpleResponse { 40 | } 41 | 42 | message StreamMsg { 43 | } 44 | 45 | message StreamMsg2 { 46 | } 47 | 48 | service Test { 49 | rpc UnaryCall(SimpleRequest) returns (SimpleResponse); 50 | 51 | // This RPC streams from the server only. 52 | rpc Downstream(SimpleRequest) returns (stream StreamMsg); 53 | 54 | // This RPC streams from the client. 55 | rpc Upstream(stream StreamMsg) returns (SimpleResponse); 56 | 57 | // This one streams in both directions. 58 | rpc Bidi(stream StreamMsg) returns (stream StreamMsg2); 59 | } 60 | -------------------------------------------------------------------------------- /github.com/golang/protobuf/protoc-gen-go/testdata/imp.proto: -------------------------------------------------------------------------------- 1 | // Go support for Protocol Buffers - Google's data interchange format 2 | // 3 | // Copyright 2010 The Go Authors. All rights reserved. 4 | // https://github.com/golang/protobuf 5 | // 6 | // Redistribution and use in source and binary forms, with or without 7 | // modification, are permitted provided that the following conditions are 8 | // met: 9 | // 10 | // * Redistributions of source code must retain the above copyright 11 | // notice, this list of conditions and the following disclaimer. 12 | // * Redistributions in binary form must reproduce the above 13 | // copyright notice, this list of conditions and the following disclaimer 14 | // in the documentation and/or other materials provided with the 15 | // distribution. 16 | // * Neither the name of Google Inc. nor the names of its 17 | // contributors may be used to endorse or promote products derived from 18 | // this software without specific prior written permission. 19 | // 20 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | 32 | syntax = "proto2"; 33 | 34 | package imp; 35 | 36 | import "imp2.proto"; 37 | import "imp3.proto"; 38 | 39 | message ImportedMessage { 40 | required int64 field = 1; 41 | 42 | // The forwarded getters for these fields are fiddly to get right. 43 | optional ImportedMessage2 local_msg = 2; 44 | optional ForeignImportedMessage foreign_msg = 3; // in imp3.proto 45 | optional Owner enum_field = 4; 46 | oneof union { 47 | int32 state = 9; 48 | } 49 | 50 | repeated string name = 5; 51 | repeated Owner boss = 6; 52 | repeated ImportedMessage2 memo = 7; 53 | 54 | map msg_map = 8; 55 | 56 | enum Owner { 57 | DAVE = 1; 58 | MIKE = 2; 59 | } 60 | 61 | extensions 90 to 100; 62 | } 63 | 64 | message ImportedMessage2 { 65 | } 66 | 67 | message ImportedExtendable { 68 | option message_set_wire_format = true; 69 | extensions 100 to max; 70 | } 71 | -------------------------------------------------------------------------------- /github.com/golang/protobuf/protoc-gen-go/testdata/imp2.proto: -------------------------------------------------------------------------------- 1 | // Go support for Protocol Buffers - Google's data interchange format 2 | // 3 | // Copyright 2011 The Go Authors. All rights reserved. 4 | // https://github.com/golang/protobuf 5 | // 6 | // Redistribution and use in source and binary forms, with or without 7 | // modification, are permitted provided that the following conditions are 8 | // met: 9 | // 10 | // * Redistributions of source code must retain the above copyright 11 | // notice, this list of conditions and the following disclaimer. 12 | // * Redistributions in binary form must reproduce the above 13 | // copyright notice, this list of conditions and the following disclaimer 14 | // in the documentation and/or other materials provided with the 15 | // distribution. 16 | // * Neither the name of Google Inc. nor the names of its 17 | // contributors may be used to endorse or promote products derived from 18 | // this software without specific prior written permission. 19 | // 20 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | 32 | syntax = "proto2"; 33 | 34 | package imp; 35 | 36 | message PubliclyImportedMessage { 37 | optional int64 field = 1; 38 | } 39 | 40 | enum PubliclyImportedEnum { 41 | GLASSES = 1; 42 | HAIR = 2; 43 | } 44 | -------------------------------------------------------------------------------- /github.com/golang/protobuf/protoc-gen-go/testdata/imp3.proto: -------------------------------------------------------------------------------- 1 | // Go support for Protocol Buffers - Google's data interchange format 2 | // 3 | // Copyright 2012 The Go Authors. All rights reserved. 4 | // https://github.com/golang/protobuf 5 | // 6 | // Redistribution and use in source and binary forms, with or without 7 | // modification, are permitted provided that the following conditions are 8 | // met: 9 | // 10 | // * Redistributions of source code must retain the above copyright 11 | // notice, this list of conditions and the following disclaimer. 12 | // * Redistributions in binary form must reproduce the above 13 | // copyright notice, this list of conditions and the following disclaimer 14 | // in the documentation and/or other materials provided with the 15 | // distribution. 16 | // * Neither the name of Google Inc. nor the names of its 17 | // contributors may be used to endorse or promote products derived from 18 | // this software without specific prior written permission. 19 | // 20 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | 32 | syntax = "proto2"; 33 | 34 | package imp; 35 | 36 | message ForeignImportedMessage { 37 | optional string tuber = 1; 38 | } 39 | -------------------------------------------------------------------------------- /github.com/golang/protobuf/protoc-gen-go/testdata/main_test.go: -------------------------------------------------------------------------------- 1 | // Go support for Protocol Buffers - Google's data interchange format 2 | // 3 | // Copyright 2010 The Go Authors. All rights reserved. 4 | // https://github.com/golang/protobuf 5 | // 6 | // Redistribution and use in source and binary forms, with or without 7 | // modification, are permitted provided that the following conditions are 8 | // met: 9 | // 10 | // * Redistributions of source code must retain the above copyright 11 | // notice, this list of conditions and the following disclaimer. 12 | // * Redistributions in binary form must reproduce the above 13 | // copyright notice, this list of conditions and the following disclaimer 14 | // in the documentation and/or other materials provided with the 15 | // distribution. 16 | // * Neither the name of Google Inc. nor the names of its 17 | // contributors may be used to endorse or promote products derived from 18 | // this software without specific prior written permission. 19 | // 20 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | 32 | // A simple binary to link together the protocol buffers in this test. 33 | 34 | package testdata 35 | 36 | import ( 37 | "testing" 38 | 39 | mytestpb "./my_test" 40 | multipb "github.com/golang/protobuf/protoc-gen-go/testdata/multi" 41 | ) 42 | 43 | func TestLink(t *testing.T) { 44 | _ = &multipb.Multi1{} 45 | _ = &mytestpb.Request{} 46 | } 47 | -------------------------------------------------------------------------------- /github.com/golang/protobuf/protoc-gen-go/testdata/multi/multi1.proto: -------------------------------------------------------------------------------- 1 | // Go support for Protocol Buffers - Google's data interchange format 2 | // 3 | // Copyright 2010 The Go Authors. All rights reserved. 4 | // https://github.com/golang/protobuf 5 | // 6 | // Redistribution and use in source and binary forms, with or without 7 | // modification, are permitted provided that the following conditions are 8 | // met: 9 | // 10 | // * Redistributions of source code must retain the above copyright 11 | // notice, this list of conditions and the following disclaimer. 12 | // * Redistributions in binary form must reproduce the above 13 | // copyright notice, this list of conditions and the following disclaimer 14 | // in the documentation and/or other materials provided with the 15 | // distribution. 16 | // * Neither the name of Google Inc. nor the names of its 17 | // contributors may be used to endorse or promote products derived from 18 | // this software without specific prior written permission. 19 | // 20 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | 32 | syntax = "proto2"; 33 | 34 | import "multi/multi2.proto"; 35 | import "multi/multi3.proto"; 36 | 37 | package multitest; 38 | 39 | message Multi1 { 40 | required Multi2 multi2 = 1; 41 | optional Multi2.Color color = 2; 42 | optional Multi3.HatType hat_type = 3; 43 | } 44 | 45 | -------------------------------------------------------------------------------- /github.com/golang/protobuf/protoc-gen-go/testdata/multi/multi2.proto: -------------------------------------------------------------------------------- 1 | // Go support for Protocol Buffers - Google's data interchange format 2 | // 3 | // Copyright 2010 The Go Authors. All rights reserved. 4 | // https://github.com/golang/protobuf 5 | // 6 | // Redistribution and use in source and binary forms, with or without 7 | // modification, are permitted provided that the following conditions are 8 | // met: 9 | // 10 | // * Redistributions of source code must retain the above copyright 11 | // notice, this list of conditions and the following disclaimer. 12 | // * Redistributions in binary form must reproduce the above 13 | // copyright notice, this list of conditions and the following disclaimer 14 | // in the documentation and/or other materials provided with the 15 | // distribution. 16 | // * Neither the name of Google Inc. nor the names of its 17 | // contributors may be used to endorse or promote products derived from 18 | // this software without specific prior written permission. 19 | // 20 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | 32 | syntax = "proto2"; 33 | 34 | package multitest; 35 | 36 | message Multi2 { 37 | required int32 required_value = 1; 38 | 39 | enum Color { 40 | BLUE = 1; 41 | GREEN = 2; 42 | RED = 3; 43 | }; 44 | optional Color color = 2; 45 | } 46 | 47 | -------------------------------------------------------------------------------- /github.com/golang/protobuf/protoc-gen-go/testdata/multi/multi3.proto: -------------------------------------------------------------------------------- 1 | // Go support for Protocol Buffers - Google's data interchange format 2 | // 3 | // Copyright 2010 The Go Authors. All rights reserved. 4 | // https://github.com/golang/protobuf 5 | // 6 | // Redistribution and use in source and binary forms, with or without 7 | // modification, are permitted provided that the following conditions are 8 | // met: 9 | // 10 | // * Redistributions of source code must retain the above copyright 11 | // notice, this list of conditions and the following disclaimer. 12 | // * Redistributions in binary form must reproduce the above 13 | // copyright notice, this list of conditions and the following disclaimer 14 | // in the documentation and/or other materials provided with the 15 | // distribution. 16 | // * Neither the name of Google Inc. nor the names of its 17 | // contributors may be used to endorse or promote products derived from 18 | // this software without specific prior written permission. 19 | // 20 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | 32 | syntax = "proto2"; 33 | 34 | package multitest; 35 | 36 | message Multi3 { 37 | enum HatType { 38 | FEDORA = 1; 39 | FEZ = 2; 40 | }; 41 | optional HatType hat_type = 1; 42 | } 43 | 44 | -------------------------------------------------------------------------------- /github.com/golang/protobuf/protoc-gen-go/testdata/proto3.proto: -------------------------------------------------------------------------------- 1 | // Go support for Protocol Buffers - Google's data interchange format 2 | // 3 | // Copyright 2014 The Go Authors. All rights reserved. 4 | // https://github.com/golang/protobuf 5 | // 6 | // Redistribution and use in source and binary forms, with or without 7 | // modification, are permitted provided that the following conditions are 8 | // met: 9 | // 10 | // * Redistributions of source code must retain the above copyright 11 | // notice, this list of conditions and the following disclaimer. 12 | // * Redistributions in binary form must reproduce the above 13 | // copyright notice, this list of conditions and the following disclaimer 14 | // in the documentation and/or other materials provided with the 15 | // distribution. 16 | // * Neither the name of Google Inc. nor the names of its 17 | // contributors may be used to endorse or promote products derived from 18 | // this software without specific prior written permission. 19 | // 20 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | 32 | syntax = "proto3"; 33 | 34 | package proto3; 35 | 36 | message Request { 37 | enum Flavour { 38 | SWEET = 0; 39 | SOUR = 1; 40 | UMAMI = 2; 41 | GOPHERLICIOUS = 3; 42 | } 43 | string name = 1; 44 | repeated int64 key = 2; 45 | Flavour taste = 3; 46 | Book book = 4; 47 | } 48 | 49 | message Book { 50 | string title = 1; 51 | bytes raw_data = 2; 52 | } 53 | -------------------------------------------------------------------------------- /github.com/manucorporat/sse/.travis.yml: -------------------------------------------------------------------------------- 1 | language: go 2 | sudo: false 3 | go: 4 | - 1.3 5 | - 1.4 6 | - tip 7 | -------------------------------------------------------------------------------- /github.com/manucorporat/sse/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Manuel Martínez-Almeida 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /github.com/manucorporat/sse/README.md: -------------------------------------------------------------------------------- 1 | #Server-Sent Events [![GoDoc](https://godoc.org/github.com/manucorporat/sse?status.svg)](https://godoc.org/github.com/manucorporat/sse) [![Build Status](https://travis-ci.org/manucorporat/sse.svg)](https://travis-ci.org/manucorporat/sse) 2 | 3 | Server-sent events (SSE) is a technology where a browser receives automatic updates from a server via HTTP connection. The Server-Sent Events EventSource API is [standardized as part of HTML5[1] by the W3C](http://www.w3.org/TR/2009/WD-eventsource-20091029/). 4 | 5 | - [Real world demostration using Gin](http://sse.getgin.io/) 6 | - [Read this great SSE introduction by the HTML5Rocks guys](http://www.html5rocks.com/en/tutorials/eventsource/basics/) 7 | - [Browser support](http://caniuse.com/#feat=eventsource) 8 | 9 | ##Sample code 10 | 11 | ```go 12 | import "github.com/manucorporat/sse" 13 | 14 | func httpHandler(w http.ResponseWriter, req *http.Request) { 15 | // data can be a primitive like a string, an integer or a float 16 | sse.Encode(w, sse.Event{ 17 | Event: "message", 18 | Data: "some data\nmore data", 19 | }) 20 | 21 | // also a complex type, like a map, a struct or a slice 22 | sse.Encode(w, sse.Event{ 23 | Id: "124", 24 | Event: "message", 25 | Data: map[string]interface{}{ 26 | "user": "manu", 27 | "date": time.Now().Unix(), 28 | "content": "hi!", 29 | }, 30 | }) 31 | } 32 | ``` 33 | ``` 34 | event: message 35 | data: some data\\nmore data 36 | 37 | id: 124 38 | event: message 39 | data: {"content":"hi!","date":1431540810,"user":"manu"} 40 | 41 | ``` 42 | 43 | ##Content-Type 44 | 45 | ```go 46 | fmt.Println(sse.ContentType) 47 | ``` 48 | ``` 49 | text/event-stream 50 | ``` 51 | 52 | ##Decoding support 53 | 54 | There is a client-side implementation of SSE coming soon. -------------------------------------------------------------------------------- /github.com/manucorporat/sse/sse-decoder_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 Manu Martinez-Almeida. All rights reserved. 2 | // Use of this source code is governed by a MIT style 3 | // license that can be found in the LICENSE file. 4 | 5 | package sse 6 | 7 | import ( 8 | "bytes" 9 | "testing" 10 | 11 | "github.com/stretchr/testify/assert" 12 | ) 13 | 14 | func TestDecodeSingle1(t *testing.T) { 15 | events, err := Decode(bytes.NewBufferString( 16 | `data: this is a text 17 | event: message 18 | fake: 19 | id: 123456789010 20 | : we can append data 21 | : and multiple comments should not break it 22 | data: a very nice one`)) 23 | 24 | assert.NoError(t, err) 25 | assert.Len(t, events, 1) 26 | assert.Equal(t, events[0].Event, "message") 27 | assert.Equal(t, events[0].Id, "123456789010") 28 | } 29 | 30 | func TestDecodeSingle2(t *testing.T) { 31 | events, err := Decode(bytes.NewBufferString( 32 | `: starting with a comment 33 | fake: 34 | 35 | data:this is a \ntext 36 | event:a message\n\n 37 | fake 38 | :and multiple comments\n should not break it\n\n 39 | id:1234567890\n10 40 | :we can append data 41 | data:a very nice one\n! 42 | 43 | 44 | `)) 45 | assert.NoError(t, err) 46 | assert.Len(t, events, 1) 47 | assert.Equal(t, events[0].Event, "a message\\n\\n") 48 | assert.Equal(t, events[0].Id, "1234567890\\n10") 49 | } 50 | 51 | func TestDecodeSingle3(t *testing.T) { 52 | events, err := Decode(bytes.NewBufferString( 53 | ` 54 | id:123456ABCabc789010 55 | event: message123 56 | : we can append data 57 | data:this is a text 58 | data: a very nice one 59 | data: 60 | data 61 | : ending with a comment`)) 62 | 63 | assert.NoError(t, err) 64 | assert.Len(t, events, 1) 65 | assert.Equal(t, events[0].Event, "message123") 66 | assert.Equal(t, events[0].Id, "123456ABCabc789010") 67 | } 68 | 69 | func TestDecodeMulti1(t *testing.T) { 70 | events, err := Decode(bytes.NewBufferString( 71 | ` 72 | id: 73 | event: weird event 74 | data:this is a text 75 | :data: this should NOT APER 76 | data: second line 77 | 78 | : a comment 79 | event: message 80 | id:123 81 | data:this is a text 82 | :data: this should NOT APER 83 | data: second line 84 | 85 | 86 | : a comment 87 | event: message 88 | id:123 89 | data:this is a text 90 | data: second line 91 | 92 | :hola 93 | 94 | data 95 | 96 | event: 97 | 98 | id`)) 99 | assert.NoError(t, err) 100 | assert.Len(t, events, 3) 101 | assert.Equal(t, events[0].Event, "weird event") 102 | assert.Equal(t, events[0].Id, "") 103 | } 104 | 105 | func TestDecodeW3C(t *testing.T) { 106 | events, err := Decode(bytes.NewBufferString( 107 | `data 108 | 109 | data 110 | data 111 | 112 | data: 113 | `)) 114 | assert.NoError(t, err) 115 | assert.Len(t, events, 1) 116 | } 117 | -------------------------------------------------------------------------------- /github.com/manucorporat/sse/sse-encoder.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 Manu Martinez-Almeida. All rights reserved. 2 | // Use of this source code is governed by a MIT style 3 | // license that can be found in the LICENSE file. 4 | 5 | package sse 6 | 7 | import ( 8 | "encoding/json" 9 | "fmt" 10 | "io" 11 | "net/http" 12 | "reflect" 13 | "strconv" 14 | "strings" 15 | ) 16 | 17 | // Server-Sent Events 18 | // W3C Working Draft 29 October 2009 19 | // http://www.w3.org/TR/2009/WD-eventsource-20091029/ 20 | 21 | const ContentType = "text/event-stream" 22 | 23 | var contentType = []string{ContentType} 24 | var noCache = []string{"no-cache"} 25 | 26 | var fieldReplacer = strings.NewReplacer( 27 | "\n", "\\n", 28 | "\r", "\\r") 29 | 30 | var dataReplacer = strings.NewReplacer( 31 | "\n", "\ndata:", 32 | "\r", "\\r") 33 | 34 | type Event struct { 35 | Event string 36 | Id string 37 | Retry uint 38 | Data interface{} 39 | } 40 | 41 | func Encode(writer io.Writer, event Event) error { 42 | w := checkWriter(writer) 43 | writeId(w, event.Id) 44 | writeEvent(w, event.Event) 45 | writeRetry(w, event.Retry) 46 | return writeData(w, event.Data) 47 | } 48 | 49 | func writeId(w stringWriter, id string) { 50 | if len(id) > 0 { 51 | w.WriteString("id:") 52 | fieldReplacer.WriteString(w, id) 53 | w.WriteString("\n") 54 | } 55 | } 56 | 57 | func writeEvent(w stringWriter, event string) { 58 | if len(event) > 0 { 59 | w.WriteString("event:") 60 | fieldReplacer.WriteString(w, event) 61 | w.WriteString("\n") 62 | } 63 | } 64 | 65 | func writeRetry(w stringWriter, retry uint) { 66 | if retry > 0 { 67 | w.WriteString("retry:") 68 | w.WriteString(strconv.FormatUint(uint64(retry), 10)) 69 | w.WriteString("\n") 70 | } 71 | } 72 | 73 | func writeData(w stringWriter, data interface{}) error { 74 | w.WriteString("data:") 75 | switch kindOfData(data) { 76 | case reflect.Struct, reflect.Slice, reflect.Map: 77 | err := json.NewEncoder(w).Encode(data) 78 | if err != nil { 79 | return err 80 | } 81 | w.WriteString("\n") 82 | default: 83 | dataReplacer.WriteString(w, fmt.Sprint(data)) 84 | w.WriteString("\n\n") 85 | } 86 | return nil 87 | } 88 | 89 | func (r Event) Render(w http.ResponseWriter) error { 90 | header := w.Header() 91 | header["Content-Type"] = contentType 92 | 93 | if _, exist := header["Cache-Control"]; !exist { 94 | header["Cache-Control"] = noCache 95 | } 96 | return Encode(w, r) 97 | } 98 | 99 | func kindOfData(data interface{}) reflect.Kind { 100 | value := reflect.ValueOf(data) 101 | valueType := value.Kind() 102 | if valueType == reflect.Ptr { 103 | valueType = value.Elem().Kind() 104 | } 105 | return valueType 106 | } 107 | -------------------------------------------------------------------------------- /github.com/manucorporat/sse/writer.go: -------------------------------------------------------------------------------- 1 | package sse 2 | 3 | import "io" 4 | 5 | type stringWriter interface { 6 | io.Writer 7 | WriteString(string) (int, error) 8 | } 9 | 10 | type stringWrapper struct { 11 | io.Writer 12 | } 13 | 14 | func (w stringWrapper) WriteString(str string) (int, error) { 15 | return w.Writer.Write([]byte(str)) 16 | } 17 | 18 | func checkWriter(writer io.Writer) stringWriter { 19 | if w, ok := writer.(stringWriter); ok { 20 | return w 21 | } else { 22 | return stringWrapper{writer} 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /github.com/nfnt/resize/.travis.yml: -------------------------------------------------------------------------------- 1 | language: go 2 | 3 | go: 4 | - 1.1 5 | - 1.2 6 | - 1.3 7 | - tip 8 | -------------------------------------------------------------------------------- /github.com/nfnt/resize/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2012, Jan Schlicht 2 | 3 | Permission to use, copy, modify, and/or distribute this software for any purpose 4 | with or without fee is hereby granted, provided that the above copyright notice 5 | and this permission notice appear in all copies. 6 | 7 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 8 | REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND 9 | FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 10 | INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS 11 | OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 12 | TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF 13 | THIS SOFTWARE. 14 | -------------------------------------------------------------------------------- /github.com/nfnt/resize/converter_test.go: -------------------------------------------------------------------------------- 1 | package resize 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func Test_ClampUint8(t *testing.T) { 8 | var testData = []struct { 9 | in int32 10 | expected uint8 11 | }{ 12 | {0, 0}, 13 | {255, 255}, 14 | {128, 128}, 15 | {-2, 0}, 16 | {256, 255}, 17 | } 18 | for _, test := range testData { 19 | actual := clampUint8(test.in) 20 | if actual != test.expected { 21 | t.Fail() 22 | } 23 | } 24 | } 25 | 26 | func Test_ClampUint16(t *testing.T) { 27 | var testData = []struct { 28 | in int64 29 | expected uint16 30 | }{ 31 | {0, 0}, 32 | {65535, 65535}, 33 | {128, 128}, 34 | {-2, 0}, 35 | {65536, 65535}, 36 | } 37 | for _, test := range testData { 38 | actual := clampUint16(test.in) 39 | if actual != test.expected { 40 | t.Fail() 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /github.com/nfnt/resize/nearest_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2014, Charlie Vieth 3 | 4 | Permission to use, copy, modify, and/or distribute this software for any purpose 5 | with or without fee is hereby granted, provided that the above copyright notice 6 | and this permission notice appear in all copies. 7 | 8 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 9 | REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND 10 | FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 11 | INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS 12 | OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 13 | TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF 14 | THIS SOFTWARE. 15 | */ 16 | 17 | package resize 18 | 19 | import "testing" 20 | 21 | func Test_FloatToUint8(t *testing.T) { 22 | var testData = []struct { 23 | in float32 24 | expected uint8 25 | }{ 26 | {0, 0}, 27 | {255, 255}, 28 | {128, 128}, 29 | {1, 1}, 30 | {256, 255}, 31 | } 32 | for _, test := range testData { 33 | actual := floatToUint8(test.in) 34 | if actual != test.expected { 35 | t.Fail() 36 | } 37 | } 38 | } 39 | 40 | func Test_FloatToUint16(t *testing.T) { 41 | var testData = []struct { 42 | in float32 43 | expected uint16 44 | }{ 45 | {0, 0}, 46 | {65535, 65535}, 47 | {128, 128}, 48 | {1, 1}, 49 | {65536, 65535}, 50 | } 51 | for _, test := range testData { 52 | actual := floatToUint16(test.in) 53 | if actual != test.expected { 54 | t.Fail() 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /github.com/nfnt/resize/thumbnail.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2012, Jan Schlicht 3 | 4 | Permission to use, copy, modify, and/or distribute this software for any purpose 5 | with or without fee is hereby granted, provided that the above copyright notice 6 | and this permission notice appear in all copies. 7 | 8 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 9 | REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND 10 | FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 11 | INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS 12 | OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 13 | TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF 14 | THIS SOFTWARE. 15 | */ 16 | 17 | package resize 18 | 19 | import ( 20 | "image" 21 | ) 22 | 23 | // Thumbnail will downscale provided image to max width and height preserving 24 | // original aspect ratio and using the interpolation function interp. 25 | // It will return original image, without processing it, if original sizes 26 | // are already smaller than provided constraints. 27 | func Thumbnail(maxWidth, maxHeight uint, img image.Image, interp InterpolationFunction) image.Image { 28 | origBounds := img.Bounds() 29 | origWidth := uint(origBounds.Dx()) 30 | origHeight := uint(origBounds.Dy()) 31 | newWidth, newHeight := origWidth, origHeight 32 | 33 | // Return original image if it have same or smaller size as constraints 34 | if maxWidth >= origWidth && maxHeight >= origHeight { 35 | return img 36 | } 37 | 38 | // Preserve aspect ratio 39 | if origWidth > maxWidth { 40 | newHeight = uint(origHeight * maxWidth / origWidth) 41 | if newHeight < 1 { 42 | newHeight = 1 43 | } 44 | newWidth = maxWidth 45 | } 46 | 47 | if newHeight > maxHeight { 48 | newWidth = uint(newWidth * maxHeight / newHeight) 49 | if newWidth < 1 { 50 | newWidth = 1 51 | } 52 | newHeight = maxHeight 53 | } 54 | return Resize(newWidth, newHeight, img, interp) 55 | } 56 | -------------------------------------------------------------------------------- /github.com/nfnt/resize/thumbnail_test.go: -------------------------------------------------------------------------------- 1 | package resize 2 | 3 | import ( 4 | "image" 5 | "runtime" 6 | "testing" 7 | ) 8 | 9 | func init() { 10 | runtime.GOMAXPROCS(runtime.NumCPU()) 11 | } 12 | 13 | var thumbnailTests = []struct { 14 | origWidth int 15 | origHeight int 16 | maxWidth uint 17 | maxHeight uint 18 | expectedWidth uint 19 | expectedHeight uint 20 | }{ 21 | {5, 5, 10, 10, 5, 5}, 22 | {10, 10, 5, 5, 5, 5}, 23 | {10, 50, 10, 10, 2, 10}, 24 | {50, 10, 10, 10, 10, 2}, 25 | {50, 100, 60, 90, 45, 90}, 26 | {120, 100, 60, 90, 60, 50}, 27 | {200, 250, 200, 150, 120, 150}, 28 | } 29 | 30 | func TestThumbnail(t *testing.T) { 31 | for i, tt := range thumbnailTests { 32 | img := image.NewGray16(image.Rect(0, 0, tt.origWidth, tt.origHeight)) 33 | 34 | outImg := Thumbnail(tt.maxWidth, tt.maxHeight, img, NearestNeighbor) 35 | 36 | newWidth := uint(outImg.Bounds().Dx()) 37 | newHeight := uint(outImg.Bounds().Dy()) 38 | if newWidth != tt.expectedWidth || 39 | newHeight != tt.expectedHeight { 40 | t.Errorf("%d. Thumbnail(%v, %v, img, NearestNeighbor) => "+ 41 | "width: %v, height: %v, want width: %v, height: %v", 42 | i, tt.maxWidth, tt.maxHeight, 43 | newWidth, newHeight, tt.expectedWidth, tt.expectedHeight, 44 | ) 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /github.com/oliamb/cutter/.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled Object files, Static and Dynamic libs (Shared Objects) 2 | *.o 3 | *.a 4 | *.so 5 | 6 | # Folders 7 | _obj 8 | _test 9 | 10 | # Architecture specific extensions/prefixes 11 | *.[568vq] 12 | [568vq].out 13 | 14 | *.cgo1.go 15 | *.cgo2.c 16 | _cgo_defun.c 17 | _cgo_gotypes.go 18 | _cgo_export.* 19 | 20 | _testmain.go 21 | 22 | *.exe 23 | -------------------------------------------------------------------------------- /github.com/oliamb/cutter/.travis.yml: -------------------------------------------------------------------------------- 1 | language: go 2 | 3 | go: 4 | - 1.0 5 | - 1.1 6 | - tip 7 | -------------------------------------------------------------------------------- /github.com/oliamb/cutter/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Olivier Amblet 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /github.com/oliamb/cutter/README.md: -------------------------------------------------------------------------------- 1 | Cutter 2 | ====== 3 | 4 | A Go library to crop images. 5 | 6 | [![Build Status](https://travis-ci.org/oliamb/cutter.png?branch=master)](https://travis-ci.org/oliamb/cutter) 7 | [![GoDoc](https://godoc.org/github.com/oliamb/cutter?status.png)](https://godoc.org/github.com/oliamb/cutter) 8 | 9 | Cutter was initially developped to be able 10 | to crop image resized using github.com/nfnt/resize. 11 | 12 | Usage 13 | ----- 14 | 15 | Read the doc on https://godoc.org/github.com/oliamb/cutter 16 | 17 | Import package with 18 | 19 | ```go 20 | import "github.com/oliamb/cutter" 21 | ``` 22 | 23 | Package cutter provides a function to crop image. 24 | 25 | By default, the original image will be cropped at the 26 | given size from the top left corner. 27 | 28 | ```go 29 | croppedImg, err := cutter.Crop(img, cutter.Config{ 30 | Width: 250, 31 | Height: 500, 32 | }) 33 | ``` 34 | 35 | Most of the time, the cropped image will share some memory 36 | with the original, so it should be used read only. You must 37 | ask explicitely for a copy if nedded. 38 | 39 | ```go 40 | croppedImg, err := cutter.Crop(img, cutter.Config{ 41 | Width: 250, 42 | Height: 500, 43 | Options: cutter.Copy, 44 | }) 45 | ``` 46 | 47 | It is possible to specify the top left position: 48 | 49 | ```go 50 | croppedImg, err := cutter.Crop(img, cutter.Config{ 51 | Width: 250, 52 | Height: 500, 53 | Anchor: image.Point{100, 100}, 54 | Mode: cutter.TopLeft, // optional, default value 55 | }) 56 | ``` 57 | 58 | The Anchor property can represents the center of the cropped image 59 | instead of the top left corner: 60 | 61 | ```go 62 | croppedImg, err := cutter.Crop(img, cutter.Config{ 63 | Width: 250, 64 | Height: 500, 65 | Mode: cutter.Centered, 66 | }) 67 | ``` 68 | 69 | The default crop use the specified dimension, but it is possible 70 | to use Width and Heigth as a ratio instead. In this case, 71 | the resulting image will be as big as possible to fit the asked ratio 72 | from the anchor position. 73 | 74 | ```go 75 | croppedImg, err := cutter.Crop(baseImage, cutter.Config{ 76 | Width: 4, 77 | Height: 3, 78 | Mode: cutter.Centered, 79 | Options: cutter.Ratio&cutter.Copy, // Copy is useless here 80 | }) 81 | ``` 82 | 83 | About resize 84 | ------------ 85 | This lib only manage crop and won't resize image, but it works great in combination with [github.com/nfnt/resize](https://github.com/nfnt/resize) 86 | 87 | Contributing 88 | ------------ 89 | I'd love to see your contributions to Cutter. If you'd like to hack on it: 90 | 91 | - fork the project, 92 | - hack on it, 93 | - ensure tests pass, 94 | - make a pull request 95 | 96 | If you plan to modify the API, let's disscuss it first. 97 | 98 | Licensing 99 | --------- 100 | MIT License, Please see the file called LICENSE. 101 | 102 | Credits 103 | ------- 104 | Test Picture: Gopher picture from Heidi Schuyt, http://www.flickr.com/photos/hschuyt/7674222278/, 105 | © copyright Creative Commons(http://creativecommons.org/licenses/by-nc-sa/2.0/) 106 | 107 | Thanks to Urturn(http://www.urturn.com) for the time allocated to develop the library. 108 | -------------------------------------------------------------------------------- /github.com/oliamb/cutter/benchmark_test.go: -------------------------------------------------------------------------------- 1 | package cutter 2 | 3 | import ( 4 | "image" 5 | "testing" 6 | ) 7 | 8 | /* 9 | BenchmarkCrop is used to track the Crop with sharing memory. 10 | 11 | Result on my laptop: 2000000 948 ns/op 12 | */ 13 | func BenchmarkCrop(b *testing.B) { 14 | img := getImage() 15 | 16 | c := Config{ 17 | Width: 1000, 18 | Height: 1000, 19 | Mode: TopLeft, 20 | Anchor: image.Point{100, 100}, 21 | } 22 | b.ResetTimer() 23 | for i := 0; i < b.N; i++ { 24 | Crop(img, c) 25 | } 26 | } 27 | 28 | /* 29 | BenchmarkCropCopy is used to track the Crop with copy performance. 30 | 31 | Below are the actual result on my laptop given each 32 | optimization suggested by Nigel Tao: https://groups.google.com/forum/#!topic/golang-nuts/qxSpOOp1QOk 33 | 34 | 1. initial time on my Laptop: 10 210332414 ns/op 35 | 2. after inverting x and y in copy loop: 10 195377177 ns/op 36 | 3. after removing useless call to ColorModel().Convert(): 10 193589075 ns/op 37 | 4. after replacing the two 'pixel' loops by a call to draw.Draw 38 | to obtains the cropped image: 20 84960510 ns/op 39 | */ 40 | func BenchmarkCropCopy(b *testing.B) { 41 | img := getImage() 42 | 43 | c := Config{ 44 | Width: 1000, 45 | Height: 1000, 46 | Mode: TopLeft, 47 | Anchor: image.Point{100, 100}, 48 | Options: Copy, 49 | } 50 | b.ResetTimer() 51 | for i := 0; i < b.N; i++ { 52 | Crop(img, c) 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /github.com/oliamb/cutter/cutter/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "errors" 5 | "flag" 6 | "fmt" 7 | "github.com/oliamb/cutter" 8 | "image" 9 | "image/jpeg" 10 | "image/png" 11 | "log" 12 | "os" 13 | "path/filepath" 14 | ) 15 | 16 | func main() { 17 | s := len(os.Args) 18 | if s < 4 { 19 | usage() 20 | return 21 | } 22 | fmt.Println("Args", os.Args) 23 | 24 | inPath := os.Args[s-2] 25 | fi, err := os.Open(inPath) 26 | if err != nil { 27 | log.Fatal("Cannot open input file '", inPath, "':", err) 28 | } 29 | 30 | outPath := os.Args[s-1] 31 | fo, err := os.Create(outPath) 32 | if err != nil { 33 | log.Fatal("Cannot create output file '", outPath, "':", err) 34 | } 35 | 36 | img, _, err := image.Decode(fi) 37 | if err != nil { 38 | log.Fatal("Cannot decode image at '", inPath, "':", err) 39 | } 40 | 41 | cImg, err := cutter.Crop(img, cutter.Config{ 42 | Height: 1000, // height in pixel or Y ratio(see Ratio Option below) 43 | Width: 1000, // width in pixel or X ratio 44 | Mode: cutter.TopLeft, // Accepted Mode: TopLeft, Centered 45 | Anchor: image.Point{100, 100}, // Position of the top left point 46 | Options: 0, // Accepted Option: Ratio 47 | }) 48 | if err != nil { 49 | log.Fatal("Cannot crop image:", err) 50 | } 51 | 52 | switch filepath.Ext(outPath) { 53 | case ".png": 54 | err = png.Encode(fo, cImg) 55 | case ".jpg": 56 | err = jpeg.Encode(fo, cImg, &jpeg.Options{}) 57 | default: 58 | err = errors.New("Unsupported format: " + filepath.Ext(outPath)) 59 | } 60 | if err != nil { 61 | log.Fatal(err) 62 | } 63 | fmt.Println("Image saved to", outPath) 64 | } 65 | 66 | func usage() { 67 | flag.Usage() 68 | } 69 | -------------------------------------------------------------------------------- /github.com/oliamb/cutter/example_test.go: -------------------------------------------------------------------------------- 1 | package cutter 2 | 3 | import ( 4 | "fmt" 5 | "image" 6 | _ "image/jpeg" 7 | "log" 8 | "os" 9 | _ "testing" 10 | ) 11 | 12 | func ExampleCrop() { 13 | f, err := os.Open("fixtures/gopher.jpg") 14 | if err != nil { 15 | log.Fatal("Cannot open file", err) 16 | } 17 | img, _, err := image.Decode(f) 18 | if err != nil { 19 | log.Fatal("Cannot decode image:", err) 20 | } 21 | 22 | cImg, err := Crop(img, Config{ 23 | Height: 500, // height in pixel or Y ratio(see Ratio Option below) 24 | Width: 500, // width in pixel or X ratio 25 | Mode: TopLeft, // Accepted Mode: TopLeft, Centered 26 | Anchor: image.Point{10, 10}, // Position of the top left point 27 | Options: 0, // Accepted Option: Ratio 28 | }) 29 | 30 | if err != nil { 31 | log.Fatal("Cannot crop image:", err) 32 | } 33 | fmt.Println("cImg dimension:", cImg.Bounds()) 34 | // Output: cImg dimension: (10,10)-(510,510) 35 | } 36 | -------------------------------------------------------------------------------- /github.com/oliamb/cutter/fixtures/gopher.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yalay/go-thumbnail/4c72c077e1308a1d176cfba1990200b7dc2d7a52/github.com/oliamb/cutter/fixtures/gopher.jpg -------------------------------------------------------------------------------- /public/pure/22.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yalay/go-thumbnail/4c72c077e1308a1d176cfba1990200b7dc2d7a52/public/pure/22.jpg -------------------------------------------------------------------------------- /util/cache.go: -------------------------------------------------------------------------------- 1 | package util 2 | 3 | import ( 4 | "image" 5 | "image/jpeg" 6 | "io/ioutil" 7 | "os" 8 | "time" 9 | ) 10 | 11 | var ( 12 | imgCache = NewSet() 13 | ) 14 | 15 | func init() { 16 | go run() 17 | } 18 | 19 | func WriteCache(imgUrl string, img image.Image) { 20 | cacheName := genCacheName(imgUrl) 21 | cacheFile, err := os.Create(CacheRoot + cacheName) 22 | if err != nil { 23 | Logln("WriteCache err:" + err.Error()) 24 | return 25 | } 26 | defer cacheFile.Close() 27 | jpeg.Encode(cacheFile, img, nil) 28 | imgCache.Add(cacheName) 29 | } 30 | 31 | func FindInCache(imgUrl string) []byte { 32 | cacheName := genCacheName(imgUrl) 33 | if !imgCache.Contains(cacheName) { 34 | return nil 35 | } 36 | 37 | cacheBuff, _ := ioutil.ReadFile(CacheRoot + cacheName) 38 | return cacheBuff 39 | } 40 | 41 | // %2FPure%2F22.jpg100x100 42 | func loadCache() { 43 | newImgCache := NewSet() 44 | if _, err := os.Stat(CacheRoot); err != nil { 45 | os.MkdirAll(CacheRoot, os.ModePerm) 46 | } 47 | 48 | files, _ := ioutil.ReadDir(CacheRoot) 49 | for _, file := range files { 50 | if file.IsDir() { 51 | continue 52 | } 53 | 54 | newImgCache.Add(file.Name()) 55 | } 56 | imgCache = newImgCache 57 | } 58 | 59 | func genCacheName(imgUrl string) string { 60 | return Md5Sum(imgUrl) 61 | } 62 | 63 | func run() { 64 | loadCache() 65 | timer := time.NewTimer(time.Hour) 66 | for { 67 | select { 68 | case <-timer.C: 69 | loadCache() 70 | timer.Reset(time.Hour) 71 | } 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /util/common.go: -------------------------------------------------------------------------------- 1 | package util 2 | 3 | import ( 4 | "crypto/md5" 5 | "fmt" 6 | "image" 7 | "io/ioutil" 8 | "os" 9 | "strconv" 10 | "strings" 11 | 12 | _ "github.com/golang/image/webp" 13 | _ "image/gif" 14 | _ "image/png" 15 | ) 16 | 17 | func LoadImage(imgPath string) (img image.Image, err error) { 18 | file, err := os.Open(ImgRoot + imgPath) 19 | if err != nil { 20 | return 21 | } 22 | defer file.Close() 23 | img, _, err = image.Decode(file) 24 | return 25 | } 26 | 27 | func LoadFile(imgPath string) ([]byte, error) { 28 | return ioutil.ReadFile(ImgRoot + imgPath) 29 | } 30 | 31 | func ParseImgArg(imgArg string) (uint, uint) { 32 | args := strings.Split(imgArg, "x") 33 | if len(args) != 2 { 34 | return 0, 0 35 | } 36 | 37 | width, _ := strconv.Atoi(args[0]) 38 | height, _ := strconv.Atoi(args[1]) 39 | return uint(width), uint(height) 40 | } 41 | 42 | func Md5Sum(key string) string { 43 | return fmt.Sprintf("%x", md5.Sum([]byte(key))) 44 | } 45 | -------------------------------------------------------------------------------- /util/conf.go: -------------------------------------------------------------------------------- 1 | package util 2 | 3 | import ( 4 | "flag" 5 | "strings" 6 | ) 7 | 8 | var ( 9 | CacheRoot = "./cache/" 10 | ImgRoot = "./public/" 11 | ServePort = "6789" 12 | ExtImgSize = "400x600" // 外链图片尺寸大小 13 | WaterMarkImg = "water.png" 14 | WaterSize = "1x1" // 1x1用来标记添加水印 15 | RedirectUrl = "" // 跳转路径,可以为本地路径 16 | LogFile = "log" 17 | AdPath = "/User" 18 | ) 19 | 20 | var ( 21 | Spiders = []string{"Baiduspider", "Googlebot", "360Spider"} 22 | AllowedRefer = "127.0.0.1" 23 | ) 24 | 25 | func init() { 26 | flag.StringVar(&CacheRoot, "cPath", "./cache/", "Cache path") 27 | flag.StringVar(&ImgRoot, "sPath", "./public/", "Source image path") 28 | flag.StringVar(&WaterMarkImg, "wImg", "water.png", "Water mark image") 29 | flag.StringVar(&ServePort, "port", "6789", "Server port") 30 | flag.StringVar(&RedirectUrl, "rUrl", "", "Redirect url") 31 | flag.StringVar(&AllowedRefer, "aRefer", "127.0.0.1,192.168.1.1", "Allowed refers, split by ,") 32 | flag.StringVar(&ExtImgSize, "eSize", "400x600", "ExtLink Img Size") 33 | flag.StringVar(&LogFile, "log", "log", "log file pre name") 34 | flag.StringVar(&AdPath, "adPath", "/User", "ad image path") 35 | flag.Parse() 36 | 37 | if !strings.HasSuffix(ImgRoot, "/") { 38 | ImgRoot += "/" 39 | } 40 | 41 | if !strings.HasSuffix(CacheRoot, "/") { 42 | CacheRoot += "/" 43 | } 44 | 45 | if !strings.HasSuffix(AdPath, "/") { 46 | AdPath += "/" 47 | } 48 | } 49 | 50 | func ReferAllow(refer string) bool { 51 | allowedRefers := strings.Split(AllowedRefer, ",") 52 | if len(allowedRefers) == 0 { 53 | return true 54 | } 55 | 56 | for _, allowedRefer := range allowedRefers { 57 | if strings.Contains(refer, allowedRefer) { 58 | return true 59 | } 60 | } 61 | return false 62 | } 63 | -------------------------------------------------------------------------------- /util/cookie.go: -------------------------------------------------------------------------------- 1 | package util 2 | 3 | import ( 4 | "io/ioutil" 5 | "math/rand" 6 | "net/http" 7 | "strconv" 8 | "time" 9 | 10 | "github.com/gin-gonic/gin" 11 | ) 12 | 13 | const ( 14 | cookieKey = "cnt" 15 | adMaxCounts = 24 16 | adHttpFlag = http.StatusTemporaryRedirect 17 | ) 18 | 19 | // 并发获取cookie缓存,用户id+[时间戳][计数] 20 | var ( 21 | cookieBuffMap = make(map[string]int, 0) 22 | cookieDelay = 24 * time.Second 23 | ) 24 | 25 | func Counter() gin.HandlerFunc { 26 | return func(context *gin.Context) { 27 | if ReferAllow(context.Request.Referer()) { 28 | return 29 | } 30 | 31 | cookie, err := context.Request.Cookie(cookieKey) 32 | if err == nil { 33 | if cookie.Path != "/" { 34 | cookie.Path = "/" 35 | cookie.Expires = time.Now().Add(4 * time.Hour) 36 | } 37 | 38 | userId := getUserId(context) 39 | cnt := getCookieValue(userId, cookie) 40 | cnt = setAdStatus(cnt, userId, context) 41 | cookie.Value = strconv.Itoa(cnt) 42 | http.SetCookie(context.Writer, cookie) 43 | //Logln("[GIN] userId:" + userId + " cookie value:" + cookie.Value) 44 | } else { 45 | http.SetCookie(context.Writer, &http.Cookie{ 46 | Name: cookieKey, 47 | Value: "0", 48 | Path: "/", 49 | MaxAge: 4 * 60 * 60, 50 | Expires: time.Now().Add(4 * time.Hour), 51 | }) 52 | } 53 | context.Next() 54 | } 55 | } 56 | 57 | func DoAd(context *gin.Context) bool { 58 | if context.Writer.Status() == adHttpFlag { 59 | return true 60 | } 61 | return false 62 | } 63 | 64 | func GetRandomAdPath() string { 65 | imgs, err := ioutil.ReadDir(ImgRoot + AdPath) 66 | if err != nil || len(imgs) == 0 { 67 | return "" 68 | } 69 | return AdPath + imgs[rand.Intn(len(imgs))].Name() 70 | } 71 | 72 | func getUserId(context *gin.Context) string { 73 | return context.ClientIP() + context.Request.UserAgent() 74 | } 75 | 76 | func getCookieValue(userId string, cookie *http.Cookie) int { 77 | if cnt, ok := cookieBuffMap[userId]; ok { 78 | return cnt 79 | } else { 80 | cookieCnt, _ := strconv.Atoi(cookie.Value) 81 | cookieBuffMap[userId] = cookieCnt 82 | go cookieBuffDelay(userId) 83 | return cookieCnt 84 | } 85 | } 86 | 87 | func setAdStatus(count int, userId string, context *gin.Context) int { 88 | if count < adMaxCounts { 89 | count++ 90 | } else { 91 | count = 0 92 | Logln("[GIN] Ad. UserId:" + userId) 93 | context.Status(adHttpFlag) 94 | } 95 | 96 | if _, ok := cookieBuffMap[userId]; ok { 97 | cookieBuffMap[userId] = count 98 | } 99 | return count 100 | } 101 | 102 | func cookieBuffDelay(key string) { 103 | time.Sleep(cookieDelay) 104 | if _, ok := cookieBuffMap[key]; ok { 105 | delete(cookieBuffMap, key) 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /util/crop.go: -------------------------------------------------------------------------------- 1 | package util 2 | 3 | import ( 4 | "github.com/oliamb/cutter" 5 | "image" 6 | ) 7 | 8 | func CropImg(srcImg image.Image, dstWidth, dstHeight int) image.Image { 9 | origBounds := srcImg.Bounds() 10 | origWidth := origBounds.Dx() 11 | origHeight := origBounds.Dy() 12 | 13 | dstImg, err := cutter.Crop(srcImg, cutter.Config{ 14 | Height: dstHeight, // height in pixel or Y ratio(see Ratio Option below) 15 | Width: dstWidth, // width in pixel or X ratio 16 | Mode: cutter.TopLeft, // Accepted Mode: TopLeft, Centered 17 | Anchor: image.Point{ 18 | origWidth / 12, 19 | origHeight / 8}, // Position of the top left point 20 | Options: 0, // Accepted Option: Ratio 21 | }) 22 | if err != nil { 23 | Logln("[GIN] Cannot crop image:" + err.Error()) 24 | return srcImg 25 | } 26 | return dstImg 27 | } 28 | -------------------------------------------------------------------------------- /util/log.go: -------------------------------------------------------------------------------- 1 | package util 2 | 3 | import ( 4 | "bytes" 5 | "os" 6 | "time" 7 | ) 8 | 9 | var ( 10 | logBuffer = &bytes.Buffer{} 11 | writeDutation = 5 * time.Minute 12 | ) 13 | 14 | func init() { 15 | go writeLog() 16 | } 17 | 18 | func GetLogBuf() *bytes.Buffer { 19 | return logBuffer 20 | } 21 | 22 | func Log(msg string) { 23 | logBuffer.WriteString(msg) 24 | } 25 | 26 | func Logln(msg string) { 27 | logBuffer.WriteString(msg + "\n") 28 | } 29 | 30 | func writeLog() { 31 | for { 32 | todady := time.Now().Format("2006-01-02") 33 | file, err := os.OpenFile(LogFile+"."+todady, os.O_CREATE|os.O_WRONLY|os.O_APPEND, os.ModePerm) 34 | if err != nil { 35 | break 36 | } 37 | if logBuffer.Len() > 0 { 38 | logBuffer.WriteTo(file) 39 | } 40 | file.Close() 41 | time.Sleep(writeDutation) 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /util/thumbnail.go: -------------------------------------------------------------------------------- 1 | package util 2 | 3 | // 修改自github.com/nfnt/resize/thumbnail.go 4 | // 参数中最大长宽修改为最小长宽 5 | import ( 6 | "github.com/nfnt/resize" 7 | "image" 8 | ) 9 | 10 | // 缩略图按照指定的宽和高非失真缩放裁剪 11 | func ThumbnailCrop(minWidth, minHeight uint, img image.Image) image.Image { 12 | origBounds := img.Bounds() 13 | origWidth := uint(origBounds.Dx()) 14 | origHeight := uint(origBounds.Dy()) 15 | newWidth, newHeight := origWidth, origHeight 16 | 17 | // Return original image if it have same or smaller size as constraints 18 | if minWidth >= origWidth && minHeight >= origHeight { 19 | return img 20 | } 21 | 22 | if minWidth > origWidth { 23 | minWidth = origWidth 24 | } 25 | 26 | if minHeight > origHeight { 27 | minHeight = origHeight 28 | } 29 | 30 | // Preserve aspect ratio 31 | if origWidth > minWidth { 32 | newHeight = uint(origHeight * minWidth / origWidth) 33 | if newHeight < 1 { 34 | newHeight = 1 35 | } 36 | newWidth = minWidth 37 | } 38 | 39 | if newHeight < minHeight { 40 | newWidth = uint(newWidth * minHeight / newHeight) 41 | if newWidth < 1 { 42 | newWidth = 1 43 | } 44 | newHeight = minHeight 45 | } 46 | 47 | thumbImg := resize.Resize(newWidth, newHeight, img, resize.Lanczos3) 48 | return CropImg(thumbImg, int(minWidth), int(minHeight)) 49 | } 50 | 51 | // 简单的缩放,指定最大宽和高 52 | func ThumbnailSimple(maxWidth, maxHeight uint, img image.Image) image.Image { 53 | oriBounds := img.Bounds() 54 | oriWidth := uint(oriBounds.Dx()) 55 | oriHeight := uint(oriBounds.Dy()) 56 | 57 | if maxWidth == 0 { 58 | maxWidth = oriWidth 59 | } 60 | 61 | if maxHeight == 0 { 62 | maxHeight = oriHeight 63 | } 64 | return resize.Thumbnail(maxWidth, maxHeight, img, resize.Lanczos3) 65 | } 66 | -------------------------------------------------------------------------------- /util/watermark.go: -------------------------------------------------------------------------------- 1 | package util 2 | 3 | import ( 4 | "image" 5 | "image/draw" 6 | ) 7 | 8 | // 加水印 9 | func WaterMark(srcImg image.Image) (image.Image, error) { 10 | // 读取水印图片 11 | markImg, err := LoadImage(WaterMarkImg) 12 | if err != nil { 13 | return nil, err 14 | } 15 | 16 | //把水印写到右下角,并向0坐标各偏移10个像素 17 | srcBounds := srcImg.Bounds() 18 | offset := image.Pt(srcBounds.Dx()-markImg.Bounds().Dx()-10, srcBounds.Dy()-markImg.Bounds().Dy()-10) 19 | newImg := image.NewNRGBA(srcBounds) 20 | draw.Draw(newImg, srcBounds, srcImg, image.ZP, draw.Src) 21 | draw.Draw(newImg, markImg.Bounds().Add(offset), markImg, image.ZP, draw.Over) 22 | return newImg, nil 23 | } 24 | --------------------------------------------------------------------------------