forked from corestoreio/pkg
-
Notifications
You must be signed in to change notification settings - Fork 0
/
options.go
112 lines (101 loc) · 4.43 KB
/
options.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
// Copyright 2015-present, Cyrill @ Schumacher.fm and the CoreStore contributors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package maxmindwebservice
import (
"encoding/gob"
"net/http"
"time"
"github.com/corestoreio/errors"
"github.com/corestoreio/pkg/config"
"github.com/corestoreio/pkg/config/cfgmodel"
"github.com/corestoreio/pkg/net/geoip"
"github.com/corestoreio/pkg/storage/transcache"
"github.com/corestoreio/pkg/storage/transcache/tcbigcache"
"github.com/corestoreio/pkg/storage/transcache/tcredis"
)
// required by the transcache package
func init() {
gob.Register(geoip.Country{})
}
// WithCountryFinder uses for each incoming a request a lookup request to the
// Maxmind Webservice http://dev.maxmind.com/geoip/geoip2/web-services/ and
// caches the result in Transcacher. Hint: use package storage/transcache. If
// the httpTimeout is lower 0 then the default 20s get applied.
func WithCountryFinder(t TransCacher, userID, licenseKey string, httpTimeout time.Duration) geoip.Option {
if httpTimeout < 1 {
httpTimeout = time.Second * 20
}
return WithCountryFinderHTTPClient(&http.Client{Timeout: httpTimeout}, t, userID, licenseKey)
}
// WithCountryFinderHTTPClient uses for each incoming a request a lookup
// request to the Maxmind Webservice
// http://dev.maxmind.com/geoip/geoip2/web-services/ and caches the result in
// Transcacher. Hint: use package storage/transcache.
func WithCountryFinderHTTPClient(hc *http.Client, t TransCacher, userID, licenseKey string) geoip.Option {
return geoip.WithCountryFinder(newMMWS(t, userID, licenseKey, hc))
}
// OptionName identifies this package within the register of the
// backendgeoip.Configuration type.
const OptionName = `webservice`
// NewOptionFactory creates a new option factory function for the MaxMind web
// service in the backend package to be used for automatic scope based
// configuration initialization. Configuration values must be set from package
// backendgeoip.Configuration.
//
// First argument http.Client allows you to use a custom client when making
// requests to the MaxMind webservice. The timeout gets set by configuration
// path MaxmindWebserviceTimeout.
//
// gob.Register(geoip.Country{}) has already been called.
func NewOptionFactory(hc *http.Client, userID, license cfgmodel.Str, timeout cfgmodel.Duration, redisURL cfgmodel.URL) (optionName string, _ geoip.OptionFactoryFunc) {
return OptionName, func(sg config.Scoped) []geoip.Option {
vUserID, err := userID.Get(sg)
if err != nil {
return geoip.OptionsError(errors.Wrap(err, "[maxmindwebservice] MaxmindWebserviceUserID.Get"))
}
vLicense, err := license.Get(sg)
if err != nil {
return geoip.OptionsError(errors.Wrap(err, "[maxmindwebservice] MaxmindWebserviceLicense.Get"))
}
vTimeout, err := timeout.Get(sg)
if err != nil {
return geoip.OptionsError(errors.Wrap(err, "[maxmindwebservice] MaxmindWebserviceTimeout.Get"))
}
vRedisURL, err := redisURL.Get(sg)
if err != nil {
return geoip.OptionsError(errors.Wrap(err, "[maxmindwebservice] MaxmindWebserviceRedisURL.Get"))
}
var tco [2]objcache.Option
switch {
case vRedisURL != nil:
tco[0] = tcredis.WithURL(vRedisURL.String(), nil, true)
default:
tco[0] = tcbigcache.With()
}
tco[1] = objcache.WithPooledEncoder(objcache.GobCodec{}, geoip.Country{}) // prime gob with the Country struct
// for now only encoding/gob can be used, we might make it configurable
// to choose the encoder/decoder.
tc, err := objcache.NewProcessor(tco[:]...)
if err != nil {
return geoip.OptionsError(errors.Wrap(err, "[maxmindwebservice] transcache.NewProcessor"))
}
if vUserID == "" || vLicense == "" || vTimeout < 1 {
return geoip.OptionsError(errors.NewNotValidf("[maxmindwebservice] Incomplete WebService configuration: User: %q License %q Timeout: %d (zero timeout not supported)", vUserID, vLicense, vTimeout))
}
hc.Timeout = vTimeout
return []geoip.Option{
WithCountryFinderHTTPClient(hc, tc, vUserID, vLicense),
}
}
}