mirror of
https://github.com/mattermost/mattermost.git
synced 2026-05-28 04:35:04 -04:00
Updating server dependancies. (#7538)
This commit is contained in:
parent
8b9dbb8613
commit
b84736e9b6
422 changed files with 39231 additions and 28592 deletions
4
Makefile
4
Makefile
|
|
@ -80,7 +80,7 @@ endif
|
|||
# Prepares the enterprise build if exists. The IGNORE stuff is a hack to get the Makefile to execute the commands outside a target
|
||||
ifeq ($(BUILD_ENTERPRISE_READY),true)
|
||||
IGNORE:=$(shell echo Enterprise build selected, preparing)
|
||||
IGNORE:=$(shell mkdir -p imports/)
|
||||
IGNORE:=$(shell rm -f imports/imports.go)
|
||||
IGNORE:=$(shell cp $(BUILD_ENTERPRISE_DIR)/imports/imports.go imports/)
|
||||
IGNORE:=$(shell rm -f enterprise)
|
||||
IGNORE:=$(shell ln -s $(BUILD_ENTERPRISE_DIR) enterprise)
|
||||
|
|
@ -465,7 +465,7 @@ clean: stop-docker
|
|||
rm -f ecover.out
|
||||
rm -f *.out
|
||||
rm -f *.test
|
||||
rm -f imports.go
|
||||
rm -f imports/imports.go
|
||||
|
||||
nuke: clean clean-docker
|
||||
@echo BOOM
|
||||
|
|
|
|||
|
|
@ -1,106 +0,0 @@
|
|||
// Copyright (c) 2017-present Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/mattermost/platform/app"
|
||||
"github.com/mattermost/platform/model"
|
||||
)
|
||||
|
||||
func TestParseChannelArg(t *testing.T) {
|
||||
if team, channel := parseChannelArg("channel"); team != "" {
|
||||
t.Fatal("got incorrect team", team)
|
||||
} else if channel != "channel" {
|
||||
t.Fatal("got incorrect channel", channel)
|
||||
}
|
||||
|
||||
if team, channel := parseChannelArg("team:channel"); team != "team" {
|
||||
t.Fatal("got incorrect team", team)
|
||||
} else if channel != "channel" {
|
||||
t.Fatal("got incorrect channel", channel)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetChannelFromChannelArg(t *testing.T) {
|
||||
th := app.Setup().InitBasic()
|
||||
|
||||
team := th.BasicTeam
|
||||
channel := th.BasicChannel
|
||||
|
||||
if found := getChannelFromChannelArg(""); found != nil {
|
||||
t.Fatal("shoudn't have gotten a channel", found)
|
||||
}
|
||||
|
||||
if found := getChannelFromChannelArg(channel.Id); found == nil || found.Id != channel.Id {
|
||||
t.Fatal("got incorrect channel", found)
|
||||
}
|
||||
|
||||
if found := getChannelFromChannelArg(model.NewId()); found != nil {
|
||||
t.Fatal("shouldn't have gotten a channel that doesn't exist", found)
|
||||
}
|
||||
|
||||
if found := getChannelFromChannelArg(channel.Name); found != nil {
|
||||
t.Fatal("shouldn't have gotten a channel by name without team", found)
|
||||
}
|
||||
|
||||
if found := getChannelFromChannelArg(team.Id + ":" + channel.Name); found == nil || found.Id != channel.Id {
|
||||
t.Fatal("got incorrect channel", found)
|
||||
}
|
||||
|
||||
if found := getChannelFromChannelArg(team.Name + ":" + channel.Name); found == nil || found.Id != channel.Id {
|
||||
t.Fatal("got incorrect channel", found)
|
||||
}
|
||||
|
||||
if found := getChannelFromChannelArg(team.Name + ":" + channel.Id); found == nil || found.Id != channel.Id {
|
||||
t.Fatal("got incorrect channel", found)
|
||||
}
|
||||
|
||||
if found := getChannelFromChannelArg("notateam" + ":" + channel.Name); found != nil {
|
||||
t.Fatal("shouldn't have gotten a channel by name on incorrect team", found)
|
||||
}
|
||||
|
||||
if found := getChannelFromChannelArg(team.Name + ":" + "notachannel"); found != nil {
|
||||
t.Fatal("shouldn't have gotten a channel that doesn't exist", found)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetChannelsFromChannelArg(t *testing.T) {
|
||||
th := app.Setup().InitBasic()
|
||||
|
||||
team := th.BasicTeam
|
||||
channel := th.BasicChannel
|
||||
channel2 := th.CreateChannel(team)
|
||||
|
||||
if found := getChannelsFromChannelArgs([]string{}); len(found) != 0 {
|
||||
t.Fatal("shoudn't have gotten any channels", found)
|
||||
}
|
||||
|
||||
if found := getChannelsFromChannelArgs([]string{channel.Id}); len(found) == 1 && found[0].Id != channel.Id {
|
||||
t.Fatal("got incorrect channel", found)
|
||||
}
|
||||
|
||||
if found := getChannelsFromChannelArgs([]string{team.Name + ":" + channel2.Name}); len(found) == 1 && found[0].Id != channel2.Id {
|
||||
t.Fatal("got incorrect channel", found)
|
||||
}
|
||||
|
||||
if found := getChannelsFromChannelArgs([]string{team.Name + ":" + channel.Name, team.Name + ":" + channel2.Name}); len(found) != 2 {
|
||||
t.Fatal("got incorrect number of channels", found)
|
||||
} else if !(found[0].Id == channel.Id && found[1].Id == channel2.Id) && !(found[1].Id == channel.Id && found[0].Id == channel2.Id) {
|
||||
t.Fatal("got incorrect channels", found[0], found[1])
|
||||
}
|
||||
|
||||
if found := getChannelsFromChannelArgs([]string{channel.Id, channel2.Id}); len(found) != 2 {
|
||||
t.Fatal("got incorrect number of channels", found)
|
||||
} else if !(found[0].Id == channel.Id && found[1].Id == channel2.Id) && !(found[1].Id == channel.Id && found[0].Id == channel2.Id) {
|
||||
t.Fatal("got incorrect channels", found[0], found[1])
|
||||
}
|
||||
|
||||
if found := getChannelsFromChannelArgs([]string{channel.Id, team.Name + ":" + channel2.Name}); len(found) != 2 {
|
||||
t.Fatal("got incorrect number of channels", found)
|
||||
} else if !(found[0].Id == channel.Id && found[1].Id == channel2.Id) && !(found[1].Id == channel.Id && found[0].Id == channel2.Id) {
|
||||
t.Fatal("got incorrect channels", found[0], found[1])
|
||||
}
|
||||
}
|
||||
|
|
@ -1,58 +0,0 @@
|
|||
// Copyright (c) 2017-present Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/mattermost/platform/app"
|
||||
"github.com/mattermost/platform/model"
|
||||
)
|
||||
|
||||
func TestGetTeamFromTeamArg(t *testing.T) {
|
||||
th := app.Setup().InitBasic()
|
||||
|
||||
team := th.BasicTeam
|
||||
|
||||
if found := getTeamFromTeamArg(""); found != nil {
|
||||
t.Fatal("shoudn't have gotten a team", found)
|
||||
}
|
||||
|
||||
if found := getTeamFromTeamArg(model.NewId()); found != nil {
|
||||
t.Fatal("shoudn't have gotten a team", found)
|
||||
}
|
||||
|
||||
if found := getTeamFromTeamArg(team.Id); found == nil || found.Id != team.Id {
|
||||
t.Fatal("got incorrect team", found)
|
||||
}
|
||||
|
||||
if found := getTeamFromTeamArg(team.Name); found == nil || found.Id != team.Id {
|
||||
t.Fatal("got incorrect team", found)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetTeamsFromTeamArg(t *testing.T) {
|
||||
th := app.Setup().InitBasic()
|
||||
|
||||
team := th.BasicTeam
|
||||
team2 := th.CreateTeam()
|
||||
|
||||
if found := getTeamsFromTeamArgs([]string{}); len(found) != 0 {
|
||||
t.Fatal("shoudn't have gotten any teams", found)
|
||||
}
|
||||
|
||||
if found := getTeamsFromTeamArgs([]string{team.Id}); len(found) == 1 && found[0].Id != team.Id {
|
||||
t.Fatal("got incorrect team", found)
|
||||
}
|
||||
|
||||
if found := getTeamsFromTeamArgs([]string{team2.Name}); len(found) == 1 && found[0].Id != team2.Id {
|
||||
t.Fatal("got incorrect team", found)
|
||||
}
|
||||
|
||||
if found := getTeamsFromTeamArgs([]string{team.Name, team2.Id}); len(found) != 2 {
|
||||
t.Fatal("got incorrect number of teams", found)
|
||||
} else if !(found[0].Id == team.Id && found[1].Id == team2.Id) && !(found[1].Id == team.Id && found[0].Id == team2.Id) {
|
||||
t.Fatal("got incorrect teams", found[0], found[1])
|
||||
}
|
||||
}
|
||||
|
|
@ -1,212 +0,0 @@
|
|||
// Copyright (c) 2017-present Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/mattermost/platform/app"
|
||||
"github.com/mattermost/platform/model"
|
||||
)
|
||||
|
||||
func TestChangeUserActiveStatus(t *testing.T) {
|
||||
th := app.Setup().InitBasic()
|
||||
|
||||
user := th.BasicUser
|
||||
|
||||
if err := changeUserActiveStatus(nil, "user", false); err == nil {
|
||||
t.Fatal("should've returned error when user doesn't exist")
|
||||
}
|
||||
|
||||
if err := changeUserActiveStatus(user, user.Username, false); err != nil {
|
||||
t.Fatal(err)
|
||||
} else if user, _ = app.GetUser(user.Id); user.DeleteAt == 0 {
|
||||
t.Fatal("should've deactivated user")
|
||||
}
|
||||
|
||||
if err := changeUserActiveStatus(user, user.Username, true); err != nil {
|
||||
t.Fatal(err)
|
||||
} else if user, _ := app.GetUser(user.Id); user.DeleteAt != 0 {
|
||||
t.Fatal("should've activated user")
|
||||
}
|
||||
}
|
||||
|
||||
func TestChangeUsersActiveStatus(t *testing.T) {
|
||||
th := app.Setup().InitBasic()
|
||||
|
||||
user := th.BasicUser
|
||||
user2 := th.CreateUser()
|
||||
|
||||
changeUsersActiveStatus([]string{user.Username, user2.Id}, false)
|
||||
|
||||
if user, _ = app.GetUser(user.Id); user.DeleteAt == 0 {
|
||||
t.Fatal("should've deactivated user")
|
||||
} else if user2, _ = app.GetUser(user2.Id); user2.DeleteAt == 0 {
|
||||
t.Fatal("should've deactivated user")
|
||||
}
|
||||
|
||||
changeUsersActiveStatus([]string{user.Username, user2.Id}, true)
|
||||
|
||||
if user, _ = app.GetUser(user.Id); user.DeleteAt != 0 {
|
||||
t.Fatal("should've activated user")
|
||||
} else if user2, _ = app.GetUser(user2.Id); user2.DeleteAt != 0 {
|
||||
t.Fatal("should've activated user")
|
||||
}
|
||||
}
|
||||
|
||||
func TestUserActivateDeactivateCmdF(t *testing.T) {
|
||||
th := app.Setup().InitBasic()
|
||||
|
||||
user := th.BasicUser
|
||||
user2 := th.CreateUser()
|
||||
|
||||
userDeactivateCmdF(userDeactivateCmd, []string{user.Username, user2.Id})
|
||||
|
||||
if user, _ = app.GetUser(user.Id); user.DeleteAt == 0 {
|
||||
t.Fatal("should've deactivated user")
|
||||
} else if user2, _ = app.GetUser(user2.Id); user2.DeleteAt == 0 {
|
||||
t.Fatal("should've deactivated user")
|
||||
}
|
||||
|
||||
userActivateCmdF(userActivateCmd, []string{user.Username, user2.Id})
|
||||
|
||||
if user, _ = app.GetUser(user.Id); user.DeleteAt != 0 {
|
||||
t.Fatal("should've activated user")
|
||||
} else if user2, _ = app.GetUser(user2.Id); user2.DeleteAt != 0 {
|
||||
t.Fatal("should've activated user")
|
||||
}
|
||||
}
|
||||
|
||||
func TestUserActivateDeactivateCmd(t *testing.T) {
|
||||
th := app.Setup().InitBasic()
|
||||
|
||||
user := th.BasicUser
|
||||
user2 := th.CreateUser()
|
||||
|
||||
if err := runCommand("user deactivate " + user.Username + " " + user2.Id); err != nil {
|
||||
t.Fatal(err)
|
||||
} else if user, _ = app.GetUser(user.Id); user.DeleteAt == 0 {
|
||||
t.Fatal("should've deactivated user")
|
||||
} else if user2, _ = app.GetUser(user2.Id); user2.DeleteAt == 0 {
|
||||
t.Fatal("should've deactivated user")
|
||||
}
|
||||
|
||||
if err := runCommand("user activate " + user.Id + " " + user2.Username); err != nil {
|
||||
t.Fatal(err)
|
||||
} else if user, _ = app.GetUser(user.Id); user.DeleteAt != 0 {
|
||||
t.Fatal("should've activated user")
|
||||
} else if user2, _ = app.GetUser(user2.Id); user2.DeleteAt != 0 {
|
||||
t.Fatal("should've activated user")
|
||||
}
|
||||
}
|
||||
|
||||
func TestUserCreateCmd(t *testing.T) {
|
||||
th := app.Setup().InitBasic()
|
||||
|
||||
if err := runCommand("user create"); err == nil {
|
||||
t.Fatal("should've failed without any arguments")
|
||||
}
|
||||
|
||||
username := th.MakeUsername()
|
||||
email := th.MakeEmail()
|
||||
if err := runCommand("user create --username " + username + " --email " + email + " --password " + model.NewId()); err != nil {
|
||||
t.Fatal(err)
|
||||
} else if user, err := app.GetUserByUsername(username); err != nil {
|
||||
t.Fatal(err.Message)
|
||||
} else if user.Username != username {
|
||||
t.Fatal("should've set correct username")
|
||||
} else if user.Email != email {
|
||||
t.Fatal("should've set correct email")
|
||||
}
|
||||
|
||||
username = th.MakeUsername()
|
||||
nickname := model.NewId()
|
||||
firstName := model.NewId()
|
||||
lastName := model.NewId()
|
||||
locale := "fr"
|
||||
if err := runCommand("user create --username " + username + " --email " + th.MakeEmail() + " --password " + model.NewId() +
|
||||
" --nickname " + nickname + " --firstname " + firstName + " --lastname " + lastName + " --locale " + locale); err != nil {
|
||||
t.Fatal(err)
|
||||
} else if user, err := app.GetUserByUsername(username); err != nil {
|
||||
t.Fatal(err)
|
||||
} else if user.Nickname != nickname {
|
||||
t.Fatal("should've set correct nickname")
|
||||
} else if user.FirstName != firstName {
|
||||
t.Fatal("should've set correct first name")
|
||||
} else if user.LastName != lastName {
|
||||
t.Fatal("should've set correct last name")
|
||||
} else if user.Locale != locale {
|
||||
t.Fatal("should've set correct locale", user.Locale)
|
||||
} else if user.Roles != "system_user" {
|
||||
t.Fatal("should've set correct roles for user")
|
||||
}
|
||||
|
||||
username = th.MakeUsername()
|
||||
if err := runCommand("user create --username " + username + " --email " + th.MakeEmail() + " --password " + model.NewId() + " --system_admin"); err != nil {
|
||||
t.Fatal(err)
|
||||
} else if user, err := app.GetUserByUsername(username); err != nil {
|
||||
t.Fatal(err)
|
||||
} else if user.Roles != "system_user system_admin" {
|
||||
t.Fatal("should've set correct roles for system admin")
|
||||
}
|
||||
|
||||
if err := runCommand("user create --email " + th.MakeEmail() + " --password " + model.NewId()); err == nil {
|
||||
t.Fatal("should've failed without username")
|
||||
}
|
||||
|
||||
if err := runCommand("user create --username " + th.MakeUsername() + " --email " + th.MakeEmail()); err == nil {
|
||||
t.Fatal("should've failed without password")
|
||||
}
|
||||
|
||||
if err := runCommand("user create --username " + th.MakeUsername() + " --password " + model.NewId()); err == nil {
|
||||
t.Fatal("should've failed without email")
|
||||
}
|
||||
}
|
||||
|
||||
func TestInviteUser(t *testing.T) {
|
||||
th := app.Setup().InitBasic()
|
||||
|
||||
team := th.CreateTeam()
|
||||
|
||||
if err := inviteUser(th.MakeEmail(), nil, "faketeam"); err == nil {
|
||||
t.Fatal("should've failed with nonexistent team")
|
||||
}
|
||||
|
||||
if err := inviteUser(th.MakeEmail(), team, team.Name); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// Nothing else to test here since this just fires off an email
|
||||
}
|
||||
|
||||
func TestUserInviteCmd(t *testing.T) {
|
||||
th := app.Setup().InitBasic()
|
||||
|
||||
team := th.BasicTeam
|
||||
team2 := th.CreateTeam()
|
||||
|
||||
if err := runCommand("user invite"); err == nil {
|
||||
t.Fatal("should've failed without any arguments")
|
||||
}
|
||||
|
||||
if err := runCommand("user invite " + th.MakeEmail()); err == nil {
|
||||
t.Fatal("should've failed with 1 argument")
|
||||
}
|
||||
|
||||
if err := runCommand("user invite " + th.MakeEmail() + " " + team.Id); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if err := runCommand("user invite " + th.MakeEmail() + " " + team.Name); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if err := runCommand("user invite " + th.MakeEmail() + " " + team.Id + " " + team2.Name); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if err := runCommand("user invite " + th.MakeEmail() + " " + team.Id + " " + team2.Name + " " + "faketeam"); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
|
@ -1,58 +0,0 @@
|
|||
// Copyright (c) 2017-present Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/mattermost/platform/app"
|
||||
"github.com/mattermost/platform/model"
|
||||
)
|
||||
|
||||
func TestGetUserFromUserArg(t *testing.T) {
|
||||
th := app.Setup().InitBasic()
|
||||
|
||||
user := th.BasicUser
|
||||
|
||||
if found := getUserFromUserArg(""); found != nil {
|
||||
t.Fatal("shoudn't have gotten a user", found)
|
||||
}
|
||||
|
||||
if found := getUserFromUserArg(model.NewId()); found != nil {
|
||||
t.Fatal("shoudn't have gotten a user", found)
|
||||
}
|
||||
|
||||
if found := getUserFromUserArg(user.Id); found == nil || found.Id != user.Id {
|
||||
t.Fatal("got incorrect user", found)
|
||||
}
|
||||
|
||||
if found := getUserFromUserArg(user.Username); found == nil || found.Id != user.Id {
|
||||
t.Fatal("got incorrect user", found)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetUsersFromUserArg(t *testing.T) {
|
||||
th := app.Setup().InitBasic()
|
||||
|
||||
user := th.BasicUser
|
||||
user2 := th.CreateUser()
|
||||
|
||||
if found := getUsersFromUserArgs([]string{}); len(found) != 0 {
|
||||
t.Fatal("shoudn't have gotten any users", found)
|
||||
}
|
||||
|
||||
if found := getUsersFromUserArgs([]string{user.Id}); len(found) == 1 && found[0].Id != user.Id {
|
||||
t.Fatal("got incorrect user", found)
|
||||
}
|
||||
|
||||
if found := getUsersFromUserArgs([]string{user2.Username}); len(found) == 1 && found[0].Id != user2.Id {
|
||||
t.Fatal("got incorrect user", found)
|
||||
}
|
||||
|
||||
if found := getUsersFromUserArgs([]string{user.Username, user2.Id}); len(found) != 2 {
|
||||
t.Fatal("got incorrect number of users", found)
|
||||
} else if !(found[0].Id == user.Id && found[1].Id == user2.Id) && !(found[1].Id == user.Id && found[0].Id == user2.Id) {
|
||||
t.Fatal("got incorrect users", found[0], found[1])
|
||||
}
|
||||
}
|
||||
67
glide.lock
generated
67
glide.lock
generated
|
|
@ -1,17 +1,17 @@
|
|||
hash: c8c28a291e4ef606837d38252852246fa634c9eebac12ceaae37103caed16883
|
||||
updated: 2017-08-17T09:43:52.281308245-07:00
|
||||
hash: a63bdc06107e9917f943ab3af7d55d64702bc745e3a5dd0affa2c012a8d8e07f
|
||||
updated: 2017-09-29T08:20:31.615625246-07:00
|
||||
imports:
|
||||
- name: github.com/alecthomas/log4go
|
||||
version: 3fbce08846379ec7f4f6bc7fce6dd01ce28fae4c
|
||||
repo: https://github.com/mattermost/log4go.git
|
||||
- name: github.com/armon/go-metrics
|
||||
version: 023a4bbe4bb9bfb23ee7e1afc8d0abad217641f3
|
||||
version: 0a12dc6f6b9da6da644031a1b9b5a85478c5ee27
|
||||
- name: github.com/beorn7/perks
|
||||
version: 4c0e84591b9aa9e6dcfdf3e020114cd81f89d5f9
|
||||
subpackages:
|
||||
- quantile
|
||||
- name: github.com/cpanato/html2text
|
||||
version: d788b7d6dc58bea298b318059332a25442583880
|
||||
version: d47a5532a7bc36ad7b2b8ec3eebe24e975154f94
|
||||
- name: github.com/davecgh/go-spew
|
||||
version: 6d212800a42e8ab5c146b8ace3490ee17e5225f9
|
||||
subpackages:
|
||||
|
|
@ -21,7 +21,7 @@ imports:
|
|||
- name: github.com/dimchansky/utfbom
|
||||
version: 6c6132ff69f0f6c088739067407b5d32c52e1d0f
|
||||
- name: github.com/disintegration/imaging
|
||||
version: a5858022df0e1734a59f973fffe3f87b51c087ed
|
||||
version: c3956f26e8f5f2370428d573648fedc717fbe51e
|
||||
- name: github.com/dyatlov/go-opengraph
|
||||
version: 41a3523719dfbe7e8f853fbd4061867543db5270
|
||||
subpackages:
|
||||
|
|
@ -33,7 +33,7 @@ imports:
|
|||
- name: github.com/go-ldap/ldap
|
||||
version: 8168ee085ee43257585e50c6441aadf54ecb2c9f
|
||||
- name: github.com/go-redis/redis
|
||||
version: 19c1c2272e00c1aaa903cf574c746cd449f9cd3c
|
||||
version: 8e6b51ec3a92ec095dcbd2439c7a3eec6b6cb586
|
||||
subpackages:
|
||||
- internal
|
||||
- internal/consistenthash
|
||||
|
|
@ -48,7 +48,7 @@ imports:
|
|||
- raster
|
||||
- truetype
|
||||
- name: github.com/golang/protobuf
|
||||
version: ab9f9a6dab164b7d1246e0e688b0ab7b94d8553e
|
||||
version: 130e6b02ab059e7b717a096f397c5b60111cae74
|
||||
subpackages:
|
||||
- proto
|
||||
- name: github.com/gorilla/context
|
||||
|
|
@ -56,7 +56,7 @@ imports:
|
|||
- name: github.com/gorilla/handlers
|
||||
version: a4043c62cc2329bacda331d33fc908ab11ef0ec3
|
||||
- name: github.com/gorilla/mux
|
||||
version: bcd8bc72b08df0f70df986b97f95590779502d31
|
||||
version: 24fca303ac6da784b9e8269f724ddeb0b2eea5e7
|
||||
- name: github.com/gorilla/websocket
|
||||
version: ea4d1f681babbce9545c9c5f3d5194a789c89f5b
|
||||
- name: github.com/hashicorp/errwrap
|
||||
|
|
@ -76,7 +76,7 @@ imports:
|
|||
subpackages:
|
||||
- simplelru
|
||||
- name: github.com/hashicorp/hcl
|
||||
version: 392dba7d905ed5d04a5794ba89f558b27e2ba1ca
|
||||
version: 68e816d1c783414e79bc65b3994d9ab6b0a722ab
|
||||
subpackages:
|
||||
- hcl/ast
|
||||
- hcl/parser
|
||||
|
|
@ -87,21 +87,21 @@ imports:
|
|||
- json/scanner
|
||||
- json/token
|
||||
- name: github.com/hashicorp/memberlist
|
||||
version: d6c1fb0b99c33d0a8e22acea9da9709b369b5d39
|
||||
version: 687988a0b5daaf7ed5051e5e374aef27f8254822
|
||||
- name: github.com/inconshreveable/mousetrap
|
||||
version: 76626ae9c91c4f2a10f34cad8ce83ea42c93bb75
|
||||
- name: github.com/jehiah/go-strftime
|
||||
version: 834e15c05a45371503440cc195bbd05c9a0968d9
|
||||
- name: github.com/lib/pq
|
||||
version: e42267488fe361b9dc034be7a6bffef5b195bceb
|
||||
version: b77235e3890a962fe8a6f8c4c7198679ca7814e7
|
||||
subpackages:
|
||||
- oid
|
||||
- name: github.com/magiconair/properties
|
||||
version: be5ece7dd465ab0765a9682137865547526d1dfb
|
||||
version: 8d7837e64d3c1ee4e54a880c5a920ab4316fc90a
|
||||
- name: github.com/mattermost/gorp
|
||||
version: 995ddf2264c4ad45fbaf342f7500e4787ebae84a
|
||||
- name: github.com/mattermost/html2text
|
||||
version: d788b7d6dc58bea298b318059332a25442583880
|
||||
version: d47a5532a7bc36ad7b2b8ec3eebe24e975154f94
|
||||
- name: github.com/mattermost/rsc
|
||||
version: bbaefb05eaa0389ea712340066837c8ce4d287f9
|
||||
subpackages:
|
||||
|
|
@ -113,11 +113,13 @@ imports:
|
|||
subpackages:
|
||||
- pbutil
|
||||
- name: github.com/miekg/dns
|
||||
version: 0598bd43cf51d0375c5bcd3a42e807cc19b3b7d9
|
||||
version: aade52d68e0bf400ae55afd3adadffce3b027043
|
||||
subpackages:
|
||||
- internal/socket
|
||||
- name: github.com/minio/go-homedir
|
||||
version: 21304a94172ae3a09dee2cd86a12fb6f842138c7
|
||||
- name: github.com/minio/minio-go
|
||||
version: 1a09415eed6025360c2c3142f92d3bcf339f873d
|
||||
version: 4e0f567303d4cc90ceb055a451959fb9fc391fb9
|
||||
subpackages:
|
||||
- pkg/credentials
|
||||
- pkg/encrypt
|
||||
|
|
@ -128,22 +130,22 @@ imports:
|
|||
- name: github.com/mitchellh/mapstructure
|
||||
version: d0303fe809921458f417bcf828397a65db30a7e4
|
||||
- name: github.com/mssola/user_agent
|
||||
version: 85b2f5798558a46fc23443c596e781712f4b7792
|
||||
version: a2f39d5a9b15ecc1fa1005b6aae73cd83da240ef
|
||||
- name: github.com/nicksnyder/go-i18n
|
||||
version: 3e70a1a463008cea6726380c908b1a6a8bdf7b24
|
||||
version: ca33e78c8a430e2df435b02f63a3944fa8e9ea11
|
||||
subpackages:
|
||||
- i18n
|
||||
- i18n/bundle
|
||||
- i18n/language
|
||||
- i18n/translation
|
||||
- name: github.com/NYTimes/gziphandler
|
||||
version: 967539e5e271a2bc9b3dcb1285078a1b1df105ae
|
||||
version: 97ae7fbaf81620fe97840685304a78a306a39c64
|
||||
- name: github.com/pborman/uuid
|
||||
version: e790cca94e6cc75c7064b1332e63811d4aae1a53
|
||||
- name: github.com/pelletier/go-toml
|
||||
version: 4692b8f9babfc93db58cc592ba2689d8736781de
|
||||
version: 16398bac157da96aa88f98a2df640c7f32af1da2
|
||||
- name: github.com/pkg/errors
|
||||
version: c605e284fe17294bda444b34710735b29d1a9d90
|
||||
version: 2b3a18b5f0fb6b4f9190549597d3f962c02bc5eb
|
||||
- name: github.com/pmezard/go-difflib
|
||||
version: d8ed2627bdf02c080bf22230dbb337003b7aba2d
|
||||
subpackages:
|
||||
|
|
@ -157,7 +159,7 @@ imports:
|
|||
subpackages:
|
||||
- go
|
||||
- name: github.com/prometheus/common
|
||||
version: 61f87aac8082fa8c3c5655c7608d7478d46ac2ad
|
||||
version: 2f17f4a9d485bf34b4bfaccc273805040e4f86c8
|
||||
subpackages:
|
||||
- expfmt
|
||||
- name: github.com/prometheus/procfs
|
||||
|
|
@ -176,15 +178,15 @@ imports:
|
|||
- name: github.com/segmentio/backo-go
|
||||
version: 204274ad699c0983a70203a566887f17a717fef4
|
||||
- name: github.com/spf13/afero
|
||||
version: 9be650865eab0c12963d8753212f4f9c66cdcf12
|
||||
version: ee1bd8ee15a1306d1f9201acc41ef39cd9f99a1b
|
||||
subpackages:
|
||||
- mem
|
||||
- name: github.com/spf13/cast
|
||||
version: acbeb36b902d72a7a4c18e8f3241075e7ab763e4
|
||||
- name: github.com/spf13/cobra
|
||||
version: cb731b898346822cc0c225c28550a8a29d93c732
|
||||
version: b78744579491c1ceeaaa3b40205e56b0591b93a3
|
||||
- name: github.com/spf13/jwalterweatherman
|
||||
version: 0efa5202c04663c757d84f90f5219c1250baf94f
|
||||
version: 12bd96e66386c1960ab0f74ced1362f66f552f7b
|
||||
- name: github.com/spf13/pflag
|
||||
version: e57e3eeb33f795204c1ca35f56c44f83227c6e66
|
||||
- name: github.com/spf13/viper
|
||||
|
|
@ -197,22 +199,23 @@ imports:
|
|||
- assert
|
||||
- mock
|
||||
- require
|
||||
- suite
|
||||
- name: github.com/tylerb/graceful
|
||||
version: 4654dfbb6ad53cb5e27f37d99b02e16c1872fbbb
|
||||
- name: github.com/xenolf/lego
|
||||
version: 92ed20909982bc411971291622e8d379e1627a0b
|
||||
version: 5a2fd5039fbba3c06b640be91a2c436bc23f74e8
|
||||
subpackages:
|
||||
- acme
|
||||
- name: github.com/xtgo/uuid
|
||||
version: a0b114877d4caeffbd7f87e3757c17fce570fea7
|
||||
- name: golang.org/x/crypto
|
||||
version: b176d7def5d71bdd214203491f89843ed217f420
|
||||
version: 76eec36fa14229c4b25bb894c2d0e591527af429
|
||||
subpackages:
|
||||
- bcrypt
|
||||
- blowfish
|
||||
- ocsp
|
||||
- name: golang.org/x/image
|
||||
version: 426cfd8eeb6e08ab1932954e09e3c2cb2bc6e36d
|
||||
version: 334384d9e19178a0488c9360d94d183c1ef0f711
|
||||
subpackages:
|
||||
- bmp
|
||||
- font
|
||||
|
|
@ -220,23 +223,23 @@ imports:
|
|||
- tiff
|
||||
- tiff/lzw
|
||||
- name: golang.org/x/net
|
||||
version: 1c05540f6879653db88113bc4a2b70aec4bd491f
|
||||
version: 0a9397675ba34b2845f758fe3cd68828369c6517
|
||||
subpackages:
|
||||
- context
|
||||
- html
|
||||
- html/atom
|
||||
- publicsuffix
|
||||
- name: golang.org/x/sys
|
||||
version: 9f7170bcd8e9f4d3691c06401119c46a769a1e03
|
||||
version: 314a259e304ff91bd6985da2a7149bbf91237993
|
||||
subpackages:
|
||||
- unix
|
||||
- name: golang.org/x/text
|
||||
version: e56139fd9c5bc7244c76116c68e500765bb6db6b
|
||||
version: 1cbadb444a806fd9430d14ad08967ed91da4fa0a
|
||||
subpackages:
|
||||
- transform
|
||||
- unicode/norm
|
||||
- name: golang.org/x/time
|
||||
version: 8be79e1e0910c292df4e79c241bb7e8f7e725959
|
||||
version: 6dc17368e09b0e8634d71cac8168d853e869a0c7
|
||||
subpackages:
|
||||
- rate
|
||||
- name: gopkg.in/alexcesaro/quotedprintable.v3
|
||||
|
|
@ -246,7 +249,7 @@ imports:
|
|||
- name: gopkg.in/gomail.v2
|
||||
version: 41f3572897373c5538c50a2402db15db079fa4fd
|
||||
- name: gopkg.in/olivere/elastic.v5
|
||||
version: edbef41beaacc2ee95e61af8faff04e67c01e268
|
||||
version: 2a08d39723b7f4df92b96e2dff891a60952714d6
|
||||
subpackages:
|
||||
- config
|
||||
- uritemplates
|
||||
|
|
|
|||
15
glide.yaml
15
glide.yaml
|
|
@ -1,11 +1,11 @@
|
|||
package: github.com/mattermost/platform
|
||||
package: github.com/mattermost/mattermost-server
|
||||
import:
|
||||
- package: github.com/NYTimes/gziphandler
|
||||
- package: github.com/alecthomas/log4go
|
||||
repo: https://github.com/mattermost/log4go.git
|
||||
- package: github.com/dgryski/dgoogauth
|
||||
- package: github.com/disintegration/imaging
|
||||
version: v1.2.1
|
||||
version: v1.2.2
|
||||
- package: github.com/dyatlov/go-opengraph
|
||||
subpackages:
|
||||
- opengraph
|
||||
|
|
@ -19,7 +19,7 @@ import:
|
|||
- package: github.com/gorilla/handlers
|
||||
version: v1.2.1
|
||||
- package: github.com/gorilla/mux
|
||||
version: v1.4.0
|
||||
version: v1.5.0
|
||||
- package: github.com/gorilla/websocket
|
||||
version: v1.2.0
|
||||
- package: github.com/lib/pq
|
||||
|
|
@ -27,11 +27,10 @@ import:
|
|||
subpackages:
|
||||
- qr
|
||||
- package: github.com/minio/minio-go
|
||||
version: v3.0.1
|
||||
version: v3.0.3
|
||||
- package: github.com/mssola/user_agent
|
||||
version: v0.4.1
|
||||
- package: github.com/nicksnyder/go-i18n
|
||||
version: v1.8.1
|
||||
version: v1.9.0
|
||||
subpackages:
|
||||
- i18n
|
||||
- package: github.com/pborman/uuid
|
||||
|
|
@ -82,11 +81,11 @@ import:
|
|||
- package: github.com/prometheus/procfs
|
||||
- package: github.com/cpanato/html2text
|
||||
- package: gopkg.in/olivere/elastic.v5
|
||||
version: v5.0.45
|
||||
version: v5.0.48
|
||||
- package: github.com/mattermost/gorp
|
||||
version: 995ddf2264c4ad45fbaf342f7500e4787ebae84a
|
||||
- package: github.com/go-redis/redis
|
||||
version: v6.5.7
|
||||
version: v6.7.1
|
||||
- package: github.com/stretchr/testify
|
||||
version: v1.1.4
|
||||
subpackages:
|
||||
|
|
|
|||
201
vendor/github.com/NYTimes/gziphandler/LICENSE
generated
vendored
Normal file
201
vendor/github.com/NYTimes/gziphandler/LICENSE
generated
vendored
Normal file
|
|
@ -0,0 +1,201 @@
|
|||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright 2016-2017 The New York Times Company
|
||||
|
||||
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.
|
||||
13
vendor/github.com/NYTimes/gziphandler/LICENSE.md
generated
vendored
13
vendor/github.com/NYTimes/gziphandler/LICENSE.md
generated
vendored
|
|
@ -1,13 +0,0 @@
|
|||
Copyright (c) 2015 The New York Times Company
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this library 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.
|
||||
4
vendor/github.com/NYTimes/gziphandler/gzip.go
generated
vendored
4
vendor/github.com/NYTimes/gziphandler/gzip.go
generated
vendored
|
|
@ -105,7 +105,7 @@ func (w *GzipResponseWriter) Write(b []byte) (int, error) {
|
|||
// If the global writes are bigger than the minSize and we're about to write
|
||||
// a response containing a content type we want to handle, enable
|
||||
// compression.
|
||||
if len(w.buf) >= w.minSize && handleContentType(w.contentTypes, w) {
|
||||
if len(w.buf) >= w.minSize && handleContentType(w.contentTypes, w) && w.Header().Get(contentEncoding) == "" {
|
||||
err := w.startGzip()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
|
|
@ -134,7 +134,7 @@ func (w *GzipResponseWriter) startGzip() error {
|
|||
// Initialize the GZIP response.
|
||||
w.init()
|
||||
|
||||
// Flush the buffer into the gzip reponse.
|
||||
// Flush the buffer into the gzip response.
|
||||
n, err := w.gw.Write(w.buf)
|
||||
|
||||
// This should never happen (per io.Writer docs), but if the write didn't
|
||||
|
|
|
|||
19
vendor/github.com/NYTimes/gziphandler/gzip_test.go
generated
vendored
19
vendor/github.com/NYTimes/gziphandler/gzip_test.go
generated
vendored
|
|
@ -81,6 +81,17 @@ func TestGzipHandler(t *testing.T) {
|
|||
assert.Equal(t, http.DetectContentType([]byte(testBody)), res3.Header().Get("Content-Type"))
|
||||
}
|
||||
|
||||
func TestGzipHandlerAlreadyCompressed(t *testing.T) {
|
||||
handler := newTestHandler(testBody)
|
||||
|
||||
req, _ := http.NewRequest("GET", "/gzipped", nil)
|
||||
req.Header.Set("Accept-Encoding", "gzip")
|
||||
res := httptest.NewRecorder()
|
||||
handler.ServeHTTP(res, req)
|
||||
|
||||
assert.Equal(t, testBody, res.Body.String())
|
||||
}
|
||||
|
||||
func TestNewGzipLevelHandler(t *testing.T) {
|
||||
handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.WriteHeader(http.StatusOK)
|
||||
|
|
@ -435,6 +446,12 @@ func runBenchmark(b *testing.B, req *http.Request, handler http.Handler) {
|
|||
|
||||
func newTestHandler(body string) http.Handler {
|
||||
return GzipHandler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
io.WriteString(w, body)
|
||||
switch r.URL.Path {
|
||||
case "/gzipped":
|
||||
w.Header().Set("Content-Encoding", "gzip")
|
||||
io.WriteString(w, body)
|
||||
default:
|
||||
io.WriteString(w, body)
|
||||
}
|
||||
}))
|
||||
}
|
||||
|
|
|
|||
6
vendor/github.com/armon/go-metrics/prometheus/prometheus.go
generated
vendored
6
vendor/github.com/armon/go-metrics/prometheus/prometheus.go
generated
vendored
|
|
@ -66,7 +66,7 @@ func (p *PrometheusSink) SetGaugeWithLabels(parts []string, val float32, labels
|
|||
ConstLabels: prometheusLabels(labels),
|
||||
})
|
||||
prometheus.MustRegister(g)
|
||||
p.gauges[key] = g
|
||||
p.gauges[hash] = g
|
||||
}
|
||||
g.Set(float64(val))
|
||||
}
|
||||
|
|
@ -88,7 +88,7 @@ func (p *PrometheusSink) AddSampleWithLabels(parts []string, val float32, labels
|
|||
ConstLabels: prometheusLabels(labels),
|
||||
})
|
||||
prometheus.MustRegister(g)
|
||||
p.summaries[key] = g
|
||||
p.summaries[hash] = g
|
||||
}
|
||||
g.Observe(float64(val))
|
||||
}
|
||||
|
|
@ -115,7 +115,7 @@ func (p *PrometheusSink) IncrCounterWithLabels(parts []string, val float32, labe
|
|||
ConstLabels: prometheusLabels(labels),
|
||||
})
|
||||
prometheus.MustRegister(g)
|
||||
p.counters[key] = g
|
||||
p.counters[hash] = g
|
||||
}
|
||||
g.Add(float64(val))
|
||||
}
|
||||
|
|
|
|||
1
vendor/github.com/cpanato/html2text/LICENSE
generated
vendored
1
vendor/github.com/cpanato/html2text/LICENSE
generated
vendored
|
|
@ -1,6 +1,7 @@
|
|||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015 Jay Taylor
|
||||
Modified work: Copyright (c) 2017-present Mattermost, Inc. All Rights Reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
|
|
|||
5
vendor/github.com/disintegration/imaging/.travis.yml
generated
vendored
5
vendor/github.com/disintegration/imaging/.travis.yml
generated
vendored
|
|
@ -4,12 +4,9 @@ sudo: false
|
|||
|
||||
go:
|
||||
- 1.2
|
||||
- 1.3
|
||||
- 1.4
|
||||
- 1.5
|
||||
- 1.6
|
||||
- 1.7
|
||||
- 1.8
|
||||
- 1.9
|
||||
|
||||
before_install:
|
||||
- go get golang.org/x/tools/cmd/cover
|
||||
|
|
|
|||
429
vendor/github.com/disintegration/imaging/helpers.go
generated
vendored
429
vendor/github.com/disintegration/imaging/helpers.go
generated
vendored
|
|
@ -168,213 +168,266 @@ func New(width, height int, fillColor color.Color) *image.NRGBA {
|
|||
|
||||
// Clone returns a copy of the given image.
|
||||
func Clone(img image.Image) *image.NRGBA {
|
||||
srcBounds := img.Bounds()
|
||||
srcMinX := srcBounds.Min.X
|
||||
srcMinY := srcBounds.Min.Y
|
||||
|
||||
dstBounds := srcBounds.Sub(srcBounds.Min)
|
||||
dstW := dstBounds.Dx()
|
||||
dstH := dstBounds.Dy()
|
||||
dstBounds := img.Bounds().Sub(img.Bounds().Min)
|
||||
dst := image.NewNRGBA(dstBounds)
|
||||
|
||||
switch src := img.(type) {
|
||||
|
||||
case *image.NRGBA:
|
||||
rowSize := srcBounds.Dx() * 4
|
||||
parallel(dstH, func(partStart, partEnd int) {
|
||||
for dstY := partStart; dstY < partEnd; dstY++ {
|
||||
di := dst.PixOffset(0, dstY)
|
||||
si := src.PixOffset(srcMinX, srcMinY+dstY)
|
||||
copy(dst.Pix[di:di+rowSize], src.Pix[si:si+rowSize])
|
||||
}
|
||||
})
|
||||
|
||||
copyNRGBA(dst, src)
|
||||
case *image.NRGBA64:
|
||||
parallel(dstH, func(partStart, partEnd int) {
|
||||
for dstY := partStart; dstY < partEnd; dstY++ {
|
||||
di := dst.PixOffset(0, dstY)
|
||||
si := src.PixOffset(srcMinX, srcMinY+dstY)
|
||||
for dstX := 0; dstX < dstW; dstX++ {
|
||||
dst.Pix[di+0] = src.Pix[si+0]
|
||||
dst.Pix[di+1] = src.Pix[si+2]
|
||||
dst.Pix[di+2] = src.Pix[si+4]
|
||||
dst.Pix[di+3] = src.Pix[si+6]
|
||||
di += 4
|
||||
si += 8
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
copyNRGBA64(dst, src)
|
||||
case *image.RGBA:
|
||||
parallel(dstH, func(partStart, partEnd int) {
|
||||
for dstY := partStart; dstY < partEnd; dstY++ {
|
||||
di := dst.PixOffset(0, dstY)
|
||||
si := src.PixOffset(srcMinX, srcMinY+dstY)
|
||||
for dstX := 0; dstX < dstW; dstX++ {
|
||||
a := src.Pix[si+3]
|
||||
dst.Pix[di+3] = a
|
||||
|
||||
switch a {
|
||||
case 0:
|
||||
dst.Pix[di+0] = 0
|
||||
dst.Pix[di+1] = 0
|
||||
dst.Pix[di+2] = 0
|
||||
case 0xff:
|
||||
dst.Pix[di+0] = src.Pix[si+0]
|
||||
dst.Pix[di+1] = src.Pix[si+1]
|
||||
dst.Pix[di+2] = src.Pix[si+2]
|
||||
default:
|
||||
var tmp uint16
|
||||
tmp = uint16(src.Pix[si+0]) * 0xff / uint16(a)
|
||||
dst.Pix[di+0] = uint8(tmp)
|
||||
tmp = uint16(src.Pix[si+1]) * 0xff / uint16(a)
|
||||
dst.Pix[di+1] = uint8(tmp)
|
||||
tmp = uint16(src.Pix[si+2]) * 0xff / uint16(a)
|
||||
dst.Pix[di+2] = uint8(tmp)
|
||||
}
|
||||
|
||||
di += 4
|
||||
si += 4
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
copyRGBA(dst, src)
|
||||
case *image.RGBA64:
|
||||
parallel(dstH, func(partStart, partEnd int) {
|
||||
for dstY := partStart; dstY < partEnd; dstY++ {
|
||||
di := dst.PixOffset(0, dstY)
|
||||
si := src.PixOffset(srcMinX, srcMinY+dstY)
|
||||
for dstX := 0; dstX < dstW; dstX++ {
|
||||
a := src.Pix[si+6]
|
||||
dst.Pix[di+3] = a
|
||||
|
||||
switch a {
|
||||
case 0:
|
||||
dst.Pix[di+0] = 0
|
||||
dst.Pix[di+1] = 0
|
||||
dst.Pix[di+2] = 0
|
||||
case 0xff:
|
||||
dst.Pix[di+0] = src.Pix[si+0]
|
||||
dst.Pix[di+1] = src.Pix[si+2]
|
||||
dst.Pix[di+2] = src.Pix[si+4]
|
||||
default:
|
||||
var tmp uint16
|
||||
tmp = uint16(src.Pix[si+0]) * 0xff / uint16(a)
|
||||
dst.Pix[di+0] = uint8(tmp)
|
||||
tmp = uint16(src.Pix[si+2]) * 0xff / uint16(a)
|
||||
dst.Pix[di+1] = uint8(tmp)
|
||||
tmp = uint16(src.Pix[si+4]) * 0xff / uint16(a)
|
||||
dst.Pix[di+2] = uint8(tmp)
|
||||
}
|
||||
|
||||
di += 4
|
||||
si += 8
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
copyRGBA64(dst, src)
|
||||
case *image.Gray:
|
||||
parallel(dstH, func(partStart, partEnd int) {
|
||||
for dstY := partStart; dstY < partEnd; dstY++ {
|
||||
di := dst.PixOffset(0, dstY)
|
||||
si := src.PixOffset(srcMinX, srcMinY+dstY)
|
||||
for dstX := 0; dstX < dstW; dstX++ {
|
||||
c := src.Pix[si]
|
||||
dst.Pix[di+0] = c
|
||||
dst.Pix[di+1] = c
|
||||
dst.Pix[di+2] = c
|
||||
dst.Pix[di+3] = 0xff
|
||||
di += 4
|
||||
si += 1
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
copyGray(dst, src)
|
||||
case *image.Gray16:
|
||||
parallel(dstH, func(partStart, partEnd int) {
|
||||
for dstY := partStart; dstY < partEnd; dstY++ {
|
||||
di := dst.PixOffset(0, dstY)
|
||||
si := src.PixOffset(srcMinX, srcMinY+dstY)
|
||||
for dstX := 0; dstX < dstW; dstX++ {
|
||||
c := src.Pix[si]
|
||||
dst.Pix[di+0] = c
|
||||
dst.Pix[di+1] = c
|
||||
dst.Pix[di+2] = c
|
||||
dst.Pix[di+3] = 0xff
|
||||
di += 4
|
||||
si += 2
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
copyGray16(dst, src)
|
||||
case *image.YCbCr:
|
||||
parallel(dstH, func(partStart, partEnd int) {
|
||||
for dstY := partStart; dstY < partEnd; dstY++ {
|
||||
di := dst.PixOffset(0, dstY)
|
||||
for dstX := 0; dstX < dstW; dstX++ {
|
||||
srcX := srcMinX + dstX
|
||||
srcY := srcMinY + dstY
|
||||
siy := src.YOffset(srcX, srcY)
|
||||
sic := src.COffset(srcX, srcY)
|
||||
r, g, b := color.YCbCrToRGB(src.Y[siy], src.Cb[sic], src.Cr[sic])
|
||||
dst.Pix[di+0] = r
|
||||
dst.Pix[di+1] = g
|
||||
dst.Pix[di+2] = b
|
||||
dst.Pix[di+3] = 0xff
|
||||
di += 4
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
copyYCbCr(dst, src)
|
||||
case *image.Paletted:
|
||||
plen := len(src.Palette)
|
||||
pnew := make([]color.NRGBA, plen)
|
||||
for i := 0; i < plen; i++ {
|
||||
pnew[i] = color.NRGBAModel.Convert(src.Palette[i]).(color.NRGBA)
|
||||
}
|
||||
parallel(dstH, func(partStart, partEnd int) {
|
||||
for dstY := partStart; dstY < partEnd; dstY++ {
|
||||
di := dst.PixOffset(0, dstY)
|
||||
si := src.PixOffset(srcMinX, srcMinY+dstY)
|
||||
for dstX := 0; dstX < dstW; dstX++ {
|
||||
c := pnew[src.Pix[si]]
|
||||
dst.Pix[di+0] = c.R
|
||||
dst.Pix[di+1] = c.G
|
||||
dst.Pix[di+2] = c.B
|
||||
dst.Pix[di+3] = c.A
|
||||
di += 4
|
||||
si += 1
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
copyPaletted(dst, src)
|
||||
default:
|
||||
parallel(dstH, func(partStart, partEnd int) {
|
||||
for dstY := partStart; dstY < partEnd; dstY++ {
|
||||
di := dst.PixOffset(0, dstY)
|
||||
for dstX := 0; dstX < dstW; dstX++ {
|
||||
c := color.NRGBAModel.Convert(img.At(srcMinX+dstX, srcMinY+dstY)).(color.NRGBA)
|
||||
dst.Pix[di+0] = c.R
|
||||
dst.Pix[di+1] = c.G
|
||||
dst.Pix[di+2] = c.B
|
||||
dst.Pix[di+3] = c.A
|
||||
di += 4
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
copyImage(dst, src)
|
||||
}
|
||||
|
||||
return dst
|
||||
}
|
||||
|
||||
func copyNRGBA(dst *image.NRGBA, src *image.NRGBA) {
|
||||
srcMinX := src.Rect.Min.X
|
||||
srcMinY := src.Rect.Min.Y
|
||||
dstW := dst.Rect.Dx()
|
||||
dstH := dst.Rect.Dy()
|
||||
rowSize := dstW * 4
|
||||
parallel(dstH, func(partStart, partEnd int) {
|
||||
for dstY := partStart; dstY < partEnd; dstY++ {
|
||||
di := dst.PixOffset(0, dstY)
|
||||
si := src.PixOffset(srcMinX, srcMinY+dstY)
|
||||
copy(dst.Pix[di:di+rowSize], src.Pix[si:si+rowSize])
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func copyNRGBA64(dst *image.NRGBA, src *image.NRGBA64) {
|
||||
srcMinX := src.Rect.Min.X
|
||||
srcMinY := src.Rect.Min.Y
|
||||
dstW := dst.Rect.Dx()
|
||||
dstH := dst.Rect.Dy()
|
||||
parallel(dstH, func(partStart, partEnd int) {
|
||||
for dstY := partStart; dstY < partEnd; dstY++ {
|
||||
di := dst.PixOffset(0, dstY)
|
||||
si := src.PixOffset(srcMinX, srcMinY+dstY)
|
||||
for dstX := 0; dstX < dstW; dstX++ {
|
||||
dst.Pix[di+0] = src.Pix[si+0]
|
||||
dst.Pix[di+1] = src.Pix[si+2]
|
||||
dst.Pix[di+2] = src.Pix[si+4]
|
||||
dst.Pix[di+3] = src.Pix[si+6]
|
||||
di += 4
|
||||
si += 8
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func copyRGBA(dst *image.NRGBA, src *image.RGBA) {
|
||||
srcMinX := src.Rect.Min.X
|
||||
srcMinY := src.Rect.Min.Y
|
||||
dstW := dst.Rect.Dx()
|
||||
dstH := dst.Rect.Dy()
|
||||
parallel(dstH, func(partStart, partEnd int) {
|
||||
for dstY := partStart; dstY < partEnd; dstY++ {
|
||||
di := dst.PixOffset(0, dstY)
|
||||
si := src.PixOffset(srcMinX, srcMinY+dstY)
|
||||
for dstX := 0; dstX < dstW; dstX++ {
|
||||
a := src.Pix[si+3]
|
||||
dst.Pix[di+3] = a
|
||||
|
||||
switch a {
|
||||
case 0:
|
||||
dst.Pix[di+0] = 0
|
||||
dst.Pix[di+1] = 0
|
||||
dst.Pix[di+2] = 0
|
||||
case 0xff:
|
||||
dst.Pix[di+0] = src.Pix[si+0]
|
||||
dst.Pix[di+1] = src.Pix[si+1]
|
||||
dst.Pix[di+2] = src.Pix[si+2]
|
||||
default:
|
||||
var tmp uint16
|
||||
tmp = uint16(src.Pix[si+0]) * 0xff / uint16(a)
|
||||
dst.Pix[di+0] = uint8(tmp)
|
||||
tmp = uint16(src.Pix[si+1]) * 0xff / uint16(a)
|
||||
dst.Pix[di+1] = uint8(tmp)
|
||||
tmp = uint16(src.Pix[si+2]) * 0xff / uint16(a)
|
||||
dst.Pix[di+2] = uint8(tmp)
|
||||
}
|
||||
|
||||
di += 4
|
||||
si += 4
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func copyRGBA64(dst *image.NRGBA, src *image.RGBA64) {
|
||||
srcMinX := src.Rect.Min.X
|
||||
srcMinY := src.Rect.Min.Y
|
||||
dstW := dst.Rect.Dx()
|
||||
dstH := dst.Rect.Dy()
|
||||
parallel(dstH, func(partStart, partEnd int) {
|
||||
for dstY := partStart; dstY < partEnd; dstY++ {
|
||||
di := dst.PixOffset(0, dstY)
|
||||
si := src.PixOffset(srcMinX, srcMinY+dstY)
|
||||
for dstX := 0; dstX < dstW; dstX++ {
|
||||
a := src.Pix[si+6]
|
||||
dst.Pix[di+3] = a
|
||||
|
||||
switch a {
|
||||
case 0:
|
||||
dst.Pix[di+0] = 0
|
||||
dst.Pix[di+1] = 0
|
||||
dst.Pix[di+2] = 0
|
||||
case 0xff:
|
||||
dst.Pix[di+0] = src.Pix[si+0]
|
||||
dst.Pix[di+1] = src.Pix[si+2]
|
||||
dst.Pix[di+2] = src.Pix[si+4]
|
||||
default:
|
||||
var tmp uint16
|
||||
tmp = uint16(src.Pix[si+0]) * 0xff / uint16(a)
|
||||
dst.Pix[di+0] = uint8(tmp)
|
||||
tmp = uint16(src.Pix[si+2]) * 0xff / uint16(a)
|
||||
dst.Pix[di+1] = uint8(tmp)
|
||||
tmp = uint16(src.Pix[si+4]) * 0xff / uint16(a)
|
||||
dst.Pix[di+2] = uint8(tmp)
|
||||
}
|
||||
|
||||
di += 4
|
||||
si += 8
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func copyGray(dst *image.NRGBA, src *image.Gray) {
|
||||
srcMinX := src.Rect.Min.X
|
||||
srcMinY := src.Rect.Min.Y
|
||||
dstW := dst.Rect.Dx()
|
||||
dstH := dst.Rect.Dy()
|
||||
parallel(dstH, func(partStart, partEnd int) {
|
||||
for dstY := partStart; dstY < partEnd; dstY++ {
|
||||
di := dst.PixOffset(0, dstY)
|
||||
si := src.PixOffset(srcMinX, srcMinY+dstY)
|
||||
for dstX := 0; dstX < dstW; dstX++ {
|
||||
c := src.Pix[si]
|
||||
dst.Pix[di+0] = c
|
||||
dst.Pix[di+1] = c
|
||||
dst.Pix[di+2] = c
|
||||
dst.Pix[di+3] = 0xff
|
||||
di += 4
|
||||
si++
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func copyGray16(dst *image.NRGBA, src *image.Gray16) {
|
||||
srcMinX := src.Rect.Min.X
|
||||
srcMinY := src.Rect.Min.Y
|
||||
dstW := dst.Rect.Dx()
|
||||
dstH := dst.Rect.Dy()
|
||||
parallel(dstH, func(partStart, partEnd int) {
|
||||
for dstY := partStart; dstY < partEnd; dstY++ {
|
||||
di := dst.PixOffset(0, dstY)
|
||||
si := src.PixOffset(srcMinX, srcMinY+dstY)
|
||||
for dstX := 0; dstX < dstW; dstX++ {
|
||||
c := src.Pix[si]
|
||||
dst.Pix[di+0] = c
|
||||
dst.Pix[di+1] = c
|
||||
dst.Pix[di+2] = c
|
||||
dst.Pix[di+3] = 0xff
|
||||
di += 4
|
||||
si += 2
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func copyYCbCr(dst *image.NRGBA, src *image.YCbCr) {
|
||||
srcMinX := src.Rect.Min.X
|
||||
srcMinY := src.Rect.Min.Y
|
||||
dstW := dst.Rect.Dx()
|
||||
dstH := dst.Rect.Dy()
|
||||
parallel(dstH, func(partStart, partEnd int) {
|
||||
for dstY := partStart; dstY < partEnd; dstY++ {
|
||||
di := dst.PixOffset(0, dstY)
|
||||
for dstX := 0; dstX < dstW; dstX++ {
|
||||
srcX := srcMinX + dstX
|
||||
srcY := srcMinY + dstY
|
||||
siy := src.YOffset(srcX, srcY)
|
||||
sic := src.COffset(srcX, srcY)
|
||||
r, g, b := color.YCbCrToRGB(src.Y[siy], src.Cb[sic], src.Cr[sic])
|
||||
dst.Pix[di+0] = r
|
||||
dst.Pix[di+1] = g
|
||||
dst.Pix[di+2] = b
|
||||
dst.Pix[di+3] = 0xff
|
||||
di += 4
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func copyPaletted(dst *image.NRGBA, src *image.Paletted) {
|
||||
srcMinX := src.Rect.Min.X
|
||||
srcMinY := src.Rect.Min.Y
|
||||
dstW := dst.Rect.Dx()
|
||||
dstH := dst.Rect.Dy()
|
||||
plen := len(src.Palette)
|
||||
pnew := make([]color.NRGBA, plen)
|
||||
for i := 0; i < plen; i++ {
|
||||
pnew[i] = color.NRGBAModel.Convert(src.Palette[i]).(color.NRGBA)
|
||||
}
|
||||
parallel(dstH, func(partStart, partEnd int) {
|
||||
for dstY := partStart; dstY < partEnd; dstY++ {
|
||||
di := dst.PixOffset(0, dstY)
|
||||
si := src.PixOffset(srcMinX, srcMinY+dstY)
|
||||
for dstX := 0; dstX < dstW; dstX++ {
|
||||
c := pnew[src.Pix[si]]
|
||||
dst.Pix[di+0] = c.R
|
||||
dst.Pix[di+1] = c.G
|
||||
dst.Pix[di+2] = c.B
|
||||
dst.Pix[di+3] = c.A
|
||||
di += 4
|
||||
si++
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func copyImage(dst *image.NRGBA, src image.Image) {
|
||||
srcMinX := src.Bounds().Min.X
|
||||
srcMinY := src.Bounds().Min.Y
|
||||
dstW := dst.Bounds().Dx()
|
||||
dstH := dst.Bounds().Dy()
|
||||
parallel(dstH, func(partStart, partEnd int) {
|
||||
for dstY := partStart; dstY < partEnd; dstY++ {
|
||||
di := dst.PixOffset(0, dstY)
|
||||
for dstX := 0; dstX < dstW; dstX++ {
|
||||
c := color.NRGBAModel.Convert(src.At(srcMinX+dstX, srcMinY+dstY)).(color.NRGBA)
|
||||
dst.Pix[di+0] = c.R
|
||||
dst.Pix[di+1] = c.G
|
||||
dst.Pix[di+2] = c.B
|
||||
dst.Pix[di+3] = c.A
|
||||
di += 4
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// toNRGBA converts any image type to *image.NRGBA with min-point at (0, 0).
|
||||
func toNRGBA(img image.Image) *image.NRGBA {
|
||||
srcBounds := img.Bounds()
|
||||
if srcBounds.Min.X == 0 && srcBounds.Min.Y == 0 {
|
||||
if src0, ok := img.(*image.NRGBA); ok {
|
||||
return src0
|
||||
}
|
||||
if img, ok := img.(*image.NRGBA); ok && img.Bounds().Min.Eq(image.ZP) {
|
||||
return img
|
||||
}
|
||||
return Clone(img)
|
||||
}
|
||||
|
|
|
|||
1
vendor/github.com/go-redis/redis/.travis.yml
generated
vendored
1
vendor/github.com/go-redis/redis/.travis.yml
generated
vendored
|
|
@ -8,6 +8,7 @@ go:
|
|||
- 1.4.x
|
||||
- 1.7.x
|
||||
- 1.8.x
|
||||
- 1.9.x
|
||||
- tip
|
||||
|
||||
matrix:
|
||||
|
|
|
|||
3
vendor/github.com/go-redis/redis/README.md
generated
vendored
3
vendor/github.com/go-redis/redis/README.md
generated
vendored
|
|
@ -6,6 +6,7 @@
|
|||
Supports:
|
||||
|
||||
- Redis 3 commands except QUIT, MONITOR, SLOWLOG and SYNC.
|
||||
- Automatic connection pooling with [circuit breaker](https://en.wikipedia.org/wiki/Circuit_breaker_design_pattern) support.
|
||||
- [Pub/Sub](https://godoc.org/github.com/go-redis/redis#PubSub).
|
||||
- [Transactions](https://godoc.org/github.com/go-redis/redis#Multi).
|
||||
- [Pipeline](https://godoc.org/github.com/go-redis/redis#example-Client-Pipeline) and [TxPipeline](https://godoc.org/github.com/go-redis/redis#example-Client-TxPipeline).
|
||||
|
|
@ -16,7 +17,7 @@ Supports:
|
|||
- [Ring](https://godoc.org/github.com/go-redis/redis#NewRing).
|
||||
- [Instrumentation](https://godoc.org/github.com/go-redis/redis#ex-package--Instrumentation).
|
||||
- [Cache friendly](https://github.com/go-redis/cache).
|
||||
- [Rate limiting](https://github.com/go-redis/rate).
|
||||
- [Rate limiting](https://github.com/go-redis/redis_rate).
|
||||
- [Distributed Locks](https://github.com/bsm/redis-lock).
|
||||
|
||||
API docs: https://godoc.org/github.com/go-redis/redis.
|
||||
|
|
|
|||
368
vendor/github.com/go-redis/redis/cluster.go
generated
vendored
368
vendor/github.com/go-redis/redis/cluster.go
generated
vendored
|
|
@ -14,8 +14,8 @@ import (
|
|||
"github.com/go-redis/redis/internal/proto"
|
||||
)
|
||||
|
||||
var errClusterNoNodes = internal.RedisError("redis: cluster has no nodes")
|
||||
var errNilClusterState = internal.RedisError("redis: cannot load cluster slots")
|
||||
var errClusterNoNodes = fmt.Errorf("redis: cluster has no nodes")
|
||||
var errNilClusterState = fmt.Errorf("redis: cannot load cluster slots")
|
||||
|
||||
// ClusterOptions are used to configure a cluster client and should be
|
||||
// passed to NewClusterClient.
|
||||
|
|
@ -64,6 +64,19 @@ func (opt *ClusterOptions) init() {
|
|||
opt.ReadOnly = true
|
||||
}
|
||||
|
||||
switch opt.ReadTimeout {
|
||||
case -1:
|
||||
opt.ReadTimeout = 0
|
||||
case 0:
|
||||
opt.ReadTimeout = 3 * time.Second
|
||||
}
|
||||
switch opt.WriteTimeout {
|
||||
case -1:
|
||||
opt.WriteTimeout = 0
|
||||
case 0:
|
||||
opt.WriteTimeout = opt.ReadTimeout
|
||||
}
|
||||
|
||||
switch opt.MinRetryBackoff {
|
||||
case -1:
|
||||
opt.MinRetryBackoff = 0
|
||||
|
|
@ -192,6 +205,21 @@ func (c *clusterNodes) Close() error {
|
|||
return firstErr
|
||||
}
|
||||
|
||||
func (c *clusterNodes) Addrs() ([]string, error) {
|
||||
c.mu.RLock()
|
||||
closed := c.closed
|
||||
addrs := c.addrs
|
||||
c.mu.RUnlock()
|
||||
|
||||
if closed {
|
||||
return nil, pool.ErrClosed
|
||||
}
|
||||
if len(addrs) == 0 {
|
||||
return nil, errClusterNoNodes
|
||||
}
|
||||
return addrs, nil
|
||||
}
|
||||
|
||||
func (c *clusterNodes) NextGeneration() uint32 {
|
||||
c.generation++
|
||||
return c.generation
|
||||
|
|
@ -272,16 +300,9 @@ func (c *clusterNodes) GetOrCreate(addr string) (*clusterNode, error) {
|
|||
}
|
||||
|
||||
func (c *clusterNodes) Random() (*clusterNode, error) {
|
||||
c.mu.RLock()
|
||||
closed := c.closed
|
||||
addrs := c.addrs
|
||||
c.mu.RUnlock()
|
||||
|
||||
if closed {
|
||||
return nil, pool.ErrClosed
|
||||
}
|
||||
if len(addrs) == 0 {
|
||||
return nil, errClusterNoNodes
|
||||
addrs, err := c.Addrs()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var nodeErr error
|
||||
|
|
@ -468,13 +489,23 @@ func (c *ClusterClient) Options() *ClusterOptions {
|
|||
return c.opt
|
||||
}
|
||||
|
||||
func (c *ClusterClient) state() *clusterState {
|
||||
func (c *ClusterClient) retryBackoff(attempt int) time.Duration {
|
||||
return internal.RetryBackoff(attempt, c.opt.MinRetryBackoff, c.opt.MaxRetryBackoff)
|
||||
}
|
||||
|
||||
func (c *ClusterClient) state() (*clusterState, error) {
|
||||
v := c._state.Load()
|
||||
if v != nil {
|
||||
return v.(*clusterState)
|
||||
return v.(*clusterState), nil
|
||||
}
|
||||
|
||||
_, err := c.nodes.Addrs()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
c.lazyReloadState()
|
||||
return nil
|
||||
return nil, errNilClusterState
|
||||
}
|
||||
|
||||
func (c *ClusterClient) cmdInfo(name string) *CommandInfo {
|
||||
|
|
@ -495,17 +526,22 @@ func (c *ClusterClient) cmdInfo(name string) *CommandInfo {
|
|||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
return c.cmdsInfo[name]
|
||||
info := c.cmdsInfo[name]
|
||||
if info == nil {
|
||||
internal.Logf("info for cmd=%s not found", name)
|
||||
}
|
||||
return info
|
||||
}
|
||||
|
||||
func (c *ClusterClient) cmdSlot(cmd Cmder) int {
|
||||
cmdInfo := c.cmdInfo(cmd.Name())
|
||||
firstKey := cmd.stringArg(cmdFirstKeyPos(cmd, cmdInfo))
|
||||
return hashtag.Slot(firstKey)
|
||||
}
|
||||
|
||||
func (c *ClusterClient) cmdSlotAndNode(state *clusterState, cmd Cmder) (int, *clusterNode, error) {
|
||||
if state == nil {
|
||||
node, err := c.nodes.Random()
|
||||
return 0, node, err
|
||||
}
|
||||
|
||||
cmdInfo := c.cmdInfo(cmd.Name())
|
||||
firstKey := cmd.arg(cmdFirstKeyPos(cmd, cmdInfo))
|
||||
firstKey := cmd.stringArg(cmdFirstKeyPos(cmd, cmdInfo))
|
||||
slot := hashtag.Slot(firstKey)
|
||||
|
||||
if cmdInfo != nil && cmdInfo.ReadOnly && c.opt.ReadOnly {
|
||||
|
|
@ -523,19 +559,51 @@ func (c *ClusterClient) cmdSlotAndNode(state *clusterState, cmd Cmder) (int, *cl
|
|||
}
|
||||
|
||||
func (c *ClusterClient) Watch(fn func(*Tx) error, keys ...string) error {
|
||||
state := c.state()
|
||||
|
||||
var node *clusterNode
|
||||
var err error
|
||||
if state != nil && len(keys) > 0 {
|
||||
node, err = state.slotMasterNode(hashtag.Slot(keys[0]))
|
||||
} else {
|
||||
node, err = c.nodes.Random()
|
||||
if len(keys) == 0 {
|
||||
return fmt.Errorf("redis: keys don't hash to the same slot")
|
||||
}
|
||||
|
||||
state, err := c.state()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return node.Client.Watch(fn, keys...)
|
||||
|
||||
slot := hashtag.Slot(keys[0])
|
||||
for _, key := range keys[1:] {
|
||||
if hashtag.Slot(key) != slot {
|
||||
return fmt.Errorf("redis: Watch requires all keys to be in the same slot")
|
||||
}
|
||||
}
|
||||
|
||||
node, err := state.slotMasterNode(slot)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for attempt := 0; attempt <= c.opt.MaxRedirects; attempt++ {
|
||||
if attempt > 0 {
|
||||
time.Sleep(c.retryBackoff(attempt))
|
||||
}
|
||||
|
||||
err = node.Client.Watch(fn, keys...)
|
||||
if err == nil {
|
||||
break
|
||||
}
|
||||
|
||||
moved, ask, addr := internal.IsMovedError(err)
|
||||
if moved || ask {
|
||||
c.lazyReloadState()
|
||||
node, err = c.nodes.GetOrCreate(addr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// Close closes the cluster client, releasing any open resources.
|
||||
|
|
@ -547,7 +615,13 @@ func (c *ClusterClient) Close() error {
|
|||
}
|
||||
|
||||
func (c *ClusterClient) Process(cmd Cmder) error {
|
||||
slot, node, err := c.cmdSlotAndNode(c.state(), cmd)
|
||||
state, err := c.state()
|
||||
if err != nil {
|
||||
cmd.setErr(err)
|
||||
return err
|
||||
}
|
||||
|
||||
_, node, err := c.cmdSlotAndNode(state, cmd)
|
||||
if err != nil {
|
||||
cmd.setErr(err)
|
||||
return err
|
||||
|
|
@ -556,7 +630,7 @@ func (c *ClusterClient) Process(cmd Cmder) error {
|
|||
var ask bool
|
||||
for attempt := 0; attempt <= c.opt.MaxRedirects; attempt++ {
|
||||
if attempt > 0 {
|
||||
time.Sleep(node.Client.retryBackoff(attempt))
|
||||
time.Sleep(c.retryBackoff(attempt))
|
||||
}
|
||||
|
||||
if ask {
|
||||
|
|
@ -572,7 +646,7 @@ func (c *ClusterClient) Process(cmd Cmder) error {
|
|||
|
||||
// If there is no error - we are done.
|
||||
if err == nil {
|
||||
return nil
|
||||
break
|
||||
}
|
||||
|
||||
// If slave is loading - read from master.
|
||||
|
|
@ -582,12 +656,11 @@ func (c *ClusterClient) Process(cmd Cmder) error {
|
|||
continue
|
||||
}
|
||||
|
||||
// On network errors try random node.
|
||||
if internal.IsRetryableError(err) || internal.IsClusterDownError(err) {
|
||||
node, err = c.nodes.Random()
|
||||
if err != nil {
|
||||
cmd.setErr(err)
|
||||
return err
|
||||
if internal.IsRetryableError(err, true) {
|
||||
var nodeErr error
|
||||
node, nodeErr = c.nodes.Random()
|
||||
if nodeErr != nil {
|
||||
break
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
|
@ -596,20 +669,13 @@ func (c *ClusterClient) Process(cmd Cmder) error {
|
|||
var addr string
|
||||
moved, ask, addr = internal.IsMovedError(err)
|
||||
if moved || ask {
|
||||
state := c.state()
|
||||
if state != nil && slot >= 0 {
|
||||
master, _ := state.slotMasterNode(slot)
|
||||
if moved && (master == nil || master.Client.getAddr() != addr) {
|
||||
c.lazyReloadState()
|
||||
}
|
||||
}
|
||||
c.lazyReloadState()
|
||||
|
||||
node, err = c.nodes.GetOrCreate(addr)
|
||||
if err != nil {
|
||||
cmd.setErr(err)
|
||||
return err
|
||||
var nodeErr error
|
||||
node, nodeErr = c.nodes.GetOrCreate(addr)
|
||||
if nodeErr != nil {
|
||||
break
|
||||
}
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
|
|
@ -622,9 +688,9 @@ func (c *ClusterClient) Process(cmd Cmder) error {
|
|||
// ForEachMaster concurrently calls the fn on each master node in the cluster.
|
||||
// It returns the first error if any.
|
||||
func (c *ClusterClient) ForEachMaster(fn func(client *Client) error) error {
|
||||
state := c.state()
|
||||
if state == nil {
|
||||
return errNilClusterState
|
||||
state, err := c.state()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var wg sync.WaitGroup
|
||||
|
|
@ -655,9 +721,9 @@ func (c *ClusterClient) ForEachMaster(fn func(client *Client) error) error {
|
|||
// ForEachSlave concurrently calls the fn on each slave node in the cluster.
|
||||
// It returns the first error if any.
|
||||
func (c *ClusterClient) ForEachSlave(fn func(client *Client) error) error {
|
||||
state := c.state()
|
||||
if state == nil {
|
||||
return errNilClusterState
|
||||
state, err := c.state()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var wg sync.WaitGroup
|
||||
|
|
@ -688,9 +754,9 @@ func (c *ClusterClient) ForEachSlave(fn func(client *Client) error) error {
|
|||
// ForEachNode concurrently calls the fn on each known node in the cluster.
|
||||
// It returns the first error if any.
|
||||
func (c *ClusterClient) ForEachNode(fn func(client *Client) error) error {
|
||||
state := c.state()
|
||||
if state == nil {
|
||||
return errNilClusterState
|
||||
state, err := c.state()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var wg sync.WaitGroup
|
||||
|
|
@ -728,27 +794,31 @@ func (c *ClusterClient) ForEachNode(fn func(client *Client) error) error {
|
|||
func (c *ClusterClient) PoolStats() *PoolStats {
|
||||
var acc PoolStats
|
||||
|
||||
state := c.state()
|
||||
state, _ := c.state()
|
||||
if state == nil {
|
||||
return &acc
|
||||
}
|
||||
|
||||
for _, node := range state.masters {
|
||||
s := node.Client.connPool.Stats()
|
||||
acc.Requests += s.Requests
|
||||
acc.Hits += s.Hits
|
||||
acc.Misses += s.Misses
|
||||
acc.Timeouts += s.Timeouts
|
||||
|
||||
acc.TotalConns += s.TotalConns
|
||||
acc.FreeConns += s.FreeConns
|
||||
acc.StaleConns += s.StaleConns
|
||||
}
|
||||
|
||||
for _, node := range state.slaves {
|
||||
s := node.Client.connPool.Stats()
|
||||
acc.Requests += s.Requests
|
||||
acc.Hits += s.Hits
|
||||
acc.Misses += s.Misses
|
||||
acc.Timeouts += s.Timeouts
|
||||
|
||||
acc.TotalConns += s.TotalConns
|
||||
acc.FreeConns += s.FreeConns
|
||||
acc.StaleConns += s.StaleConns
|
||||
}
|
||||
|
||||
return &acc
|
||||
|
|
@ -762,10 +832,8 @@ func (c *ClusterClient) lazyReloadState() {
|
|||
go func() {
|
||||
defer atomic.StoreUint32(&c.reloading, 0)
|
||||
|
||||
var state *clusterState
|
||||
for {
|
||||
var err error
|
||||
state, err = c.reloadState()
|
||||
state, err := c.reloadState()
|
||||
if err == pool.ErrClosed {
|
||||
return
|
||||
}
|
||||
|
|
@ -776,11 +844,10 @@ func (c *ClusterClient) lazyReloadState() {
|
|||
}
|
||||
|
||||
c._state.Store(state)
|
||||
time.Sleep(5 * time.Second)
|
||||
c.nodes.GC(state.generation)
|
||||
break
|
||||
}
|
||||
|
||||
time.Sleep(3 * time.Second)
|
||||
c.nodes.GC(state.generation)
|
||||
}()
|
||||
}
|
||||
|
||||
|
|
@ -810,21 +877,12 @@ func (c *ClusterClient) reaper(idleCheckFrequency time.Duration) {
|
|||
break
|
||||
}
|
||||
|
||||
var n int
|
||||
for _, node := range nodes {
|
||||
nn, err := node.Client.connPool.(*pool.ConnPool).ReapStaleConns()
|
||||
_, err := node.Client.connPool.(*pool.ConnPool).ReapStaleConns()
|
||||
if err != nil {
|
||||
internal.Logf("ReapStaleConns failed: %s", err)
|
||||
} else {
|
||||
n += nn
|
||||
}
|
||||
}
|
||||
|
||||
s := c.PoolStats()
|
||||
internal.Logf(
|
||||
"reaper: removed %d stale conns (TotalConns=%d FreeConns=%d Requests=%d Hits=%d Timeouts=%d)",
|
||||
n, s.TotalConns, s.FreeConns, s.Requests, s.Hits, s.Timeouts,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -837,16 +895,21 @@ func (c *ClusterClient) Pipeline() Pipeliner {
|
|||
}
|
||||
|
||||
func (c *ClusterClient) Pipelined(fn func(Pipeliner) error) ([]Cmder, error) {
|
||||
return c.Pipeline().pipelined(fn)
|
||||
return c.Pipeline().Pipelined(fn)
|
||||
}
|
||||
|
||||
func (c *ClusterClient) pipelineExec(cmds []Cmder) error {
|
||||
cmdsMap, err := c.mapCmdsByNode(cmds)
|
||||
if err != nil {
|
||||
setCmdsErr(cmds, err)
|
||||
return err
|
||||
}
|
||||
|
||||
for i := 0; i <= c.opt.MaxRedirects; i++ {
|
||||
for attempt := 0; attempt <= c.opt.MaxRedirects; attempt++ {
|
||||
if attempt > 0 {
|
||||
time.Sleep(c.retryBackoff(attempt))
|
||||
}
|
||||
|
||||
failedCmds := make(map[*clusterNode][]Cmder)
|
||||
|
||||
for node, cmds := range cmdsMap {
|
||||
|
|
@ -856,8 +919,12 @@ func (c *ClusterClient) pipelineExec(cmds []Cmder) error {
|
|||
continue
|
||||
}
|
||||
|
||||
err = c.pipelineProcessCmds(cn, cmds, failedCmds)
|
||||
node.Client.releaseConn(cn, err)
|
||||
err = c.pipelineProcessCmds(node, cn, cmds, failedCmds)
|
||||
if err == nil || internal.IsRedisError(err) {
|
||||
_ = node.Client.connPool.Put(cn)
|
||||
} else {
|
||||
_ = node.Client.connPool.Remove(cn)
|
||||
}
|
||||
}
|
||||
|
||||
if len(failedCmds) == 0 {
|
||||
|
|
@ -866,21 +933,20 @@ func (c *ClusterClient) pipelineExec(cmds []Cmder) error {
|
|||
cmdsMap = failedCmds
|
||||
}
|
||||
|
||||
var firstErr error
|
||||
for _, cmd := range cmds {
|
||||
if err := cmd.Err(); err != nil {
|
||||
firstErr = err
|
||||
break
|
||||
}
|
||||
}
|
||||
return firstErr
|
||||
return firstCmdsErr(cmds)
|
||||
}
|
||||
|
||||
func (c *ClusterClient) mapCmdsByNode(cmds []Cmder) (map[*clusterNode][]Cmder, error) {
|
||||
state := c.state()
|
||||
state, err := c.state()
|
||||
if err != nil {
|
||||
setCmdsErr(cmds, err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
cmdsMap := make(map[*clusterNode][]Cmder)
|
||||
for _, cmd := range cmds {
|
||||
_, node, err := c.cmdSlotAndNode(state, cmd)
|
||||
slot := c.cmdSlot(cmd)
|
||||
node, err := state.slotMasterNode(slot)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -890,11 +956,12 @@ func (c *ClusterClient) mapCmdsByNode(cmds []Cmder) (map[*clusterNode][]Cmder, e
|
|||
}
|
||||
|
||||
func (c *ClusterClient) pipelineProcessCmds(
|
||||
cn *pool.Conn, cmds []Cmder, failedCmds map[*clusterNode][]Cmder,
|
||||
node *clusterNode, cn *pool.Conn, cmds []Cmder, failedCmds map[*clusterNode][]Cmder,
|
||||
) error {
|
||||
cn.SetWriteTimeout(c.opt.WriteTimeout)
|
||||
if err := writeCmd(cn, cmds...); err != nil {
|
||||
setCmdsErr(cmds, err)
|
||||
failedCmds[node] = cmds
|
||||
return err
|
||||
}
|
||||
|
||||
|
|
@ -907,46 +974,53 @@ func (c *ClusterClient) pipelineProcessCmds(
|
|||
func (c *ClusterClient) pipelineReadCmds(
|
||||
cn *pool.Conn, cmds []Cmder, failedCmds map[*clusterNode][]Cmder,
|
||||
) error {
|
||||
var firstErr error
|
||||
for _, cmd := range cmds {
|
||||
err := cmd.readReply(cn)
|
||||
if err == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
if firstErr == nil {
|
||||
firstErr = err
|
||||
if c.checkMovedErr(cmd, err, failedCmds) {
|
||||
continue
|
||||
}
|
||||
|
||||
err = c.checkMovedErr(cmd, failedCmds)
|
||||
if err != nil && firstErr == nil {
|
||||
firstErr = err
|
||||
if internal.IsRedisError(err) {
|
||||
continue
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
return firstErr
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *ClusterClient) checkMovedErr(cmd Cmder, failedCmds map[*clusterNode][]Cmder) error {
|
||||
moved, ask, addr := internal.IsMovedError(cmd.Err())
|
||||
func (c *ClusterClient) checkMovedErr(
|
||||
cmd Cmder, err error, failedCmds map[*clusterNode][]Cmder,
|
||||
) bool {
|
||||
moved, ask, addr := internal.IsMovedError(err)
|
||||
|
||||
if moved {
|
||||
c.lazyReloadState()
|
||||
|
||||
node, err := c.nodes.GetOrCreate(addr)
|
||||
if err != nil {
|
||||
return err
|
||||
return false
|
||||
}
|
||||
|
||||
failedCmds[node] = append(failedCmds[node], cmd)
|
||||
return true
|
||||
}
|
||||
|
||||
if ask {
|
||||
node, err := c.nodes.GetOrCreate(addr)
|
||||
if err != nil {
|
||||
return err
|
||||
return false
|
||||
}
|
||||
|
||||
failedCmds[node] = append(failedCmds[node], NewCmd("ASKING"), cmd)
|
||||
return true
|
||||
}
|
||||
return nil
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// TxPipeline acts like Pipeline, but wraps queued commands with MULTI/EXEC.
|
||||
|
|
@ -959,29 +1033,29 @@ func (c *ClusterClient) TxPipeline() Pipeliner {
|
|||
}
|
||||
|
||||
func (c *ClusterClient) TxPipelined(fn func(Pipeliner) error) ([]Cmder, error) {
|
||||
return c.TxPipeline().pipelined(fn)
|
||||
return c.TxPipeline().Pipelined(fn)
|
||||
}
|
||||
|
||||
func (c *ClusterClient) txPipelineExec(cmds []Cmder) error {
|
||||
cmdsMap, err := c.mapCmdsBySlot(cmds)
|
||||
state, err := c.state()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
state := c.state()
|
||||
if state == nil {
|
||||
return errNilClusterState
|
||||
}
|
||||
|
||||
cmdsMap := c.mapCmdsBySlot(cmds)
|
||||
for slot, cmds := range cmdsMap {
|
||||
node, err := state.slotMasterNode(slot)
|
||||
if err != nil {
|
||||
setCmdsErr(cmds, err)
|
||||
continue
|
||||
}
|
||||
|
||||
cmdsMap := map[*clusterNode][]Cmder{node: cmds}
|
||||
for i := 0; i <= c.opt.MaxRedirects; i++ {
|
||||
|
||||
for attempt := 0; attempt <= c.opt.MaxRedirects; attempt++ {
|
||||
if attempt > 0 {
|
||||
time.Sleep(c.retryBackoff(attempt))
|
||||
}
|
||||
|
||||
failedCmds := make(map[*clusterNode][]Cmder)
|
||||
|
||||
for node, cmds := range cmdsMap {
|
||||
|
|
@ -992,7 +1066,11 @@ func (c *ClusterClient) txPipelineExec(cmds []Cmder) error {
|
|||
}
|
||||
|
||||
err = c.txPipelineProcessCmds(node, cn, cmds, failedCmds)
|
||||
node.Client.releaseConn(cn, err)
|
||||
if err == nil || internal.IsRedisError(err) {
|
||||
_ = node.Client.connPool.Put(cn)
|
||||
} else {
|
||||
_ = node.Client.connPool.Remove(cn)
|
||||
}
|
||||
}
|
||||
|
||||
if len(failedCmds) == 0 {
|
||||
|
|
@ -1002,27 +1080,16 @@ func (c *ClusterClient) txPipelineExec(cmds []Cmder) error {
|
|||
}
|
||||
}
|
||||
|
||||
var firstErr error
|
||||
for _, cmd := range cmds {
|
||||
if err := cmd.Err(); err != nil {
|
||||
firstErr = err
|
||||
break
|
||||
}
|
||||
}
|
||||
return firstErr
|
||||
return firstCmdsErr(cmds)
|
||||
}
|
||||
|
||||
func (c *ClusterClient) mapCmdsBySlot(cmds []Cmder) (map[int][]Cmder, error) {
|
||||
state := c.state()
|
||||
func (c *ClusterClient) mapCmdsBySlot(cmds []Cmder) map[int][]Cmder {
|
||||
cmdsMap := make(map[int][]Cmder)
|
||||
for _, cmd := range cmds {
|
||||
slot, _, err := c.cmdSlotAndNode(state, cmd)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
slot := c.cmdSlot(cmd)
|
||||
cmdsMap[slot] = append(cmdsMap[slot], cmd)
|
||||
}
|
||||
return cmdsMap, nil
|
||||
return cmdsMap
|
||||
}
|
||||
|
||||
func (c *ClusterClient) txPipelineProcessCmds(
|
||||
|
|
@ -1039,22 +1106,20 @@ func (c *ClusterClient) txPipelineProcessCmds(
|
|||
cn.SetReadTimeout(c.opt.ReadTimeout)
|
||||
|
||||
if err := c.txPipelineReadQueued(cn, cmds, failedCmds); err != nil {
|
||||
setCmdsErr(cmds, err)
|
||||
return err
|
||||
}
|
||||
|
||||
_, err := pipelineReadCmds(cn, cmds)
|
||||
return err
|
||||
return pipelineReadCmds(cn, cmds)
|
||||
}
|
||||
|
||||
func (c *ClusterClient) txPipelineReadQueued(
|
||||
cn *pool.Conn, cmds []Cmder, failedCmds map[*clusterNode][]Cmder,
|
||||
) error {
|
||||
var firstErr error
|
||||
|
||||
// Parse queued replies.
|
||||
var statusCmd StatusCmd
|
||||
if err := statusCmd.readReply(cn); err != nil && firstErr == nil {
|
||||
firstErr = err
|
||||
if err := statusCmd.readReply(cn); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, cmd := range cmds {
|
||||
|
|
@ -1063,15 +1128,11 @@ func (c *ClusterClient) txPipelineReadQueued(
|
|||
continue
|
||||
}
|
||||
|
||||
cmd.setErr(err)
|
||||
if firstErr == nil {
|
||||
firstErr = err
|
||||
if c.checkMovedErr(cmd, err, failedCmds) || internal.IsRedisError(err) {
|
||||
continue
|
||||
}
|
||||
|
||||
err = c.checkMovedErr(cmd, failedCmds)
|
||||
if err != nil && firstErr == nil {
|
||||
firstErr = err
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// Parse number of replies.
|
||||
|
|
@ -1085,7 +1146,13 @@ func (c *ClusterClient) txPipelineReadQueued(
|
|||
|
||||
switch line[0] {
|
||||
case proto.ErrorReply:
|
||||
return proto.ParseErrorReply(line)
|
||||
err := proto.ParseErrorReply(line)
|
||||
for _, cmd := range cmds {
|
||||
if !c.checkMovedErr(cmd, err, failedCmds) {
|
||||
break
|
||||
}
|
||||
}
|
||||
return err
|
||||
case proto.ArrayReply:
|
||||
// ok
|
||||
default:
|
||||
|
|
@ -1093,7 +1160,7 @@ func (c *ClusterClient) txPipelineReadQueued(
|
|||
return err
|
||||
}
|
||||
|
||||
return firstErr
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *ClusterClient) pubSub(channels []string) *PubSub {
|
||||
|
|
@ -1112,7 +1179,12 @@ func (c *ClusterClient) pubSub(channels []string) *PubSub {
|
|||
slot = -1
|
||||
}
|
||||
|
||||
masterNode, err := c.state().slotMasterNode(slot)
|
||||
state, err := c.state()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
masterNode, err := state.slotMasterNode(slot)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
|||
22
vendor/github.com/go-redis/redis/cluster_commands.go
generated
vendored
Normal file
22
vendor/github.com/go-redis/redis/cluster_commands.go
generated
vendored
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
package redis
|
||||
|
||||
import "sync/atomic"
|
||||
|
||||
func (c *ClusterClient) DBSize() *IntCmd {
|
||||
cmd := NewIntCmd("dbsize")
|
||||
var size int64
|
||||
err := c.ForEachMaster(func(master *Client) error {
|
||||
n, err := master.DBSize().Result()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
atomic.AddInt64(&size, n)
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
cmd.setErr(err)
|
||||
return cmd
|
||||
}
|
||||
cmd.val = size
|
||||
return cmd
|
||||
}
|
||||
81
vendor/github.com/go-redis/redis/cluster_test.go
generated
vendored
81
vendor/github.com/go-redis/redis/cluster_test.go
generated
vendored
|
|
@ -200,7 +200,7 @@ var _ = Describe("ClusterClient", func() {
|
|||
|
||||
Eventually(func() string {
|
||||
return client.Get("A").Val()
|
||||
}).Should(Equal("VALUE"))
|
||||
}, 30*time.Second).Should(Equal("VALUE"))
|
||||
|
||||
cnt, err := client.Del("A").Result()
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
|
@ -215,7 +215,7 @@ var _ = Describe("ClusterClient", func() {
|
|||
|
||||
Eventually(func() string {
|
||||
return client.Get("A").Val()
|
||||
}).Should(Equal("VALUE"))
|
||||
}, 30*time.Second).Should(Equal("VALUE"))
|
||||
})
|
||||
|
||||
It("distributes keys", func() {
|
||||
|
|
@ -227,7 +227,7 @@ var _ = Describe("ClusterClient", func() {
|
|||
for _, master := range cluster.masters() {
|
||||
Eventually(func() string {
|
||||
return master.Info("keyspace").Val()
|
||||
}, 5*time.Second).Should(Or(
|
||||
}, 30*time.Second).Should(Or(
|
||||
ContainSubstring("keys=31"),
|
||||
ContainSubstring("keys=29"),
|
||||
ContainSubstring("keys=40"),
|
||||
|
|
@ -251,7 +251,7 @@ var _ = Describe("ClusterClient", func() {
|
|||
for _, master := range cluster.masters() {
|
||||
Eventually(func() string {
|
||||
return master.Info("keyspace").Val()
|
||||
}, 5*time.Second).Should(Or(
|
||||
}, 30*time.Second).Should(Or(
|
||||
ContainSubstring("keys=31"),
|
||||
ContainSubstring("keys=29"),
|
||||
ContainSubstring("keys=40"),
|
||||
|
|
@ -320,10 +320,6 @@ var _ = Describe("ClusterClient", func() {
|
|||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(cmds).To(HaveLen(14))
|
||||
|
||||
if opt.RouteByLatency {
|
||||
return
|
||||
}
|
||||
|
||||
for _, key := range keys {
|
||||
slot := hashtag.Slot(key)
|
||||
client.SwapSlotNodes(slot)
|
||||
|
|
@ -432,6 +428,9 @@ var _ = Describe("ClusterClient", func() {
|
|||
})
|
||||
|
||||
AfterEach(func() {
|
||||
_ = client.ForEachMaster(func(master *redis.Client) error {
|
||||
return master.FlushDB().Err()
|
||||
})
|
||||
Expect(client.Close()).NotTo(HaveOccurred())
|
||||
})
|
||||
|
||||
|
|
@ -476,11 +475,9 @@ var _ = Describe("ClusterClient", func() {
|
|||
})
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
for _, client := range cluster.masters() {
|
||||
size, err := client.DBSize().Result()
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(size).To(Equal(int64(0)))
|
||||
}
|
||||
size, err := client.DBSize().Result()
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(size).To(Equal(int64(0)))
|
||||
})
|
||||
|
||||
It("should CLUSTER SLOTS", func() {
|
||||
|
|
@ -560,6 +557,9 @@ var _ = Describe("ClusterClient", func() {
|
|||
})
|
||||
|
||||
AfterEach(func() {
|
||||
_ = client.ForEachMaster(func(master *redis.Client) error {
|
||||
return master.FlushDB().Err()
|
||||
})
|
||||
Expect(client.Close()).NotTo(HaveOccurred())
|
||||
})
|
||||
|
||||
|
|
@ -575,10 +575,19 @@ var _ = Describe("ClusterClient", func() {
|
|||
_ = client.ForEachMaster(func(master *redis.Client) error {
|
||||
return master.FlushDB().Err()
|
||||
})
|
||||
|
||||
_ = client.ForEachSlave(func(slave *redis.Client) error {
|
||||
Eventually(func() int64 {
|
||||
return client.DBSize().Val()
|
||||
}, 30*time.Second).Should(Equal(int64(0)))
|
||||
return nil
|
||||
})
|
||||
})
|
||||
|
||||
AfterEach(func() {
|
||||
client.FlushDB()
|
||||
_ = client.ForEachMaster(func(master *redis.Client) error {
|
||||
return master.FlushDB().Err()
|
||||
})
|
||||
Expect(client.Close()).NotTo(HaveOccurred())
|
||||
})
|
||||
|
||||
|
|
@ -597,7 +606,7 @@ var _ = Describe("ClusterClient without nodes", func() {
|
|||
Expect(client.Close()).NotTo(HaveOccurred())
|
||||
})
|
||||
|
||||
It("returns an error", func() {
|
||||
It("Ping returns an error", func() {
|
||||
err := client.Ping().Err()
|
||||
Expect(err).To(MatchError("redis: cluster has no nodes"))
|
||||
})
|
||||
|
|
@ -626,7 +635,7 @@ var _ = Describe("ClusterClient without valid nodes", func() {
|
|||
|
||||
It("returns an error", func() {
|
||||
err := client.Ping().Err()
|
||||
Expect(err).To(MatchError("ERR This instance has cluster support disabled"))
|
||||
Expect(err).To(MatchError("redis: cannot load cluster slots"))
|
||||
})
|
||||
|
||||
It("pipeline returns an error", func() {
|
||||
|
|
@ -634,7 +643,7 @@ var _ = Describe("ClusterClient without valid nodes", func() {
|
|||
pipe.Ping()
|
||||
return nil
|
||||
})
|
||||
Expect(err).To(MatchError("ERR This instance has cluster support disabled"))
|
||||
Expect(err).To(MatchError("redis: cannot load cluster slots"))
|
||||
})
|
||||
})
|
||||
|
||||
|
|
@ -664,7 +673,7 @@ var _ = Describe("ClusterClient timeout", func() {
|
|||
It("Tx timeouts", func() {
|
||||
err := client.Watch(func(tx *redis.Tx) error {
|
||||
return tx.Ping().Err()
|
||||
})
|
||||
}, "foo")
|
||||
Expect(err).To(HaveOccurred())
|
||||
Expect(err.(net.Error).Timeout()).To(BeTrue())
|
||||
})
|
||||
|
|
@ -676,42 +685,20 @@ var _ = Describe("ClusterClient timeout", func() {
|
|||
return nil
|
||||
})
|
||||
return err
|
||||
})
|
||||
}, "foo")
|
||||
Expect(err).To(HaveOccurred())
|
||||
Expect(err.(net.Error).Timeout()).To(BeTrue())
|
||||
})
|
||||
}
|
||||
|
||||
Context("read timeout", func() {
|
||||
const pause = time.Second
|
||||
|
||||
Context("read/write timeout", func() {
|
||||
BeforeEach(func() {
|
||||
opt := redisClusterOptions()
|
||||
opt.ReadTimeout = time.Nanosecond
|
||||
opt.WriteTimeout = -1
|
||||
client = cluster.clusterClient(opt)
|
||||
})
|
||||
|
||||
testTimeout()
|
||||
})
|
||||
|
||||
Context("write timeout", func() {
|
||||
BeforeEach(func() {
|
||||
opt := redisClusterOptions()
|
||||
opt.ReadTimeout = time.Nanosecond
|
||||
opt.WriteTimeout = -1
|
||||
client = cluster.clusterClient(opt)
|
||||
})
|
||||
|
||||
testTimeout()
|
||||
})
|
||||
|
||||
Context("ClientPause timeout", func() {
|
||||
const pause = time.Second
|
||||
|
||||
BeforeEach(func() {
|
||||
opt := redisClusterOptions()
|
||||
opt.ReadTimeout = pause / 10
|
||||
opt.WriteTimeout = pause / 10
|
||||
opt.MaxRedirects = -1
|
||||
opt.ReadTimeout = 100 * time.Millisecond
|
||||
opt.WriteTimeout = 100 * time.Millisecond
|
||||
opt.MaxRedirects = 1
|
||||
client = cluster.clusterClient(opt)
|
||||
|
||||
err := client.ForEachNode(func(client *redis.Client) error {
|
||||
|
|
|
|||
86
vendor/github.com/go-redis/redis/command.go
generated
vendored
86
vendor/github.com/go-redis/redis/command.go
generated
vendored
|
|
@ -12,28 +12,10 @@ import (
|
|||
"github.com/go-redis/redis/internal/proto"
|
||||
)
|
||||
|
||||
var (
|
||||
_ Cmder = (*Cmd)(nil)
|
||||
_ Cmder = (*SliceCmd)(nil)
|
||||
_ Cmder = (*StatusCmd)(nil)
|
||||
_ Cmder = (*IntCmd)(nil)
|
||||
_ Cmder = (*DurationCmd)(nil)
|
||||
_ Cmder = (*BoolCmd)(nil)
|
||||
_ Cmder = (*StringCmd)(nil)
|
||||
_ Cmder = (*FloatCmd)(nil)
|
||||
_ Cmder = (*StringSliceCmd)(nil)
|
||||
_ Cmder = (*BoolSliceCmd)(nil)
|
||||
_ Cmder = (*StringStringMapCmd)(nil)
|
||||
_ Cmder = (*StringIntMapCmd)(nil)
|
||||
_ Cmder = (*ZSliceCmd)(nil)
|
||||
_ Cmder = (*ScanCmd)(nil)
|
||||
_ Cmder = (*ClusterSlotsCmd)(nil)
|
||||
)
|
||||
|
||||
type Cmder interface {
|
||||
args() []interface{}
|
||||
arg(int) string
|
||||
Name() string
|
||||
Args() []interface{}
|
||||
stringArg(int) string
|
||||
|
||||
readReply(*pool.Conn) error
|
||||
setErr(error)
|
||||
|
|
@ -46,14 +28,25 @@ type Cmder interface {
|
|||
|
||||
func setCmdsErr(cmds []Cmder, e error) {
|
||||
for _, cmd := range cmds {
|
||||
cmd.setErr(e)
|
||||
if cmd.Err() == nil {
|
||||
cmd.setErr(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func firstCmdsErr(cmds []Cmder) error {
|
||||
for _, cmd := range cmds {
|
||||
if err := cmd.Err(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func writeCmd(cn *pool.Conn, cmds ...Cmder) error {
|
||||
cn.Wb.Reset()
|
||||
for _, cmd := range cmds {
|
||||
if err := cn.Wb.Append(cmd.args()); err != nil {
|
||||
if err := cn.Wb.Append(cmd.Args()); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
|
@ -64,7 +57,7 @@ func writeCmd(cn *pool.Conn, cmds ...Cmder) error {
|
|||
|
||||
func cmdString(cmd Cmder, val interface{}) string {
|
||||
var ss []string
|
||||
for _, arg := range cmd.args() {
|
||||
for _, arg := range cmd.Args() {
|
||||
ss = append(ss, fmt.Sprint(arg))
|
||||
}
|
||||
s := strings.Join(ss, " ")
|
||||
|
|
@ -86,7 +79,7 @@ func cmdString(cmd Cmder, val interface{}) string {
|
|||
func cmdFirstKeyPos(cmd Cmder, info *CommandInfo) int {
|
||||
switch cmd.Name() {
|
||||
case "eval", "evalsha":
|
||||
if cmd.arg(2) != "0" {
|
||||
if cmd.stringArg(2) != "0" {
|
||||
return 3
|
||||
} else {
|
||||
return -1
|
||||
|
|
@ -95,7 +88,6 @@ func cmdFirstKeyPos(cmd Cmder, info *CommandInfo) int {
|
|||
return 1
|
||||
}
|
||||
if info == nil {
|
||||
internal.Logf("info for cmd=%s not found", cmd.Name())
|
||||
return -1
|
||||
}
|
||||
return int(info.FirstKeyPos)
|
||||
|
|
@ -110,15 +102,17 @@ type baseCmd struct {
|
|||
_readTimeout *time.Duration
|
||||
}
|
||||
|
||||
var _ Cmder = (*Cmd)(nil)
|
||||
|
||||
func (cmd *baseCmd) Err() error {
|
||||
return cmd.err
|
||||
}
|
||||
|
||||
func (cmd *baseCmd) args() []interface{} {
|
||||
func (cmd *baseCmd) Args() []interface{} {
|
||||
return cmd._args
|
||||
}
|
||||
|
||||
func (cmd *baseCmd) arg(pos int) string {
|
||||
func (cmd *baseCmd) stringArg(pos int) string {
|
||||
if pos < 0 || pos >= len(cmd._args) {
|
||||
return ""
|
||||
}
|
||||
|
|
@ -129,7 +123,7 @@ func (cmd *baseCmd) arg(pos int) string {
|
|||
func (cmd *baseCmd) Name() string {
|
||||
if len(cmd._args) > 0 {
|
||||
// Cmd name must be lower cased.
|
||||
s := internal.ToLower(cmd.arg(0))
|
||||
s := internal.ToLower(cmd.stringArg(0))
|
||||
cmd._args[0] = s
|
||||
return s
|
||||
}
|
||||
|
|
@ -194,6 +188,8 @@ type SliceCmd struct {
|
|||
val []interface{}
|
||||
}
|
||||
|
||||
var _ Cmder = (*SliceCmd)(nil)
|
||||
|
||||
func NewSliceCmd(args ...interface{}) *SliceCmd {
|
||||
return &SliceCmd{
|
||||
baseCmd: baseCmd{_args: args},
|
||||
|
|
@ -230,6 +226,8 @@ type StatusCmd struct {
|
|||
val string
|
||||
}
|
||||
|
||||
var _ Cmder = (*StatusCmd)(nil)
|
||||
|
||||
func NewStatusCmd(args ...interface{}) *StatusCmd {
|
||||
return &StatusCmd{
|
||||
baseCmd: baseCmd{_args: args},
|
||||
|
|
@ -261,6 +259,8 @@ type IntCmd struct {
|
|||
val int64
|
||||
}
|
||||
|
||||
var _ Cmder = (*IntCmd)(nil)
|
||||
|
||||
func NewIntCmd(args ...interface{}) *IntCmd {
|
||||
return &IntCmd{
|
||||
baseCmd: baseCmd{_args: args},
|
||||
|
|
@ -293,6 +293,8 @@ type DurationCmd struct {
|
|||
precision time.Duration
|
||||
}
|
||||
|
||||
var _ Cmder = (*DurationCmd)(nil)
|
||||
|
||||
func NewDurationCmd(precision time.Duration, args ...interface{}) *DurationCmd {
|
||||
return &DurationCmd{
|
||||
baseCmd: baseCmd{_args: args},
|
||||
|
|
@ -330,6 +332,8 @@ type TimeCmd struct {
|
|||
val time.Time
|
||||
}
|
||||
|
||||
var _ Cmder = (*TimeCmd)(nil)
|
||||
|
||||
func NewTimeCmd(args ...interface{}) *TimeCmd {
|
||||
return &TimeCmd{
|
||||
baseCmd: baseCmd{_args: args},
|
||||
|
|
@ -366,6 +370,8 @@ type BoolCmd struct {
|
|||
val bool
|
||||
}
|
||||
|
||||
var _ Cmder = (*BoolCmd)(nil)
|
||||
|
||||
func NewBoolCmd(args ...interface{}) *BoolCmd {
|
||||
return &BoolCmd{
|
||||
baseCmd: baseCmd{_args: args},
|
||||
|
|
@ -421,6 +427,8 @@ type StringCmd struct {
|
|||
val []byte
|
||||
}
|
||||
|
||||
var _ Cmder = (*StringCmd)(nil)
|
||||
|
||||
func NewStringCmd(args ...interface{}) *StringCmd {
|
||||
return &StringCmd{
|
||||
baseCmd: baseCmd{_args: args},
|
||||
|
|
@ -484,6 +492,8 @@ type FloatCmd struct {
|
|||
val float64
|
||||
}
|
||||
|
||||
var _ Cmder = (*FloatCmd)(nil)
|
||||
|
||||
func NewFloatCmd(args ...interface{}) *FloatCmd {
|
||||
return &FloatCmd{
|
||||
baseCmd: baseCmd{_args: args},
|
||||
|
|
@ -515,6 +525,8 @@ type StringSliceCmd struct {
|
|||
val []string
|
||||
}
|
||||
|
||||
var _ Cmder = (*StringSliceCmd)(nil)
|
||||
|
||||
func NewStringSliceCmd(args ...interface{}) *StringSliceCmd {
|
||||
return &StringSliceCmd{
|
||||
baseCmd: baseCmd{_args: args},
|
||||
|
|
@ -555,6 +567,8 @@ type BoolSliceCmd struct {
|
|||
val []bool
|
||||
}
|
||||
|
||||
var _ Cmder = (*BoolSliceCmd)(nil)
|
||||
|
||||
func NewBoolSliceCmd(args ...interface{}) *BoolSliceCmd {
|
||||
return &BoolSliceCmd{
|
||||
baseCmd: baseCmd{_args: args},
|
||||
|
|
@ -591,6 +605,8 @@ type StringStringMapCmd struct {
|
|||
val map[string]string
|
||||
}
|
||||
|
||||
var _ Cmder = (*StringStringMapCmd)(nil)
|
||||
|
||||
func NewStringStringMapCmd(args ...interface{}) *StringStringMapCmd {
|
||||
return &StringStringMapCmd{
|
||||
baseCmd: baseCmd{_args: args},
|
||||
|
|
@ -627,6 +643,8 @@ type StringIntMapCmd struct {
|
|||
val map[string]int64
|
||||
}
|
||||
|
||||
var _ Cmder = (*StringIntMapCmd)(nil)
|
||||
|
||||
func NewStringIntMapCmd(args ...interface{}) *StringIntMapCmd {
|
||||
return &StringIntMapCmd{
|
||||
baseCmd: baseCmd{_args: args},
|
||||
|
|
@ -663,6 +681,8 @@ type ZSliceCmd struct {
|
|||
val []Z
|
||||
}
|
||||
|
||||
var _ Cmder = (*ZSliceCmd)(nil)
|
||||
|
||||
func NewZSliceCmd(args ...interface{}) *ZSliceCmd {
|
||||
return &ZSliceCmd{
|
||||
baseCmd: baseCmd{_args: args},
|
||||
|
|
@ -702,6 +722,8 @@ type ScanCmd struct {
|
|||
process func(cmd Cmder) error
|
||||
}
|
||||
|
||||
var _ Cmder = (*ScanCmd)(nil)
|
||||
|
||||
func NewScanCmd(process func(cmd Cmder) error, args ...interface{}) *ScanCmd {
|
||||
return &ScanCmd{
|
||||
baseCmd: baseCmd{_args: args},
|
||||
|
|
@ -752,6 +774,8 @@ type ClusterSlotsCmd struct {
|
|||
val []ClusterSlot
|
||||
}
|
||||
|
||||
var _ Cmder = (*ClusterSlotsCmd)(nil)
|
||||
|
||||
func NewClusterSlotsCmd(args ...interface{}) *ClusterSlotsCmd {
|
||||
return &ClusterSlotsCmd{
|
||||
baseCmd: baseCmd{_args: args},
|
||||
|
|
@ -811,6 +835,8 @@ type GeoLocationCmd struct {
|
|||
locations []GeoLocation
|
||||
}
|
||||
|
||||
var _ Cmder = (*GeoLocationCmd)(nil)
|
||||
|
||||
func NewGeoLocationCmd(q *GeoRadiusQuery, args ...interface{}) *GeoLocationCmd {
|
||||
args = append(args, q.Radius)
|
||||
if q.Unit != "" {
|
||||
|
|
@ -881,6 +907,8 @@ type GeoPosCmd struct {
|
|||
positions []*GeoPos
|
||||
}
|
||||
|
||||
var _ Cmder = (*GeoPosCmd)(nil)
|
||||
|
||||
func NewGeoPosCmd(args ...interface{}) *GeoPosCmd {
|
||||
return &GeoPosCmd{
|
||||
baseCmd: baseCmd{_args: args},
|
||||
|
|
@ -927,6 +955,8 @@ type CommandsInfoCmd struct {
|
|||
val map[string]*CommandInfo
|
||||
}
|
||||
|
||||
var _ Cmder = (*CommandsInfoCmd)(nil)
|
||||
|
||||
func NewCommandsInfoCmd(args ...interface{}) *CommandsInfoCmd {
|
||||
return &CommandsInfoCmd{
|
||||
baseCmd: baseCmd{_args: args},
|
||||
|
|
|
|||
5
vendor/github.com/go-redis/redis/commands.go
generated
vendored
5
vendor/github.com/go-redis/redis/commands.go
generated
vendored
|
|
@ -11,7 +11,7 @@ func readTimeout(timeout time.Duration) time.Duration {
|
|||
if timeout == 0 {
|
||||
return 0
|
||||
}
|
||||
return timeout + time.Second
|
||||
return timeout + 10*time.Second
|
||||
}
|
||||
|
||||
func usePrecise(dur time.Duration) bool {
|
||||
|
|
@ -42,6 +42,9 @@ type Cmdable interface {
|
|||
Pipeline() Pipeliner
|
||||
Pipelined(fn func(Pipeliner) error) ([]Cmder, error)
|
||||
|
||||
TxPipelined(fn func(Pipeliner) error) ([]Cmder, error)
|
||||
TxPipeline() Pipeliner
|
||||
|
||||
ClientGetName() *StringCmd
|
||||
Echo(message interface{}) *StringCmd
|
||||
Ping() *StatusCmd
|
||||
|
|
|
|||
55
vendor/github.com/go-redis/redis/commands_test.go
generated
vendored
55
vendor/github.com/go-redis/redis/commands_test.go
generated
vendored
|
|
@ -27,11 +27,21 @@ var _ = Describe("Commands", func() {
|
|||
Describe("server", func() {
|
||||
|
||||
It("should Auth", func() {
|
||||
_, err := client.Pipelined(func(pipe redis.Pipeliner) error {
|
||||
cmds, err := client.Pipelined(func(pipe redis.Pipeliner) error {
|
||||
pipe.Auth("password")
|
||||
pipe.Auth("")
|
||||
return nil
|
||||
})
|
||||
Expect(err).To(MatchError("ERR Client sent AUTH, but no password is set"))
|
||||
Expect(cmds[0].Err()).To(MatchError("ERR Client sent AUTH, but no password is set"))
|
||||
Expect(cmds[1].Err()).To(MatchError("ERR Client sent AUTH, but no password is set"))
|
||||
|
||||
stats := client.PoolStats()
|
||||
Expect(stats.Hits).To(Equal(uint32(1)))
|
||||
Expect(stats.Misses).To(Equal(uint32(1)))
|
||||
Expect(stats.Timeouts).To(Equal(uint32(0)))
|
||||
Expect(stats.TotalConns).To(Equal(uint32(1)))
|
||||
Expect(stats.FreeConns).To(Equal(uint32(1)))
|
||||
})
|
||||
|
||||
It("should Echo", func() {
|
||||
|
|
@ -187,6 +197,29 @@ var _ = Describe("Commands", func() {
|
|||
Expect(tm).To(BeTemporally("~", time.Now(), 3*time.Second))
|
||||
})
|
||||
|
||||
It("Should Command", func() {
|
||||
cmds, err := client.Command().Result()
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(len(cmds)).To(BeNumerically("~", 180, 10))
|
||||
|
||||
cmd := cmds["mget"]
|
||||
Expect(cmd.Name).To(Equal("mget"))
|
||||
Expect(cmd.Arity).To(Equal(int8(-2)))
|
||||
Expect(cmd.Flags).To(ContainElement("readonly"))
|
||||
Expect(cmd.FirstKeyPos).To(Equal(int8(1)))
|
||||
Expect(cmd.LastKeyPos).To(Equal(int8(-1)))
|
||||
Expect(cmd.StepCount).To(Equal(int8(1)))
|
||||
|
||||
cmd = cmds["ping"]
|
||||
Expect(cmd.Name).To(Equal("ping"))
|
||||
Expect(cmd.Arity).To(Equal(int8(-1)))
|
||||
Expect(cmd.Flags).To(ContainElement("stale"))
|
||||
Expect(cmd.Flags).To(ContainElement("fast"))
|
||||
Expect(cmd.FirstKeyPos).To(Equal(int8(0)))
|
||||
Expect(cmd.LastKeyPos).To(Equal(int8(0)))
|
||||
Expect(cmd.StepCount).To(Equal(int8(0)))
|
||||
})
|
||||
|
||||
})
|
||||
|
||||
Describe("debugging", func() {
|
||||
|
|
@ -1358,8 +1391,8 @@ var _ = Describe("Commands", func() {
|
|||
Expect(client.Ping().Err()).NotTo(HaveOccurred())
|
||||
|
||||
stats := client.PoolStats()
|
||||
Expect(stats.Requests).To(Equal(uint32(3)))
|
||||
Expect(stats.Hits).To(Equal(uint32(1)))
|
||||
Expect(stats.Misses).To(Equal(uint32(2)))
|
||||
Expect(stats.Timeouts).To(Equal(uint32(0)))
|
||||
})
|
||||
|
||||
|
|
@ -2887,24 +2920,6 @@ var _ = Describe("Commands", func() {
|
|||
|
||||
})
|
||||
|
||||
Describe("Command", func() {
|
||||
|
||||
It("returns map of commands", func() {
|
||||
cmds, err := client.Command().Result()
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(len(cmds)).To(BeNumerically("~", 180, 10))
|
||||
|
||||
cmd := cmds["mget"]
|
||||
Expect(cmd.Name).To(Equal("mget"))
|
||||
Expect(cmd.Arity).To(Equal(int8(-2)))
|
||||
Expect(cmd.Flags).To(ContainElement("readonly"))
|
||||
Expect(cmd.FirstKeyPos).To(Equal(int8(1)))
|
||||
Expect(cmd.LastKeyPos).To(Equal(int8(-1)))
|
||||
Expect(cmd.StepCount).To(Equal(int8(1)))
|
||||
})
|
||||
|
||||
})
|
||||
|
||||
Describe("Eval", func() {
|
||||
|
||||
It("returns keys and values", func() {
|
||||
|
|
|
|||
14
vendor/github.com/go-redis/redis/export_test.go
generated
vendored
14
vendor/github.com/go-redis/redis/export_test.go
generated
vendored
|
|
@ -20,8 +20,13 @@ func (c *PubSub) ReceiveMessageTimeout(timeout time.Duration) (*Message, error)
|
|||
}
|
||||
|
||||
func (c *ClusterClient) SlotAddrs(slot int) []string {
|
||||
state, err := c.state()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
var addrs []string
|
||||
for _, n := range c.state().slotNodes(slot) {
|
||||
for _, n := range state.slotNodes(slot) {
|
||||
addrs = append(addrs, n.Client.getAddr())
|
||||
}
|
||||
return addrs
|
||||
|
|
@ -29,7 +34,12 @@ func (c *ClusterClient) SlotAddrs(slot int) []string {
|
|||
|
||||
// SwapSlot swaps a slot's master/slave address for testing MOVED redirects.
|
||||
func (c *ClusterClient) SwapSlotNodes(slot int) {
|
||||
nodes := c.state().slots[slot]
|
||||
state, err := c.state()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
nodes := state.slots[slot]
|
||||
if len(nodes) == 2 {
|
||||
nodes[0], nodes[1] = nodes[1], nodes[0]
|
||||
}
|
||||
|
|
|
|||
27
vendor/github.com/go-redis/redis/internal/error.go
generated
vendored
27
vendor/github.com/go-redis/redis/internal/error.go
generated
vendored
|
|
@ -12,11 +12,24 @@ type RedisError string
|
|||
|
||||
func (e RedisError) Error() string { return string(e) }
|
||||
|
||||
func IsRetryableError(err error) bool {
|
||||
return IsNetworkError(err) || err.Error() == "ERR max number of clients reached"
|
||||
func IsRetryableError(err error, retryNetError bool) bool {
|
||||
if IsNetworkError(err) {
|
||||
return retryNetError
|
||||
}
|
||||
s := err.Error()
|
||||
if s == "ERR max number of clients reached" {
|
||||
return true
|
||||
}
|
||||
if strings.HasPrefix(s, "LOADING ") {
|
||||
return true
|
||||
}
|
||||
if strings.HasPrefix(s, "CLUSTERDOWN ") {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func IsInternalError(err error) bool {
|
||||
func IsRedisError(err error) bool {
|
||||
_, ok := err.(RedisError)
|
||||
return ok
|
||||
}
|
||||
|
|
@ -33,7 +46,7 @@ func IsBadConn(err error, allowTimeout bool) bool {
|
|||
if err == nil {
|
||||
return false
|
||||
}
|
||||
if IsInternalError(err) {
|
||||
if IsRedisError(err) {
|
||||
return false
|
||||
}
|
||||
if allowTimeout {
|
||||
|
|
@ -45,7 +58,7 @@ func IsBadConn(err error, allowTimeout bool) bool {
|
|||
}
|
||||
|
||||
func IsMovedError(err error) (moved bool, ask bool, addr string) {
|
||||
if !IsInternalError(err) {
|
||||
if !IsRedisError(err) {
|
||||
return
|
||||
}
|
||||
|
||||
|
|
@ -69,7 +82,3 @@ func IsMovedError(err error) (moved bool, ask bool, addr string) {
|
|||
func IsLoadingError(err error) bool {
|
||||
return strings.HasPrefix(err.Error(), "LOADING ")
|
||||
}
|
||||
|
||||
func IsClusterDownError(err error) bool {
|
||||
return strings.HasPrefix(err.Error(), "CLUSTERDOWN ")
|
||||
}
|
||||
|
|
|
|||
25
vendor/github.com/go-redis/redis/internal/pool/pool.go
generated
vendored
25
vendor/github.com/go-redis/redis/internal/pool/pool.go
generated
vendored
|
|
@ -23,12 +23,13 @@ var timers = sync.Pool{
|
|||
|
||||
// Stats contains pool state information and accumulated stats.
|
||||
type Stats struct {
|
||||
Requests uint32 // number of times a connection was requested by the pool
|
||||
Hits uint32 // number of times free connection was found in the pool
|
||||
Misses uint32 // number of times free connection was NOT found in the pool
|
||||
Timeouts uint32 // number of times a wait timeout occurred
|
||||
|
||||
TotalConns uint32 // the number of total connections in the pool
|
||||
FreeConns uint32 // the number of free connections in the pool
|
||||
TotalConns uint32 // number of total connections in the pool
|
||||
FreeConns uint32 // number of free connections in the pool
|
||||
StaleConns uint32 // number of stale connections removed from the pool
|
||||
}
|
||||
|
||||
type Pooler interface {
|
||||
|
|
@ -150,8 +151,6 @@ func (p *ConnPool) Get() (*Conn, bool, error) {
|
|||
return nil, false, ErrClosed
|
||||
}
|
||||
|
||||
atomic.AddUint32(&p.stats.Requests, 1)
|
||||
|
||||
select {
|
||||
case p.queue <- struct{}{}:
|
||||
default:
|
||||
|
|
@ -189,6 +188,8 @@ func (p *ConnPool) Get() (*Conn, bool, error) {
|
|||
return cn, false, nil
|
||||
}
|
||||
|
||||
atomic.AddUint32(&p.stats.Misses, 1)
|
||||
|
||||
newcn, err := p.NewConn()
|
||||
if err != nil {
|
||||
<-p.queue
|
||||
|
|
@ -265,11 +266,13 @@ func (p *ConnPool) FreeLen() int {
|
|||
|
||||
func (p *ConnPool) Stats() *Stats {
|
||||
return &Stats{
|
||||
Requests: atomic.LoadUint32(&p.stats.Requests),
|
||||
Hits: atomic.LoadUint32(&p.stats.Hits),
|
||||
Timeouts: atomic.LoadUint32(&p.stats.Timeouts),
|
||||
Hits: atomic.LoadUint32(&p.stats.Hits),
|
||||
Misses: atomic.LoadUint32(&p.stats.Misses),
|
||||
Timeouts: atomic.LoadUint32(&p.stats.Timeouts),
|
||||
|
||||
TotalConns: uint32(p.Len()),
|
||||
FreeConns: uint32(p.FreeLen()),
|
||||
StaleConns: atomic.LoadUint32(&p.stats.StaleConns),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -362,10 +365,6 @@ func (p *ConnPool) reaper(frequency time.Duration) {
|
|||
internal.Logf("ReapStaleConns failed: %s", err)
|
||||
continue
|
||||
}
|
||||
s := p.Stats()
|
||||
internal.Logf(
|
||||
"reaper: removed %d stale conns (TotalConns=%d FreeConns=%d Requests=%d Hits=%d Timeouts=%d)",
|
||||
n, s.TotalConns, s.FreeConns, s.Requests, s.Hits, s.Timeouts,
|
||||
)
|
||||
atomic.AddUint32(&p.stats.StaleConns, uint32(n))
|
||||
}
|
||||
}
|
||||
|
|
|
|||
2
vendor/github.com/go-redis/redis/internal/proto/reader.go
generated
vendored
2
vendor/github.com/go-redis/redis/internal/proto/reader.go
generated
vendored
|
|
@ -63,7 +63,7 @@ func (p *Reader) ReadLine() ([]byte, error) {
|
|||
return nil, bufio.ErrBufferFull
|
||||
}
|
||||
if len(line) == 0 {
|
||||
return nil, internal.RedisError("redis: reply is empty")
|
||||
return nil, fmt.Errorf("redis: reply is empty")
|
||||
}
|
||||
if isNilReply(line) {
|
||||
return nil, internal.Nil
|
||||
|
|
|
|||
2
vendor/github.com/go-redis/redis/internal/proto/scan.go
generated
vendored
2
vendor/github.com/go-redis/redis/internal/proto/scan.go
generated
vendored
|
|
@ -11,7 +11,7 @@ import (
|
|||
func Scan(b []byte, v interface{}) error {
|
||||
switch v := v.(type) {
|
||||
case nil:
|
||||
return internal.RedisError("redis: Scan(nil)")
|
||||
return fmt.Errorf("redis: Scan(nil)")
|
||||
case *string:
|
||||
*v = internal.BytesToString(b)
|
||||
return nil
|
||||
|
|
|
|||
4
vendor/github.com/go-redis/redis/main_test.go
generated
vendored
4
vendor/github.com/go-redis/redis/main_test.go
generated
vendored
|
|
@ -50,10 +50,6 @@ var cluster = &clusterScenario{
|
|||
clients: make(map[string]*redis.Client, 6),
|
||||
}
|
||||
|
||||
func init() {
|
||||
//redis.SetLogger(log.New(os.Stderr, "redis: ", log.LstdFlags|log.Lshortfile))
|
||||
}
|
||||
|
||||
var _ = BeforeSuite(func() {
|
||||
var err error
|
||||
|
||||
|
|
|
|||
10
vendor/github.com/go-redis/redis/options.go
generated
vendored
10
vendor/github.com/go-redis/redis/options.go
generated
vendored
|
|
@ -198,13 +198,3 @@ func newConnPool(opt *Options) *pool.ConnPool {
|
|||
IdleCheckFrequency: opt.IdleCheckFrequency,
|
||||
})
|
||||
}
|
||||
|
||||
// PoolStats contains pool state information and accumulated stats.
|
||||
type PoolStats struct {
|
||||
Requests uint32 // number of times a connection was requested by the pool
|
||||
Hits uint32 // number of times free connection was found in the pool
|
||||
Timeouts uint32 // number of times a wait timeout occurred
|
||||
|
||||
TotalConns uint32 // the number of total connections in the pool
|
||||
FreeConns uint32 // the number of free connections in the pool
|
||||
}
|
||||
|
|
|
|||
10
vendor/github.com/go-redis/redis/pipeline.go
generated
vendored
10
vendor/github.com/go-redis/redis/pipeline.go
generated
vendored
|
|
@ -13,9 +13,7 @@ type Pipeliner interface {
|
|||
Process(cmd Cmder) error
|
||||
Close() error
|
||||
Discard() error
|
||||
discard() error
|
||||
Exec() ([]Cmder, error)
|
||||
pipelined(fn func(Pipeliner) error) ([]Cmder, error)
|
||||
}
|
||||
|
||||
var _ Pipeliner = (*Pipeline)(nil)
|
||||
|
|
@ -104,3 +102,11 @@ func (c *Pipeline) Pipelined(fn func(Pipeliner) error) ([]Cmder, error) {
|
|||
func (c *Pipeline) Pipeline() Pipeliner {
|
||||
return c
|
||||
}
|
||||
|
||||
func (c *Pipeline) TxPipelined(fn func(Pipeliner) error) ([]Cmder, error) {
|
||||
return c.pipelined(fn)
|
||||
}
|
||||
|
||||
func (c *Pipeline) TxPipeline() Pipeliner {
|
||||
return c
|
||||
}
|
||||
|
|
|
|||
10
vendor/github.com/go-redis/redis/pool_test.go
generated
vendored
10
vendor/github.com/go-redis/redis/pool_test.go
generated
vendored
|
|
@ -95,8 +95,8 @@ var _ = Describe("pool", func() {
|
|||
Expect(pool.FreeLen()).To(Equal(1))
|
||||
|
||||
stats := pool.Stats()
|
||||
Expect(stats.Requests).To(Equal(uint32(4)))
|
||||
Expect(stats.Hits).To(Equal(uint32(2)))
|
||||
Expect(stats.Misses).To(Equal(uint32(2)))
|
||||
Expect(stats.Timeouts).To(Equal(uint32(0)))
|
||||
})
|
||||
|
||||
|
|
@ -112,30 +112,32 @@ var _ = Describe("pool", func() {
|
|||
Expect(pool.FreeLen()).To(Equal(1))
|
||||
|
||||
stats := pool.Stats()
|
||||
Expect(stats.Requests).To(Equal(uint32(101)))
|
||||
Expect(stats.Hits).To(Equal(uint32(100)))
|
||||
Expect(stats.Misses).To(Equal(uint32(1)))
|
||||
Expect(stats.Timeouts).To(Equal(uint32(0)))
|
||||
})
|
||||
|
||||
It("removes idle connections", func() {
|
||||
stats := client.PoolStats()
|
||||
Expect(stats).To(Equal(&redis.PoolStats{
|
||||
Requests: 1,
|
||||
Hits: 0,
|
||||
Misses: 1,
|
||||
Timeouts: 0,
|
||||
TotalConns: 1,
|
||||
FreeConns: 1,
|
||||
StaleConns: 0,
|
||||
}))
|
||||
|
||||
time.Sleep(2 * time.Second)
|
||||
|
||||
stats = client.PoolStats()
|
||||
Expect(stats).To(Equal(&redis.PoolStats{
|
||||
Requests: 1,
|
||||
Hits: 0,
|
||||
Misses: 1,
|
||||
Timeouts: 0,
|
||||
TotalConns: 0,
|
||||
FreeConns: 0,
|
||||
StaleConns: 1,
|
||||
}))
|
||||
})
|
||||
})
|
||||
|
|
|
|||
5
vendor/github.com/go-redis/redis/pubsub.go
generated
vendored
5
vendor/github.com/go-redis/redis/pubsub.go
generated
vendored
|
|
@ -95,7 +95,10 @@ func (c *PubSub) releaseConn(cn *pool.Conn, err error) {
|
|||
}
|
||||
|
||||
func (c *PubSub) _releaseConn(cn *pool.Conn, err error) {
|
||||
if internal.IsBadConn(err, true) && c.cn == cn {
|
||||
if c.cn != cn {
|
||||
return
|
||||
}
|
||||
if internal.IsBadConn(err, true) {
|
||||
_ = c.closeTheCn()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
6
vendor/github.com/go-redis/redis/pubsub_test.go
generated
vendored
6
vendor/github.com/go-redis/redis/pubsub_test.go
generated
vendored
|
|
@ -68,7 +68,7 @@ var _ = Describe("PubSub", func() {
|
|||
}
|
||||
|
||||
stats := client.PoolStats()
|
||||
Expect(stats.Requests - stats.Hits).To(Equal(uint32(2)))
|
||||
Expect(stats.Misses).To(Equal(uint32(2)))
|
||||
})
|
||||
|
||||
It("should pub/sub channels", func() {
|
||||
|
|
@ -191,7 +191,7 @@ var _ = Describe("PubSub", func() {
|
|||
}
|
||||
|
||||
stats := client.PoolStats()
|
||||
Expect(stats.Requests - stats.Hits).To(Equal(uint32(2)))
|
||||
Expect(stats.Misses).To(Equal(uint32(2)))
|
||||
})
|
||||
|
||||
It("should ping/pong", func() {
|
||||
|
|
@ -290,8 +290,8 @@ var _ = Describe("PubSub", func() {
|
|||
Eventually(done).Should(Receive())
|
||||
|
||||
stats := client.PoolStats()
|
||||
Expect(stats.Requests).To(Equal(uint32(2)))
|
||||
Expect(stats.Hits).To(Equal(uint32(1)))
|
||||
Expect(stats.Misses).To(Equal(uint32(1)))
|
||||
})
|
||||
|
||||
It("returns an error when subscribe fails", func() {
|
||||
|
|
|
|||
92
vendor/github.com/go-redis/redis/redis.go
generated
vendored
92
vendor/github.com/go-redis/redis/redis.go
generated
vendored
|
|
@ -3,6 +3,7 @@ package redis
|
|||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/go-redis/redis/internal"
|
||||
|
|
@ -13,6 +14,10 @@ import (
|
|||
// Redis nil reply, .e.g. when key does not exist.
|
||||
const Nil = internal.Nil
|
||||
|
||||
func init() {
|
||||
SetLogger(log.New(os.Stderr, "redis: ", log.LstdFlags|log.Lshortfile))
|
||||
}
|
||||
|
||||
func SetLogger(logger *log.Logger) {
|
||||
internal.Logger = logger
|
||||
}
|
||||
|
|
@ -131,7 +136,7 @@ func (c *baseClient) defaultProcess(cmd Cmder) error {
|
|||
cn, _, err := c.getConn()
|
||||
if err != nil {
|
||||
cmd.setErr(err)
|
||||
if internal.IsRetryableError(err) {
|
||||
if internal.IsRetryableError(err, true) {
|
||||
continue
|
||||
}
|
||||
return err
|
||||
|
|
@ -141,7 +146,7 @@ func (c *baseClient) defaultProcess(cmd Cmder) error {
|
|||
if err := writeCmd(cn, cmd); err != nil {
|
||||
c.releaseConn(cn, err)
|
||||
cmd.setErr(err)
|
||||
if internal.IsRetryableError(err) {
|
||||
if internal.IsRetryableError(err, true) {
|
||||
continue
|
||||
}
|
||||
return err
|
||||
|
|
@ -150,7 +155,7 @@ func (c *baseClient) defaultProcess(cmd Cmder) error {
|
|||
cn.SetReadTimeout(c.cmdTimeout(cmd))
|
||||
err = cmd.readReply(cn)
|
||||
c.releaseConn(cn, err)
|
||||
if err != nil && internal.IsRetryableError(err) {
|
||||
if err != nil && internal.IsRetryableError(err, cmd.readTimeout() == nil) {
|
||||
continue
|
||||
}
|
||||
|
||||
|
|
@ -197,8 +202,11 @@ type pipelineProcessor func(*pool.Conn, []Cmder) (bool, error)
|
|||
|
||||
func (c *baseClient) pipelineExecer(p pipelineProcessor) pipelineExecer {
|
||||
return func(cmds []Cmder) error {
|
||||
var firstErr error
|
||||
for i := 0; i <= c.opt.MaxRetries; i++ {
|
||||
for attempt := 0; attempt <= c.opt.MaxRetries; attempt++ {
|
||||
if attempt > 0 {
|
||||
time.Sleep(c.retryBackoff(attempt))
|
||||
}
|
||||
|
||||
cn, _, err := c.getConn()
|
||||
if err != nil {
|
||||
setCmdsErr(cmds, err)
|
||||
|
|
@ -206,18 +214,18 @@ func (c *baseClient) pipelineExecer(p pipelineProcessor) pipelineExecer {
|
|||
}
|
||||
|
||||
canRetry, err := p(cn, cmds)
|
||||
c.releaseConn(cn, err)
|
||||
if err == nil {
|
||||
return nil
|
||||
|
||||
if err == nil || internal.IsRedisError(err) {
|
||||
_ = c.connPool.Put(cn)
|
||||
break
|
||||
}
|
||||
if firstErr == nil {
|
||||
firstErr = err
|
||||
}
|
||||
if !canRetry || !internal.IsRetryableError(err) {
|
||||
_ = c.connPool.Remove(cn)
|
||||
|
||||
if !canRetry || !internal.IsRetryableError(err, true) {
|
||||
break
|
||||
}
|
||||
}
|
||||
return firstErr
|
||||
return firstCmdsErr(cmds)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -230,23 +238,17 @@ func (c *baseClient) pipelineProcessCmds(cn *pool.Conn, cmds []Cmder) (bool, err
|
|||
|
||||
// Set read timeout for all commands.
|
||||
cn.SetReadTimeout(c.opt.ReadTimeout)
|
||||
return pipelineReadCmds(cn, cmds)
|
||||
return true, pipelineReadCmds(cn, cmds)
|
||||
}
|
||||
|
||||
func pipelineReadCmds(cn *pool.Conn, cmds []Cmder) (retry bool, firstErr error) {
|
||||
for i, cmd := range cmds {
|
||||
func pipelineReadCmds(cn *pool.Conn, cmds []Cmder) error {
|
||||
for _, cmd := range cmds {
|
||||
err := cmd.readReply(cn)
|
||||
if err == nil {
|
||||
continue
|
||||
}
|
||||
if i == 0 {
|
||||
retry = true
|
||||
}
|
||||
if firstErr == nil {
|
||||
firstErr = err
|
||||
if err != nil && !internal.IsRedisError(err) {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *baseClient) txPipelineProcessCmds(cn *pool.Conn, cmds []Cmder) (bool, error) {
|
||||
|
|
@ -260,11 +262,11 @@ func (c *baseClient) txPipelineProcessCmds(cn *pool.Conn, cmds []Cmder) (bool, e
|
|||
cn.SetReadTimeout(c.opt.ReadTimeout)
|
||||
|
||||
if err := c.txPipelineReadQueued(cn, cmds); err != nil {
|
||||
setCmdsErr(cmds, err)
|
||||
return false, err
|
||||
}
|
||||
|
||||
_, err := pipelineReadCmds(cn, cmds)
|
||||
return false, err
|
||||
return false, pipelineReadCmds(cn, cmds)
|
||||
}
|
||||
|
||||
func txPipelineWriteMulti(cn *pool.Conn, cmds []Cmder) error {
|
||||
|
|
@ -276,21 +278,16 @@ func txPipelineWriteMulti(cn *pool.Conn, cmds []Cmder) error {
|
|||
}
|
||||
|
||||
func (c *baseClient) txPipelineReadQueued(cn *pool.Conn, cmds []Cmder) error {
|
||||
var firstErr error
|
||||
|
||||
// Parse queued replies.
|
||||
var statusCmd StatusCmd
|
||||
if err := statusCmd.readReply(cn); err != nil && firstErr == nil {
|
||||
firstErr = err
|
||||
if err := statusCmd.readReply(cn); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, cmd := range cmds {
|
||||
for _ = range cmds {
|
||||
err := statusCmd.readReply(cn)
|
||||
if err != nil {
|
||||
cmd.setErr(err)
|
||||
if firstErr == nil {
|
||||
firstErr = err
|
||||
}
|
||||
if err != nil && !internal.IsRedisError(err) {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -355,21 +352,16 @@ func (c *Client) Options() *Options {
|
|||
return c.opt
|
||||
}
|
||||
|
||||
type PoolStats pool.Stats
|
||||
|
||||
// PoolStats returns connection pool stats.
|
||||
func (c *Client) PoolStats() *PoolStats {
|
||||
s := c.connPool.Stats()
|
||||
return &PoolStats{
|
||||
Requests: s.Requests,
|
||||
Hits: s.Hits,
|
||||
Timeouts: s.Timeouts,
|
||||
|
||||
TotalConns: s.TotalConns,
|
||||
FreeConns: s.FreeConns,
|
||||
}
|
||||
stats := c.connPool.Stats()
|
||||
return (*PoolStats)(stats)
|
||||
}
|
||||
|
||||
func (c *Client) Pipelined(fn func(Pipeliner) error) ([]Cmder, error) {
|
||||
return c.Pipeline().pipelined(fn)
|
||||
return c.Pipeline().Pipelined(fn)
|
||||
}
|
||||
|
||||
func (c *Client) Pipeline() Pipeliner {
|
||||
|
|
@ -381,7 +373,7 @@ func (c *Client) Pipeline() Pipeliner {
|
|||
}
|
||||
|
||||
func (c *Client) TxPipelined(fn func(Pipeliner) error) ([]Cmder, error) {
|
||||
return c.TxPipeline().pipelined(fn)
|
||||
return c.TxPipeline().Pipelined(fn)
|
||||
}
|
||||
|
||||
// TxPipeline acts like Pipeline, but wraps queued commands with MULTI/EXEC.
|
||||
|
|
@ -433,7 +425,7 @@ type Conn struct {
|
|||
}
|
||||
|
||||
func (c *Conn) Pipelined(fn func(Pipeliner) error) ([]Cmder, error) {
|
||||
return c.Pipeline().pipelined(fn)
|
||||
return c.Pipeline().Pipelined(fn)
|
||||
}
|
||||
|
||||
func (c *Conn) Pipeline() Pipeliner {
|
||||
|
|
@ -445,7 +437,7 @@ func (c *Conn) Pipeline() Pipeliner {
|
|||
}
|
||||
|
||||
func (c *Conn) TxPipelined(fn func(Pipeliner) error) ([]Cmder, error) {
|
||||
return c.TxPipeline().pipelined(fn)
|
||||
return c.TxPipeline().Pipelined(fn)
|
||||
}
|
||||
|
||||
// TxPipeline acts like Pipeline, but wraps queued commands with MULTI/EXEC.
|
||||
|
|
|
|||
121
vendor/github.com/go-redis/redis/ring.go
generated
vendored
121
vendor/github.com/go-redis/redis/ring.go
generated
vendored
|
|
@ -34,7 +34,9 @@ type RingOptions struct {
|
|||
DB int
|
||||
Password string
|
||||
|
||||
MaxRetries int
|
||||
MaxRetries int
|
||||
MinRetryBackoff time.Duration
|
||||
MaxRetryBackoff time.Duration
|
||||
|
||||
DialTimeout time.Duration
|
||||
ReadTimeout time.Duration
|
||||
|
|
@ -50,6 +52,19 @@ func (opt *RingOptions) init() {
|
|||
if opt.HeartbeatFrequency == 0 {
|
||||
opt.HeartbeatFrequency = 500 * time.Millisecond
|
||||
}
|
||||
|
||||
switch opt.MinRetryBackoff {
|
||||
case -1:
|
||||
opt.MinRetryBackoff = 0
|
||||
case 0:
|
||||
opt.MinRetryBackoff = 8 * time.Millisecond
|
||||
}
|
||||
switch opt.MaxRetryBackoff {
|
||||
case -1:
|
||||
opt.MaxRetryBackoff = 0
|
||||
case 0:
|
||||
opt.MaxRetryBackoff = 512 * time.Millisecond
|
||||
}
|
||||
}
|
||||
|
||||
func (opt *RingOptions) clientOptions() *Options {
|
||||
|
|
@ -130,9 +145,10 @@ type Ring struct {
|
|||
opt *RingOptions
|
||||
nreplicas int
|
||||
|
||||
mu sync.RWMutex
|
||||
hash *consistenthash.Map
|
||||
shards map[string]*ringShard
|
||||
mu sync.RWMutex
|
||||
hash *consistenthash.Map
|
||||
shards map[string]*ringShard
|
||||
shardsList []*ringShard
|
||||
|
||||
cmdsInfoOnce internal.Once
|
||||
cmdsInfo map[string]*CommandInfo
|
||||
|
|
@ -154,24 +170,41 @@ func NewRing(opt *RingOptions) *Ring {
|
|||
for name, addr := range opt.Addrs {
|
||||
clopt := opt.clientOptions()
|
||||
clopt.Addr = addr
|
||||
ring.addClient(name, NewClient(clopt))
|
||||
ring.addShard(name, NewClient(clopt))
|
||||
}
|
||||
go ring.heartbeat()
|
||||
return ring
|
||||
}
|
||||
|
||||
func (c *Ring) addShard(name string, cl *Client) {
|
||||
shard := &ringShard{Client: cl}
|
||||
c.mu.Lock()
|
||||
c.hash.Add(name)
|
||||
c.shards[name] = shard
|
||||
c.shardsList = append(c.shardsList, shard)
|
||||
c.mu.Unlock()
|
||||
}
|
||||
|
||||
// Options returns read-only Options that were used to create the client.
|
||||
func (c *Ring) Options() *RingOptions {
|
||||
return c.opt
|
||||
}
|
||||
|
||||
func (c *Ring) retryBackoff(attempt int) time.Duration {
|
||||
return internal.RetryBackoff(attempt, c.opt.MinRetryBackoff, c.opt.MaxRetryBackoff)
|
||||
}
|
||||
|
||||
// PoolStats returns accumulated connection pool stats.
|
||||
func (c *Ring) PoolStats() *PoolStats {
|
||||
c.mu.RLock()
|
||||
shards := c.shardsList
|
||||
c.mu.RUnlock()
|
||||
|
||||
var acc PoolStats
|
||||
for _, shard := range c.shards {
|
||||
for _, shard := range shards {
|
||||
s := shard.Client.connPool.Stats()
|
||||
acc.Requests += s.Requests
|
||||
acc.Hits += s.Hits
|
||||
acc.Misses += s.Misses
|
||||
acc.Timeouts += s.Timeouts
|
||||
acc.TotalConns += s.TotalConns
|
||||
acc.FreeConns += s.FreeConns
|
||||
|
|
@ -210,9 +243,13 @@ func (c *Ring) PSubscribe(channels ...string) *PubSub {
|
|||
// ForEachShard concurrently calls the fn on each live shard in the ring.
|
||||
// It returns the first error if any.
|
||||
func (c *Ring) ForEachShard(fn func(client *Client) error) error {
|
||||
c.mu.RLock()
|
||||
shards := c.shardsList
|
||||
c.mu.RUnlock()
|
||||
|
||||
var wg sync.WaitGroup
|
||||
errCh := make(chan error, 1)
|
||||
for _, shard := range c.shards {
|
||||
for _, shard := range shards {
|
||||
if shard.IsDown() {
|
||||
continue
|
||||
}
|
||||
|
|
@ -241,8 +278,12 @@ func (c *Ring) ForEachShard(fn func(client *Client) error) error {
|
|||
|
||||
func (c *Ring) cmdInfo(name string) *CommandInfo {
|
||||
err := c.cmdsInfoOnce.Do(func() error {
|
||||
c.mu.RLock()
|
||||
shards := c.shardsList
|
||||
c.mu.RUnlock()
|
||||
|
||||
var firstErr error
|
||||
for _, shard := range c.shards {
|
||||
for _, shard := range shards {
|
||||
cmdsInfo, err := shard.Client.Command().Result()
|
||||
if err == nil {
|
||||
c.cmdsInfo = cmdsInfo
|
||||
|
|
@ -257,14 +298,11 @@ func (c *Ring) cmdInfo(name string) *CommandInfo {
|
|||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
return c.cmdsInfo[name]
|
||||
}
|
||||
|
||||
func (c *Ring) addClient(name string, cl *Client) {
|
||||
c.mu.Lock()
|
||||
c.hash.Add(name)
|
||||
c.shards[name] = &ringShard{Client: cl}
|
||||
c.mu.Unlock()
|
||||
info := c.cmdsInfo[name]
|
||||
if info == nil {
|
||||
internal.Logf("info for cmd=%s not found", name)
|
||||
}
|
||||
return info
|
||||
}
|
||||
|
||||
func (c *Ring) shardByKey(key string) (*ringShard, error) {
|
||||
|
|
@ -305,7 +343,7 @@ func (c *Ring) shardByName(name string) (*ringShard, error) {
|
|||
|
||||
func (c *Ring) cmdShard(cmd Cmder) (*ringShard, error) {
|
||||
cmdInfo := c.cmdInfo(cmd.Name())
|
||||
firstKey := cmd.arg(cmdFirstKeyPos(cmd, cmdInfo))
|
||||
firstKey := cmd.stringArg(cmdFirstKeyPos(cmd, cmdInfo))
|
||||
return c.shardByKey(firstKey)
|
||||
}
|
||||
|
||||
|
|
@ -346,7 +384,10 @@ func (c *Ring) heartbeat() {
|
|||
break
|
||||
}
|
||||
|
||||
for _, shard := range c.shards {
|
||||
shards := c.shardsList
|
||||
c.mu.RUnlock()
|
||||
|
||||
for _, shard := range shards {
|
||||
err := shard.Client.Ping().Err()
|
||||
if shard.Vote(err == nil || err == pool.ErrPoolTimeout) {
|
||||
internal.Logf("ring shard state changed: %s", shard)
|
||||
|
|
@ -354,8 +395,6 @@ func (c *Ring) heartbeat() {
|
|||
}
|
||||
}
|
||||
|
||||
c.mu.RUnlock()
|
||||
|
||||
if rebalance {
|
||||
c.rebalance()
|
||||
}
|
||||
|
|
@ -383,6 +422,7 @@ func (c *Ring) Close() error {
|
|||
}
|
||||
c.hash = nil
|
||||
c.shards = nil
|
||||
c.shardsList = nil
|
||||
|
||||
return firstErr
|
||||
}
|
||||
|
|
@ -396,51 +436,48 @@ func (c *Ring) Pipeline() Pipeliner {
|
|||
}
|
||||
|
||||
func (c *Ring) Pipelined(fn func(Pipeliner) error) ([]Cmder, error) {
|
||||
return c.Pipeline().pipelined(fn)
|
||||
return c.Pipeline().Pipelined(fn)
|
||||
}
|
||||
|
||||
func (c *Ring) pipelineExec(cmds []Cmder) (firstErr error) {
|
||||
func (c *Ring) pipelineExec(cmds []Cmder) error {
|
||||
cmdsMap := make(map[string][]Cmder)
|
||||
for _, cmd := range cmds {
|
||||
cmdInfo := c.cmdInfo(cmd.Name())
|
||||
name := cmd.arg(cmdFirstKeyPos(cmd, cmdInfo))
|
||||
name := cmd.stringArg(cmdFirstKeyPos(cmd, cmdInfo))
|
||||
if name != "" {
|
||||
name = c.hash.Get(hashtag.Key(name))
|
||||
}
|
||||
cmdsMap[name] = append(cmdsMap[name], cmd)
|
||||
}
|
||||
|
||||
for i := 0; i <= c.opt.MaxRetries; i++ {
|
||||
for attempt := 0; attempt <= c.opt.MaxRetries; attempt++ {
|
||||
if attempt > 0 {
|
||||
time.Sleep(c.retryBackoff(attempt))
|
||||
}
|
||||
|
||||
var failedCmdsMap map[string][]Cmder
|
||||
|
||||
for name, cmds := range cmdsMap {
|
||||
shard, err := c.shardByName(name)
|
||||
if err != nil {
|
||||
setCmdsErr(cmds, err)
|
||||
if firstErr == nil {
|
||||
firstErr = err
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
cn, _, err := shard.Client.getConn()
|
||||
if err != nil {
|
||||
setCmdsErr(cmds, err)
|
||||
if firstErr == nil {
|
||||
firstErr = err
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
canRetry, err := shard.Client.pipelineProcessCmds(cn, cmds)
|
||||
shard.Client.releaseConn(cn, err)
|
||||
if err == nil {
|
||||
if err == nil || internal.IsRedisError(err) {
|
||||
_ = shard.Client.connPool.Put(cn)
|
||||
continue
|
||||
}
|
||||
if firstErr == nil {
|
||||
firstErr = err
|
||||
}
|
||||
if canRetry && internal.IsRetryableError(err) {
|
||||
_ = shard.Client.connPool.Remove(cn)
|
||||
|
||||
if canRetry && internal.IsRetryableError(err, true) {
|
||||
if failedCmdsMap == nil {
|
||||
failedCmdsMap = make(map[string][]Cmder)
|
||||
}
|
||||
|
|
@ -454,5 +491,13 @@ func (c *Ring) pipelineExec(cmds []Cmder) (firstErr error) {
|
|||
cmdsMap = failedCmdsMap
|
||||
}
|
||||
|
||||
return firstErr
|
||||
return firstCmdsErr(cmds)
|
||||
}
|
||||
|
||||
func (c *Ring) TxPipeline() Pipeliner {
|
||||
panic("not implemented")
|
||||
}
|
||||
|
||||
func (c *Ring) TxPipelined(fn func(Pipeliner) error) ([]Cmder, error) {
|
||||
panic("not implemented")
|
||||
}
|
||||
|
|
|
|||
6
vendor/github.com/go-redis/redis/sentinel.go
generated
vendored
6
vendor/github.com/go-redis/redis/sentinel.go
generated
vendored
|
|
@ -301,8 +301,10 @@ func (d *sentinelFailover) listen(sentinel *sentinelClient) {
|
|||
|
||||
msg, err := pubsub.ReceiveMessage()
|
||||
if err != nil {
|
||||
internal.Logf("sentinel: ReceiveMessage failed: %s", err)
|
||||
pubsub.Close()
|
||||
if err != pool.ErrClosed {
|
||||
internal.Logf("sentinel: ReceiveMessage failed: %s", err)
|
||||
pubsub.Close()
|
||||
}
|
||||
d.resetSentinel()
|
||||
return
|
||||
}
|
||||
|
|
|
|||
23
vendor/github.com/go-redis/redis/tx.go
generated
vendored
23
vendor/github.com/go-redis/redis/tx.go
generated
vendored
|
|
@ -36,11 +36,10 @@ func (c *Client) Watch(fn func(*Tx) error, keys ...string) error {
|
|||
return err
|
||||
}
|
||||
}
|
||||
firstErr := fn(tx)
|
||||
if err := tx.Close(); err != nil && firstErr == nil {
|
||||
firstErr = err
|
||||
}
|
||||
return firstErr
|
||||
|
||||
err := fn(tx)
|
||||
_ = tx.Close()
|
||||
return err
|
||||
}
|
||||
|
||||
// close closes the transaction, releasing any open resources.
|
||||
|
|
@ -53,7 +52,7 @@ func (c *Tx) Close() error {
|
|||
// of a transaction.
|
||||
func (c *Tx) Watch(keys ...string) *StatusCmd {
|
||||
args := make([]interface{}, 1+len(keys))
|
||||
args[0] = "WATCH"
|
||||
args[0] = "watch"
|
||||
for i, key := range keys {
|
||||
args[1+i] = key
|
||||
}
|
||||
|
|
@ -65,7 +64,7 @@ func (c *Tx) Watch(keys ...string) *StatusCmd {
|
|||
// Unwatch flushes all the previously watched keys for a transaction.
|
||||
func (c *Tx) Unwatch(keys ...string) *StatusCmd {
|
||||
args := make([]interface{}, 1+len(keys))
|
||||
args[0] = "UNWATCH"
|
||||
args[0] = "unwatch"
|
||||
for i, key := range keys {
|
||||
args[1+i] = key
|
||||
}
|
||||
|
|
@ -92,5 +91,13 @@ func (c *Tx) Pipeline() Pipeliner {
|
|||
// TxFailedErr is returned. Otherwise Exec returns error of the first
|
||||
// failed command or nil.
|
||||
func (c *Tx) Pipelined(fn func(Pipeliner) error) ([]Cmder, error) {
|
||||
return c.Pipeline().pipelined(fn)
|
||||
return c.Pipeline().Pipelined(fn)
|
||||
}
|
||||
|
||||
func (c *Tx) TxPipelined(fn func(Pipeliner) error) ([]Cmder, error) {
|
||||
return c.Pipelined(fn)
|
||||
}
|
||||
|
||||
func (c *Tx) TxPipeline() Pipeliner {
|
||||
return c.Pipeline()
|
||||
}
|
||||
|
|
|
|||
7
vendor/github.com/go-redis/redis/universal.go
generated
vendored
7
vendor/github.com/go-redis/redis/universal.go
generated
vendored
|
|
@ -90,8 +90,8 @@ func (o *UniversalOptions) simple() *Options {
|
|||
}
|
||||
|
||||
return &Options{
|
||||
Addr: addr,
|
||||
DB: o.DB,
|
||||
Addr: addr,
|
||||
DB: o.DB,
|
||||
|
||||
MaxRetries: o.MaxRetries,
|
||||
Password: o.Password,
|
||||
|
|
@ -117,6 +117,9 @@ type UniversalClient interface {
|
|||
Close() error
|
||||
}
|
||||
|
||||
var _ UniversalClient = (*Client)(nil)
|
||||
var _ UniversalClient = (*ClusterClient)(nil)
|
||||
|
||||
// NewUniversalClient returns a new multi client. The type of client returned depends
|
||||
// on the following three conditions:
|
||||
//
|
||||
|
|
|
|||
1
vendor/github.com/golang/protobuf/.travis.yml
generated
vendored
1
vendor/github.com/golang/protobuf/.travis.yml
generated
vendored
|
|
@ -4,6 +4,7 @@ go:
|
|||
- 1.6.x
|
||||
- 1.7.x
|
||||
- 1.8.x
|
||||
- 1.9.x
|
||||
|
||||
install:
|
||||
- go get -v -d -t github.com/golang/protobuf/...
|
||||
|
|
|
|||
1
vendor/github.com/golang/protobuf/README.md
generated
vendored
1
vendor/github.com/golang/protobuf/README.md
generated
vendored
|
|
@ -111,6 +111,7 @@ When the .proto file specifies `syntax="proto3"`, there are some differences:
|
|||
Consider file test.proto, containing
|
||||
|
||||
```proto
|
||||
syntax = "proto2";
|
||||
package example;
|
||||
|
||||
enum FOO { X = 17; };
|
||||
|
|
|
|||
66
vendor/github.com/golang/protobuf/jsonpb/jsonpb.go
generated
vendored
66
vendor/github.com/golang/protobuf/jsonpb/jsonpb.go
generated
vendored
|
|
@ -73,6 +73,31 @@ type Marshaler struct {
|
|||
|
||||
// Whether to use the original (.proto) name for fields.
|
||||
OrigName bool
|
||||
|
||||
// A custom URL resolver to use when marshaling Any messages to JSON.
|
||||
// If unset, the default resolution strategy is to extract the
|
||||
// fully-qualified type name from the type URL and pass that to
|
||||
// proto.MessageType(string).
|
||||
AnyResolver AnyResolver
|
||||
}
|
||||
|
||||
// AnyResolver takes a type URL, present in an Any message, and resolves it into
|
||||
// an instance of the associated message.
|
||||
type AnyResolver interface {
|
||||
Resolve(typeUrl string) (proto.Message, error)
|
||||
}
|
||||
|
||||
func defaultResolveAny(typeUrl string) (proto.Message, error) {
|
||||
// Only the part of typeUrl after the last slash is relevant.
|
||||
mname := typeUrl
|
||||
if slash := strings.LastIndex(mname, "/"); slash >= 0 {
|
||||
mname = mname[slash+1:]
|
||||
}
|
||||
mt := proto.MessageType(mname)
|
||||
if mt == nil {
|
||||
return nil, fmt.Errorf("unknown message type %q", mname)
|
||||
}
|
||||
return reflect.New(mt.Elem()).Interface().(proto.Message), nil
|
||||
}
|
||||
|
||||
// JSONPBMarshaler is implemented by protobuf messages that customize the
|
||||
|
|
@ -344,16 +369,17 @@ func (m *Marshaler) marshalAny(out *errWriter, any proto.Message, indent string)
|
|||
turl := v.Field(0).String()
|
||||
val := v.Field(1).Bytes()
|
||||
|
||||
// Only the part of type_url after the last slash is relevant.
|
||||
mname := turl
|
||||
if slash := strings.LastIndex(mname, "/"); slash >= 0 {
|
||||
mname = mname[slash+1:]
|
||||
var msg proto.Message
|
||||
var err error
|
||||
if m.AnyResolver != nil {
|
||||
msg, err = m.AnyResolver.Resolve(turl)
|
||||
} else {
|
||||
msg, err = defaultResolveAny(turl)
|
||||
}
|
||||
mt := proto.MessageType(mname)
|
||||
if mt == nil {
|
||||
return fmt.Errorf("unknown message type %q", mname)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
msg := reflect.New(mt.Elem()).Interface().(proto.Message)
|
||||
|
||||
if err := proto.Unmarshal(val, msg); err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
@ -590,6 +616,12 @@ type Unmarshaler struct {
|
|||
// Whether to allow messages to contain unknown fields, as opposed to
|
||||
// failing to unmarshal.
|
||||
AllowUnknownFields bool
|
||||
|
||||
// A custom URL resolver to use when unmarshaling Any messages from JSON.
|
||||
// If unset, the default resolution strategy is to extract the
|
||||
// fully-qualified type name from the type URL and pass that to
|
||||
// proto.MessageType(string).
|
||||
AnyResolver AnyResolver
|
||||
}
|
||||
|
||||
// UnmarshalNext unmarshals the next protocol buffer from a JSON object stream.
|
||||
|
|
@ -641,7 +673,8 @@ func (u *Unmarshaler) unmarshalValue(target reflect.Value, inputValue json.RawMe
|
|||
if targetType.Kind() == reflect.Ptr {
|
||||
// If input value is "null" and target is a pointer type, then the field should be treated as not set
|
||||
// UNLESS the target is structpb.Value, in which case it should be set to structpb.NullValue.
|
||||
if string(inputValue) == "null" && targetType != reflect.TypeOf(&stpb.Value{}) {
|
||||
_, isJSONPBUnmarshaler := target.Interface().(JSONPBUnmarshaler)
|
||||
if string(inputValue) == "null" && targetType != reflect.TypeOf(&stpb.Value{}) && !isJSONPBUnmarshaler {
|
||||
return nil
|
||||
}
|
||||
target.Set(reflect.New(targetType.Elem()))
|
||||
|
|
@ -679,16 +712,17 @@ func (u *Unmarshaler) unmarshalValue(target reflect.Value, inputValue json.RawMe
|
|||
}
|
||||
target.Field(0).SetString(turl)
|
||||
|
||||
mname := turl
|
||||
if slash := strings.LastIndex(mname, "/"); slash >= 0 {
|
||||
mname = mname[slash+1:]
|
||||
var m proto.Message
|
||||
var err error
|
||||
if u.AnyResolver != nil {
|
||||
m, err = u.AnyResolver.Resolve(turl)
|
||||
} else {
|
||||
m, err = defaultResolveAny(turl)
|
||||
}
|
||||
mt := proto.MessageType(mname)
|
||||
if mt == nil {
|
||||
return fmt.Errorf("unknown message type %q", mname)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
m := reflect.New(mt.Elem()).Interface().(proto.Message)
|
||||
if _, ok := m.(wkt); ok {
|
||||
val, ok := jsonFields["value"]
|
||||
if !ok {
|
||||
|
|
|
|||
107
vendor/github.com/golang/protobuf/jsonpb/jsonpb_test.go
generated
vendored
107
vendor/github.com/golang/protobuf/jsonpb/jsonpb_test.go
generated
vendored
|
|
@ -721,6 +721,65 @@ func TestUnmarshalingBadInput(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
type funcResolver func(turl string) (proto.Message, error)
|
||||
|
||||
func (fn funcResolver) Resolve(turl string) (proto.Message, error) {
|
||||
return fn(turl)
|
||||
}
|
||||
|
||||
func TestAnyWithCustomResolver(t *testing.T) {
|
||||
var resolvedTypeUrls []string
|
||||
resolver := funcResolver(func(turl string) (proto.Message, error) {
|
||||
resolvedTypeUrls = append(resolvedTypeUrls, turl)
|
||||
return new(pb.Simple), nil
|
||||
})
|
||||
msg := &pb.Simple{
|
||||
OBytes: []byte{1, 2, 3, 4},
|
||||
OBool: proto.Bool(true),
|
||||
OString: proto.String("foobar"),
|
||||
OInt64: proto.Int64(1020304),
|
||||
}
|
||||
msgBytes, err := proto.Marshal(msg)
|
||||
if err != nil {
|
||||
t.Errorf("an unexpected error occurred when marshaling message: %v", err)
|
||||
}
|
||||
// make an Any with a type URL that won't resolve w/out custom resolver
|
||||
any := &anypb.Any{
|
||||
TypeUrl: "https://foobar.com/some.random.MessageKind",
|
||||
Value: msgBytes,
|
||||
}
|
||||
|
||||
m := Marshaler{AnyResolver: resolver}
|
||||
js, err := m.MarshalToString(any)
|
||||
if err != nil {
|
||||
t.Errorf("an unexpected error occurred when marshaling any to JSON: %v", err)
|
||||
}
|
||||
if len(resolvedTypeUrls) != 1 {
|
||||
t.Errorf("custom resolver was not invoked during marshaling")
|
||||
} else if resolvedTypeUrls[0] != "https://foobar.com/some.random.MessageKind" {
|
||||
t.Errorf("custom resolver was invoked with wrong URL: got %q, wanted %q", resolvedTypeUrls[0], "https://foobar.com/some.random.MessageKind")
|
||||
}
|
||||
wanted := `{"@type":"https://foobar.com/some.random.MessageKind","oBool":true,"oInt64":"1020304","oString":"foobar","oBytes":"AQIDBA=="}`
|
||||
if js != wanted {
|
||||
t.Errorf("marshalling JSON produced incorrect output: got %s, wanted %s", js, wanted)
|
||||
}
|
||||
|
||||
u := Unmarshaler{AnyResolver: resolver}
|
||||
roundTrip := &anypb.Any{}
|
||||
err = u.Unmarshal(bytes.NewReader([]byte(js)), roundTrip)
|
||||
if err != nil {
|
||||
t.Errorf("an unexpected error occurred when unmarshaling any from JSON: %v", err)
|
||||
}
|
||||
if len(resolvedTypeUrls) != 2 {
|
||||
t.Errorf("custom resolver was not invoked during marshaling")
|
||||
} else if resolvedTypeUrls[1] != "https://foobar.com/some.random.MessageKind" {
|
||||
t.Errorf("custom resolver was invoked with wrong URL: got %q, wanted %q", resolvedTypeUrls[1], "https://foobar.com/some.random.MessageKind")
|
||||
}
|
||||
if !proto.Equal(any, roundTrip) {
|
||||
t.Errorf("message contents not set correctly after unmarshalling JSON: got %s, wanted %s", roundTrip, any)
|
||||
}
|
||||
}
|
||||
|
||||
func TestUnmarshalJSONPBUnmarshaler(t *testing.T) {
|
||||
rawJson := `{ "foo": "bar", "baz": [0, 1, 2, 3] }`
|
||||
var msg dynamicMessage
|
||||
|
|
@ -732,6 +791,19 @@ func TestUnmarshalJSONPBUnmarshaler(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestUnmarshalNullWithJSONPBUnmarshaler(t *testing.T) {
|
||||
rawJson := `{"stringField":null}`
|
||||
var ptrFieldMsg ptrFieldMessage
|
||||
if err := Unmarshal(strings.NewReader(rawJson), &ptrFieldMsg); err != nil {
|
||||
t.Errorf("unmarshal error: %v", err)
|
||||
}
|
||||
|
||||
want := ptrFieldMessage{StringField: &stringField{IsSet: true, StringValue: "null"}}
|
||||
if !proto.Equal(&ptrFieldMsg, &want) {
|
||||
t.Errorf("unmarshal result StringField: got %v, want %v", ptrFieldMsg, want)
|
||||
}
|
||||
}
|
||||
|
||||
func TestUnmarshalAnyJSONPBUnmarshaler(t *testing.T) {
|
||||
rawJson := `{ "@type": "blah.com/` + dynamicMessageName + `", "foo": "bar", "baz": [0, 1, 2, 3] }`
|
||||
var got anypb.Any
|
||||
|
|
@ -762,6 +834,41 @@ func init() {
|
|||
proto.RegisterType((*dynamicMessage)(nil), dynamicMessageName)
|
||||
}
|
||||
|
||||
type ptrFieldMessage struct {
|
||||
StringField *stringField `protobuf:"bytes,1,opt,name=stringField"`
|
||||
}
|
||||
|
||||
func (m *ptrFieldMessage) Reset() {
|
||||
}
|
||||
|
||||
func (m *ptrFieldMessage) String() string {
|
||||
return m.StringField.StringValue
|
||||
}
|
||||
|
||||
func (m *ptrFieldMessage) ProtoMessage() {
|
||||
}
|
||||
|
||||
type stringField struct {
|
||||
IsSet bool `protobuf:"varint,1,opt,name=isSet"`
|
||||
StringValue string `protobuf:"bytes,2,opt,name=stringValue"`
|
||||
}
|
||||
|
||||
func (s *stringField) Reset() {
|
||||
}
|
||||
|
||||
func (s *stringField) String() string {
|
||||
return s.StringValue
|
||||
}
|
||||
|
||||
func (s *stringField) ProtoMessage() {
|
||||
}
|
||||
|
||||
func (s *stringField) UnmarshalJSONPB(jum *Unmarshaler, js []byte) error {
|
||||
s.IsSet = true
|
||||
s.StringValue = string(js)
|
||||
return nil
|
||||
}
|
||||
|
||||
// dynamicMessage implements protobuf.Message but is not a normal generated message type.
|
||||
// It provides implementations of JSONPBMarshaler and JSONPBUnmarshaler for JSON support.
|
||||
type dynamicMessage struct {
|
||||
|
|
|
|||
425
vendor/github.com/golang/protobuf/protoc-gen-go/descriptor/descriptor.pb.go
generated
vendored
425
vendor/github.com/golang/protobuf/protoc-gen-go/descriptor/descriptor.pb.go
generated
vendored
|
|
@ -11,6 +11,7 @@ It has these top-level messages:
|
|||
FileDescriptorSet
|
||||
FileDescriptorProto
|
||||
DescriptorProto
|
||||
ExtensionRangeOptions
|
||||
FieldDescriptorProto
|
||||
OneofDescriptorProto
|
||||
EnumDescriptorProto
|
||||
|
|
@ -137,7 +138,7 @@ func (x *FieldDescriptorProto_Type) UnmarshalJSON(data []byte) error {
|
|||
*x = FieldDescriptorProto_Type(value)
|
||||
return nil
|
||||
}
|
||||
func (FieldDescriptorProto_Type) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{3, 0} }
|
||||
func (FieldDescriptorProto_Type) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{4, 0} }
|
||||
|
||||
type FieldDescriptorProto_Label int32
|
||||
|
||||
|
|
@ -176,7 +177,7 @@ func (x *FieldDescriptorProto_Label) UnmarshalJSON(data []byte) error {
|
|||
return nil
|
||||
}
|
||||
func (FieldDescriptorProto_Label) EnumDescriptor() ([]byte, []int) {
|
||||
return fileDescriptor0, []int{3, 1}
|
||||
return fileDescriptor0, []int{4, 1}
|
||||
}
|
||||
|
||||
// Generated classes can be optimized for speed or code size.
|
||||
|
|
@ -216,7 +217,7 @@ func (x *FileOptions_OptimizeMode) UnmarshalJSON(data []byte) error {
|
|||
*x = FileOptions_OptimizeMode(value)
|
||||
return nil
|
||||
}
|
||||
func (FileOptions_OptimizeMode) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{9, 0} }
|
||||
func (FileOptions_OptimizeMode) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{10, 0} }
|
||||
|
||||
type FieldOptions_CType int32
|
||||
|
||||
|
|
@ -254,7 +255,7 @@ func (x *FieldOptions_CType) UnmarshalJSON(data []byte) error {
|
|||
*x = FieldOptions_CType(value)
|
||||
return nil
|
||||
}
|
||||
func (FieldOptions_CType) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{11, 0} }
|
||||
func (FieldOptions_CType) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{12, 0} }
|
||||
|
||||
type FieldOptions_JSType int32
|
||||
|
||||
|
|
@ -294,7 +295,7 @@ func (x *FieldOptions_JSType) UnmarshalJSON(data []byte) error {
|
|||
*x = FieldOptions_JSType(value)
|
||||
return nil
|
||||
}
|
||||
func (FieldOptions_JSType) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{11, 1} }
|
||||
func (FieldOptions_JSType) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{12, 1} }
|
||||
|
||||
// Is this method side-effect-free (or safe in HTTP parlance), or idempotent,
|
||||
// or neither? HTTP based RPC implementation may choose GET verb for safe
|
||||
|
|
@ -335,7 +336,7 @@ func (x *MethodOptions_IdempotencyLevel) UnmarshalJSON(data []byte) error {
|
|||
return nil
|
||||
}
|
||||
func (MethodOptions_IdempotencyLevel) EnumDescriptor() ([]byte, []int) {
|
||||
return fileDescriptor0, []int{16, 0}
|
||||
return fileDescriptor0, []int{17, 0}
|
||||
}
|
||||
|
||||
// The protocol compiler can output a FileDescriptorSet containing the .proto
|
||||
|
|
@ -567,9 +568,10 @@ func (m *DescriptorProto) GetReservedName() []string {
|
|||
}
|
||||
|
||||
type DescriptorProto_ExtensionRange struct {
|
||||
Start *int32 `protobuf:"varint,1,opt,name=start" json:"start,omitempty"`
|
||||
End *int32 `protobuf:"varint,2,opt,name=end" json:"end,omitempty"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
Start *int32 `protobuf:"varint,1,opt,name=start" json:"start,omitempty"`
|
||||
End *int32 `protobuf:"varint,2,opt,name=end" json:"end,omitempty"`
|
||||
Options *ExtensionRangeOptions `protobuf:"bytes,3,opt,name=options" json:"options,omitempty"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
}
|
||||
|
||||
func (m *DescriptorProto_ExtensionRange) Reset() { *m = DescriptorProto_ExtensionRange{} }
|
||||
|
|
@ -593,6 +595,13 @@ func (m *DescriptorProto_ExtensionRange) GetEnd() int32 {
|
|||
return 0
|
||||
}
|
||||
|
||||
func (m *DescriptorProto_ExtensionRange) GetOptions() *ExtensionRangeOptions {
|
||||
if m != nil {
|
||||
return m.Options
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Range of reserved tag numbers. Reserved tag numbers may not be used by
|
||||
// fields or extension ranges in the same message. Reserved ranges may
|
||||
// not overlap.
|
||||
|
|
@ -623,6 +632,33 @@ func (m *DescriptorProto_ReservedRange) GetEnd() int32 {
|
|||
return 0
|
||||
}
|
||||
|
||||
type ExtensionRangeOptions struct {
|
||||
// The parser stores options it doesn't recognize here. See above.
|
||||
UninterpretedOption []*UninterpretedOption `protobuf:"bytes,999,rep,name=uninterpreted_option,json=uninterpretedOption" json:"uninterpreted_option,omitempty"`
|
||||
proto.XXX_InternalExtensions `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
}
|
||||
|
||||
func (m *ExtensionRangeOptions) Reset() { *m = ExtensionRangeOptions{} }
|
||||
func (m *ExtensionRangeOptions) String() string { return proto.CompactTextString(m) }
|
||||
func (*ExtensionRangeOptions) ProtoMessage() {}
|
||||
func (*ExtensionRangeOptions) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{3} }
|
||||
|
||||
var extRange_ExtensionRangeOptions = []proto.ExtensionRange{
|
||||
{1000, 536870911},
|
||||
}
|
||||
|
||||
func (*ExtensionRangeOptions) ExtensionRangeArray() []proto.ExtensionRange {
|
||||
return extRange_ExtensionRangeOptions
|
||||
}
|
||||
|
||||
func (m *ExtensionRangeOptions) GetUninterpretedOption() []*UninterpretedOption {
|
||||
if m != nil {
|
||||
return m.UninterpretedOption
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Describes a field within a message.
|
||||
type FieldDescriptorProto struct {
|
||||
Name *string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"`
|
||||
|
|
@ -661,7 +697,7 @@ type FieldDescriptorProto struct {
|
|||
func (m *FieldDescriptorProto) Reset() { *m = FieldDescriptorProto{} }
|
||||
func (m *FieldDescriptorProto) String() string { return proto.CompactTextString(m) }
|
||||
func (*FieldDescriptorProto) ProtoMessage() {}
|
||||
func (*FieldDescriptorProto) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{3} }
|
||||
func (*FieldDescriptorProto) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{4} }
|
||||
|
||||
func (m *FieldDescriptorProto) GetName() string {
|
||||
if m != nil && m.Name != nil {
|
||||
|
|
@ -743,7 +779,7 @@ type OneofDescriptorProto struct {
|
|||
func (m *OneofDescriptorProto) Reset() { *m = OneofDescriptorProto{} }
|
||||
func (m *OneofDescriptorProto) String() string { return proto.CompactTextString(m) }
|
||||
func (*OneofDescriptorProto) ProtoMessage() {}
|
||||
func (*OneofDescriptorProto) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{4} }
|
||||
func (*OneofDescriptorProto) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{5} }
|
||||
|
||||
func (m *OneofDescriptorProto) GetName() string {
|
||||
if m != nil && m.Name != nil {
|
||||
|
|
@ -770,7 +806,7 @@ type EnumDescriptorProto struct {
|
|||
func (m *EnumDescriptorProto) Reset() { *m = EnumDescriptorProto{} }
|
||||
func (m *EnumDescriptorProto) String() string { return proto.CompactTextString(m) }
|
||||
func (*EnumDescriptorProto) ProtoMessage() {}
|
||||
func (*EnumDescriptorProto) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{5} }
|
||||
func (*EnumDescriptorProto) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{6} }
|
||||
|
||||
func (m *EnumDescriptorProto) GetName() string {
|
||||
if m != nil && m.Name != nil {
|
||||
|
|
@ -804,7 +840,7 @@ type EnumValueDescriptorProto struct {
|
|||
func (m *EnumValueDescriptorProto) Reset() { *m = EnumValueDescriptorProto{} }
|
||||
func (m *EnumValueDescriptorProto) String() string { return proto.CompactTextString(m) }
|
||||
func (*EnumValueDescriptorProto) ProtoMessage() {}
|
||||
func (*EnumValueDescriptorProto) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{6} }
|
||||
func (*EnumValueDescriptorProto) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{7} }
|
||||
|
||||
func (m *EnumValueDescriptorProto) GetName() string {
|
||||
if m != nil && m.Name != nil {
|
||||
|
|
@ -838,7 +874,7 @@ type ServiceDescriptorProto struct {
|
|||
func (m *ServiceDescriptorProto) Reset() { *m = ServiceDescriptorProto{} }
|
||||
func (m *ServiceDescriptorProto) String() string { return proto.CompactTextString(m) }
|
||||
func (*ServiceDescriptorProto) ProtoMessage() {}
|
||||
func (*ServiceDescriptorProto) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{7} }
|
||||
func (*ServiceDescriptorProto) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{8} }
|
||||
|
||||
func (m *ServiceDescriptorProto) GetName() string {
|
||||
if m != nil && m.Name != nil {
|
||||
|
|
@ -879,7 +915,7 @@ type MethodDescriptorProto struct {
|
|||
func (m *MethodDescriptorProto) Reset() { *m = MethodDescriptorProto{} }
|
||||
func (m *MethodDescriptorProto) String() string { return proto.CompactTextString(m) }
|
||||
func (*MethodDescriptorProto) ProtoMessage() {}
|
||||
func (*MethodDescriptorProto) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{8} }
|
||||
func (*MethodDescriptorProto) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{9} }
|
||||
|
||||
const Default_MethodDescriptorProto_ClientStreaming bool = false
|
||||
const Default_MethodDescriptorProto_ServerStreaming bool = false
|
||||
|
|
@ -974,7 +1010,7 @@ type FileOptions struct {
|
|||
CcGenericServices *bool `protobuf:"varint,16,opt,name=cc_generic_services,json=ccGenericServices,def=0" json:"cc_generic_services,omitempty"`
|
||||
JavaGenericServices *bool `protobuf:"varint,17,opt,name=java_generic_services,json=javaGenericServices,def=0" json:"java_generic_services,omitempty"`
|
||||
PyGenericServices *bool `protobuf:"varint,18,opt,name=py_generic_services,json=pyGenericServices,def=0" json:"py_generic_services,omitempty"`
|
||||
PhpGenericServices *bool `protobuf:"varint,19,opt,name=php_generic_services,json=phpGenericServices,def=0" json:"php_generic_services,omitempty"`
|
||||
PhpGenericServices *bool `protobuf:"varint,42,opt,name=php_generic_services,json=phpGenericServices,def=0" json:"php_generic_services,omitempty"`
|
||||
// Is this file deprecated?
|
||||
// Depending on the target platform, this can emit Deprecated annotations
|
||||
// for everything in the file, or it will be completely ignored; in the very
|
||||
|
|
@ -1009,7 +1045,7 @@ type FileOptions struct {
|
|||
func (m *FileOptions) Reset() { *m = FileOptions{} }
|
||||
func (m *FileOptions) String() string { return proto.CompactTextString(m) }
|
||||
func (*FileOptions) ProtoMessage() {}
|
||||
func (*FileOptions) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{9} }
|
||||
func (*FileOptions) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{10} }
|
||||
|
||||
var extRange_FileOptions = []proto.ExtensionRange{
|
||||
{1000, 536870911},
|
||||
|
|
@ -1222,7 +1258,7 @@ type MessageOptions struct {
|
|||
func (m *MessageOptions) Reset() { *m = MessageOptions{} }
|
||||
func (m *MessageOptions) String() string { return proto.CompactTextString(m) }
|
||||
func (*MessageOptions) ProtoMessage() {}
|
||||
func (*MessageOptions) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{10} }
|
||||
func (*MessageOptions) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{11} }
|
||||
|
||||
var extRange_MessageOptions = []proto.ExtensionRange{
|
||||
{1000, 536870911},
|
||||
|
|
@ -1285,13 +1321,15 @@ type FieldOptions struct {
|
|||
Packed *bool `protobuf:"varint,2,opt,name=packed" json:"packed,omitempty"`
|
||||
// The jstype option determines the JavaScript type used for values of the
|
||||
// field. The option is permitted only for 64 bit integral and fixed types
|
||||
// (int64, uint64, sint64, fixed64, sfixed64). By default these types are
|
||||
// represented as JavaScript strings. This avoids loss of precision that can
|
||||
// happen when a large value is converted to a floating point JavaScript
|
||||
// numbers. Specifying JS_NUMBER for the jstype causes the generated
|
||||
// JavaScript code to use the JavaScript "number" type instead of strings.
|
||||
// This option is an enum to permit additional types to be added,
|
||||
// e.g. goog.math.Integer.
|
||||
// (int64, uint64, sint64, fixed64, sfixed64). A field with jstype JS_STRING
|
||||
// is represented as JavaScript string, which avoids loss of precision that
|
||||
// can happen when a large value is converted to a floating point JavaScript.
|
||||
// Specifying JS_NUMBER for the jstype causes the generated JavaScript code to
|
||||
// use the JavaScript "number" type. The behavior of the default option
|
||||
// JS_NORMAL is implementation dependent.
|
||||
//
|
||||
// This option is an enum to permit additional types to be added, e.g.
|
||||
// goog.math.Integer.
|
||||
Jstype *FieldOptions_JSType `protobuf:"varint,6,opt,name=jstype,enum=google.protobuf.FieldOptions_JSType,def=0" json:"jstype,omitempty"`
|
||||
// Should this field be parsed lazily? Lazy applies only to message-type
|
||||
// fields. It means that when the outer message is initially parsed, the
|
||||
|
|
@ -1338,7 +1376,7 @@ type FieldOptions struct {
|
|||
func (m *FieldOptions) Reset() { *m = FieldOptions{} }
|
||||
func (m *FieldOptions) String() string { return proto.CompactTextString(m) }
|
||||
func (*FieldOptions) ProtoMessage() {}
|
||||
func (*FieldOptions) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{11} }
|
||||
func (*FieldOptions) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{12} }
|
||||
|
||||
var extRange_FieldOptions = []proto.ExtensionRange{
|
||||
{1000, 536870911},
|
||||
|
|
@ -1413,7 +1451,7 @@ type OneofOptions struct {
|
|||
func (m *OneofOptions) Reset() { *m = OneofOptions{} }
|
||||
func (m *OneofOptions) String() string { return proto.CompactTextString(m) }
|
||||
func (*OneofOptions) ProtoMessage() {}
|
||||
func (*OneofOptions) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{12} }
|
||||
func (*OneofOptions) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{13} }
|
||||
|
||||
var extRange_OneofOptions = []proto.ExtensionRange{
|
||||
{1000, 536870911},
|
||||
|
|
@ -1448,7 +1486,7 @@ type EnumOptions struct {
|
|||
func (m *EnumOptions) Reset() { *m = EnumOptions{} }
|
||||
func (m *EnumOptions) String() string { return proto.CompactTextString(m) }
|
||||
func (*EnumOptions) ProtoMessage() {}
|
||||
func (*EnumOptions) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{13} }
|
||||
func (*EnumOptions) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{14} }
|
||||
|
||||
var extRange_EnumOptions = []proto.ExtensionRange{
|
||||
{1000, 536870911},
|
||||
|
|
@ -1496,7 +1534,7 @@ type EnumValueOptions struct {
|
|||
func (m *EnumValueOptions) Reset() { *m = EnumValueOptions{} }
|
||||
func (m *EnumValueOptions) String() string { return proto.CompactTextString(m) }
|
||||
func (*EnumValueOptions) ProtoMessage() {}
|
||||
func (*EnumValueOptions) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{14} }
|
||||
func (*EnumValueOptions) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{15} }
|
||||
|
||||
var extRange_EnumValueOptions = []proto.ExtensionRange{
|
||||
{1000, 536870911},
|
||||
|
|
@ -1537,7 +1575,7 @@ type ServiceOptions struct {
|
|||
func (m *ServiceOptions) Reset() { *m = ServiceOptions{} }
|
||||
func (m *ServiceOptions) String() string { return proto.CompactTextString(m) }
|
||||
func (*ServiceOptions) ProtoMessage() {}
|
||||
func (*ServiceOptions) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{15} }
|
||||
func (*ServiceOptions) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{16} }
|
||||
|
||||
var extRange_ServiceOptions = []proto.ExtensionRange{
|
||||
{1000, 536870911},
|
||||
|
|
@ -1579,7 +1617,7 @@ type MethodOptions struct {
|
|||
func (m *MethodOptions) Reset() { *m = MethodOptions{} }
|
||||
func (m *MethodOptions) String() string { return proto.CompactTextString(m) }
|
||||
func (*MethodOptions) ProtoMessage() {}
|
||||
func (*MethodOptions) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{16} }
|
||||
func (*MethodOptions) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{17} }
|
||||
|
||||
var extRange_MethodOptions = []proto.ExtensionRange{
|
||||
{1000, 536870911},
|
||||
|
|
@ -1635,7 +1673,7 @@ type UninterpretedOption struct {
|
|||
func (m *UninterpretedOption) Reset() { *m = UninterpretedOption{} }
|
||||
func (m *UninterpretedOption) String() string { return proto.CompactTextString(m) }
|
||||
func (*UninterpretedOption) ProtoMessage() {}
|
||||
func (*UninterpretedOption) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{17} }
|
||||
func (*UninterpretedOption) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{18} }
|
||||
|
||||
func (m *UninterpretedOption) GetName() []*UninterpretedOption_NamePart {
|
||||
if m != nil {
|
||||
|
|
@ -1701,7 +1739,7 @@ func (m *UninterpretedOption_NamePart) Reset() { *m = UninterpretedOptio
|
|||
func (m *UninterpretedOption_NamePart) String() string { return proto.CompactTextString(m) }
|
||||
func (*UninterpretedOption_NamePart) ProtoMessage() {}
|
||||
func (*UninterpretedOption_NamePart) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor0, []int{17, 0}
|
||||
return fileDescriptor0, []int{18, 0}
|
||||
}
|
||||
|
||||
func (m *UninterpretedOption_NamePart) GetNamePart() string {
|
||||
|
|
@ -1771,7 +1809,7 @@ type SourceCodeInfo struct {
|
|||
func (m *SourceCodeInfo) Reset() { *m = SourceCodeInfo{} }
|
||||
func (m *SourceCodeInfo) String() string { return proto.CompactTextString(m) }
|
||||
func (*SourceCodeInfo) ProtoMessage() {}
|
||||
func (*SourceCodeInfo) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{18} }
|
||||
func (*SourceCodeInfo) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{19} }
|
||||
|
||||
func (m *SourceCodeInfo) GetLocation() []*SourceCodeInfo_Location {
|
||||
if m != nil {
|
||||
|
|
@ -1867,7 +1905,7 @@ type SourceCodeInfo_Location struct {
|
|||
func (m *SourceCodeInfo_Location) Reset() { *m = SourceCodeInfo_Location{} }
|
||||
func (m *SourceCodeInfo_Location) String() string { return proto.CompactTextString(m) }
|
||||
func (*SourceCodeInfo_Location) ProtoMessage() {}
|
||||
func (*SourceCodeInfo_Location) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{18, 0} }
|
||||
func (*SourceCodeInfo_Location) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{19, 0} }
|
||||
|
||||
func (m *SourceCodeInfo_Location) GetPath() []int32 {
|
||||
if m != nil {
|
||||
|
|
@ -1917,7 +1955,7 @@ type GeneratedCodeInfo struct {
|
|||
func (m *GeneratedCodeInfo) Reset() { *m = GeneratedCodeInfo{} }
|
||||
func (m *GeneratedCodeInfo) String() string { return proto.CompactTextString(m) }
|
||||
func (*GeneratedCodeInfo) ProtoMessage() {}
|
||||
func (*GeneratedCodeInfo) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{19} }
|
||||
func (*GeneratedCodeInfo) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{20} }
|
||||
|
||||
func (m *GeneratedCodeInfo) GetAnnotation() []*GeneratedCodeInfo_Annotation {
|
||||
if m != nil {
|
||||
|
|
@ -1946,7 +1984,7 @@ func (m *GeneratedCodeInfo_Annotation) Reset() { *m = GeneratedCodeInfo_
|
|||
func (m *GeneratedCodeInfo_Annotation) String() string { return proto.CompactTextString(m) }
|
||||
func (*GeneratedCodeInfo_Annotation) ProtoMessage() {}
|
||||
func (*GeneratedCodeInfo_Annotation) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor0, []int{19, 0}
|
||||
return fileDescriptor0, []int{20, 0}
|
||||
}
|
||||
|
||||
func (m *GeneratedCodeInfo_Annotation) GetPath() []int32 {
|
||||
|
|
@ -1983,6 +2021,7 @@ func init() {
|
|||
proto.RegisterType((*DescriptorProto)(nil), "google.protobuf.DescriptorProto")
|
||||
proto.RegisterType((*DescriptorProto_ExtensionRange)(nil), "google.protobuf.DescriptorProto.ExtensionRange")
|
||||
proto.RegisterType((*DescriptorProto_ReservedRange)(nil), "google.protobuf.DescriptorProto.ReservedRange")
|
||||
proto.RegisterType((*ExtensionRangeOptions)(nil), "google.protobuf.ExtensionRangeOptions")
|
||||
proto.RegisterType((*FieldDescriptorProto)(nil), "google.protobuf.FieldDescriptorProto")
|
||||
proto.RegisterType((*OneofDescriptorProto)(nil), "google.protobuf.OneofDescriptorProto")
|
||||
proto.RegisterType((*EnumDescriptorProto)(nil), "google.protobuf.EnumDescriptorProto")
|
||||
|
|
@ -2014,161 +2053,163 @@ func init() {
|
|||
func init() { proto.RegisterFile("google/protobuf/descriptor.proto", fileDescriptor0) }
|
||||
|
||||
var fileDescriptor0 = []byte{
|
||||
// 2490 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xc4, 0x59, 0xdd, 0x8e, 0xdb, 0xc6,
|
||||
0x15, 0x8e, 0x7e, 0x57, 0x3a, 0xd2, 0x6a, 0x67, 0x67, 0x37, 0x36, 0xbd, 0xf9, 0xf1, 0x5a, 0xf9,
|
||||
0xf1, 0x3a, 0x69, 0xb4, 0xc1, 0xc6, 0x76, 0x9c, 0x4d, 0xe1, 0x42, 0x2b, 0xd1, 0x1b, 0xb9, 0x5a,
|
||||
0x49, 0xa5, 0xb4, 0x8d, 0x9d, 0x1b, 0x62, 0x96, 0x1c, 0x49, 0xb4, 0x29, 0x92, 0x21, 0x29, 0xdb,
|
||||
0x9b, 0x2b, 0x03, 0xbd, 0x2a, 0xd0, 0x07, 0x28, 0x8a, 0xa2, 0x17, 0xb9, 0x09, 0xd0, 0x07, 0x28,
|
||||
0xd0, 0xbb, 0x3e, 0x41, 0x81, 0xbc, 0x41, 0x51, 0x14, 0x68, 0xdf, 0xa0, 0xb7, 0xc5, 0xcc, 0x90,
|
||||
0x14, 0xa9, 0x1f, 0x7b, 0x1b, 0xc0, 0xc9, 0x95, 0x34, 0xdf, 0xf9, 0xce, 0x99, 0x33, 0x67, 0xce,
|
||||
0xcc, 0x9c, 0x19, 0xc2, 0xee, 0xc8, 0xb6, 0x47, 0x26, 0xdd, 0x77, 0x5c, 0xdb, 0xb7, 0xcf, 0xa6,
|
||||
0xc3, 0x7d, 0x9d, 0x7a, 0x9a, 0x6b, 0x38, 0xbe, 0xed, 0xd6, 0x38, 0x86, 0x37, 0x04, 0xa3, 0x16,
|
||||
0x32, 0xaa, 0x27, 0xb0, 0x79, 0xcf, 0x30, 0x69, 0x33, 0x22, 0xf6, 0xa9, 0x8f, 0xef, 0x40, 0x76,
|
||||
0x68, 0x98, 0x54, 0x4a, 0xed, 0x66, 0xf6, 0x4a, 0x07, 0xef, 0xd6, 0xe6, 0x94, 0x6a, 0x49, 0x8d,
|
||||
0x1e, 0x83, 0x15, 0xae, 0x51, 0xfd, 0x57, 0x16, 0xb6, 0x96, 0x48, 0x31, 0x86, 0xac, 0x45, 0x26,
|
||||
0xcc, 0x62, 0x6a, 0xaf, 0xa8, 0xf0, 0xff, 0x58, 0x82, 0x35, 0x87, 0x68, 0x8f, 0xc9, 0x88, 0x4a,
|
||||
0x69, 0x0e, 0x87, 0x4d, 0xfc, 0x36, 0x80, 0x4e, 0x1d, 0x6a, 0xe9, 0xd4, 0xd2, 0xce, 0xa5, 0xcc,
|
||||
0x6e, 0x66, 0xaf, 0xa8, 0xc4, 0x10, 0xfc, 0x21, 0x6c, 0x3a, 0xd3, 0x33, 0xd3, 0xd0, 0xd4, 0x18,
|
||||
0x0d, 0x76, 0x33, 0x7b, 0x39, 0x05, 0x09, 0x41, 0x73, 0x46, 0xbe, 0x0e, 0x1b, 0x4f, 0x29, 0x79,
|
||||
0x1c, 0xa7, 0x96, 0x38, 0xb5, 0xc2, 0xe0, 0x18, 0xb1, 0x01, 0xe5, 0x09, 0xf5, 0x3c, 0x32, 0xa2,
|
||||
0xaa, 0x7f, 0xee, 0x50, 0x29, 0xcb, 0x47, 0xbf, 0xbb, 0x30, 0xfa, 0xf9, 0x91, 0x97, 0x02, 0xad,
|
||||
0xc1, 0xb9, 0x43, 0x71, 0x1d, 0x8a, 0xd4, 0x9a, 0x4e, 0x84, 0x85, 0xdc, 0x8a, 0xf8, 0xc9, 0xd6,
|
||||
0x74, 0x32, 0x6f, 0xa5, 0xc0, 0xd4, 0x02, 0x13, 0x6b, 0x1e, 0x75, 0x9f, 0x18, 0x1a, 0x95, 0xf2,
|
||||
0xdc, 0xc0, 0xf5, 0x05, 0x03, 0x7d, 0x21, 0x9f, 0xb7, 0x11, 0xea, 0xe1, 0x06, 0x14, 0xe9, 0x33,
|
||||
0x9f, 0x5a, 0x9e, 0x61, 0x5b, 0xd2, 0x1a, 0x37, 0xf2, 0xde, 0x92, 0x59, 0xa4, 0xa6, 0x3e, 0x6f,
|
||||
0x62, 0xa6, 0x87, 0x6f, 0xc3, 0x9a, 0xed, 0xf8, 0x86, 0x6d, 0x79, 0x52, 0x61, 0x37, 0xb5, 0x57,
|
||||
0x3a, 0x78, 0x73, 0x69, 0x22, 0x74, 0x05, 0x47, 0x09, 0xc9, 0xb8, 0x05, 0xc8, 0xb3, 0xa7, 0xae,
|
||||
0x46, 0x55, 0xcd, 0xd6, 0xa9, 0x6a, 0x58, 0x43, 0x5b, 0x2a, 0x72, 0x03, 0x57, 0x17, 0x07, 0xc2,
|
||||
0x89, 0x0d, 0x5b, 0xa7, 0x2d, 0x6b, 0x68, 0x2b, 0x15, 0x2f, 0xd1, 0xc6, 0x97, 0x20, 0xef, 0x9d,
|
||||
0x5b, 0x3e, 0x79, 0x26, 0x95, 0x79, 0x86, 0x04, 0xad, 0xea, 0x7f, 0x73, 0xb0, 0x71, 0x91, 0x14,
|
||||
0xfb, 0x1c, 0x72, 0x43, 0x36, 0x4a, 0x29, 0xfd, 0xff, 0xc4, 0x40, 0xe8, 0x24, 0x83, 0x98, 0xff,
|
||||
0x81, 0x41, 0xac, 0x43, 0xc9, 0xa2, 0x9e, 0x4f, 0x75, 0x91, 0x11, 0x99, 0x0b, 0xe6, 0x14, 0x08,
|
||||
0xa5, 0xc5, 0x94, 0xca, 0xfe, 0xa0, 0x94, 0x7a, 0x00, 0x1b, 0x91, 0x4b, 0xaa, 0x4b, 0xac, 0x51,
|
||||
0x98, 0x9b, 0xfb, 0x2f, 0xf3, 0xa4, 0x26, 0x87, 0x7a, 0x0a, 0x53, 0x53, 0x2a, 0x34, 0xd1, 0xc6,
|
||||
0x4d, 0x00, 0xdb, 0xa2, 0xf6, 0x50, 0xd5, 0xa9, 0x66, 0x4a, 0x85, 0x15, 0x51, 0xea, 0x32, 0xca,
|
||||
0x42, 0x94, 0x6c, 0x81, 0x6a, 0x26, 0xfe, 0x6c, 0x96, 0x6a, 0x6b, 0x2b, 0x32, 0xe5, 0x44, 0x2c,
|
||||
0xb2, 0x85, 0x6c, 0x3b, 0x85, 0x8a, 0x4b, 0x59, 0xde, 0x53, 0x3d, 0x18, 0x59, 0x91, 0x3b, 0x51,
|
||||
0x7b, 0xe9, 0xc8, 0x94, 0x40, 0x4d, 0x0c, 0x6c, 0xdd, 0x8d, 0x37, 0xf1, 0x3b, 0x10, 0x01, 0x2a,
|
||||
0x4f, 0x2b, 0xe0, 0xbb, 0x50, 0x39, 0x04, 0x3b, 0x64, 0x42, 0x77, 0xee, 0x40, 0x25, 0x19, 0x1e,
|
||||
0xbc, 0x0d, 0x39, 0xcf, 0x27, 0xae, 0xcf, 0xb3, 0x30, 0xa7, 0x88, 0x06, 0x46, 0x90, 0xa1, 0x96,
|
||||
0xce, 0x77, 0xb9, 0x9c, 0xc2, 0xfe, 0xee, 0x7c, 0x0a, 0xeb, 0x89, 0xee, 0x2f, 0xaa, 0x58, 0xfd,
|
||||
0x7d, 0x1e, 0xb6, 0x97, 0xe5, 0xdc, 0xd2, 0xf4, 0xbf, 0x04, 0x79, 0x6b, 0x3a, 0x39, 0xa3, 0xae,
|
||||
0x94, 0xe1, 0x16, 0x82, 0x16, 0xae, 0x43, 0xce, 0x24, 0x67, 0xd4, 0x94, 0xb2, 0xbb, 0xa9, 0xbd,
|
||||
0xca, 0xc1, 0x87, 0x17, 0xca, 0xea, 0x5a, 0x9b, 0xa9, 0x28, 0x42, 0x13, 0xdf, 0x85, 0x6c, 0xb0,
|
||||
0xc5, 0x31, 0x0b, 0x1f, 0x5c, 0xcc, 0x02, 0xcb, 0x45, 0x85, 0xeb, 0xe1, 0x37, 0xa0, 0xc8, 0x7e,
|
||||
0x45, 0x6c, 0xf3, 0xdc, 0xe7, 0x02, 0x03, 0x58, 0x5c, 0xf1, 0x0e, 0x14, 0x78, 0x9a, 0xe9, 0x34,
|
||||
0x3c, 0x1a, 0xa2, 0x36, 0x9b, 0x18, 0x9d, 0x0e, 0xc9, 0xd4, 0xf4, 0xd5, 0x27, 0xc4, 0x9c, 0x52,
|
||||
0x9e, 0x30, 0x45, 0xa5, 0x1c, 0x80, 0xbf, 0x66, 0x18, 0xbe, 0x0a, 0x25, 0x91, 0x95, 0x86, 0xa5,
|
||||
0xd3, 0x67, 0x7c, 0xf7, 0xc9, 0x29, 0x22, 0x51, 0x5b, 0x0c, 0x61, 0xdd, 0x3f, 0xf2, 0x6c, 0x2b,
|
||||
0x9c, 0x5a, 0xde, 0x05, 0x03, 0x78, 0xf7, 0x9f, 0xce, 0x6f, 0x7c, 0x6f, 0x2d, 0x1f, 0xde, 0x7c,
|
||||
0x2e, 0x56, 0xff, 0x92, 0x86, 0x2c, 0x5f, 0x6f, 0x1b, 0x50, 0x1a, 0x3c, 0xec, 0xc9, 0x6a, 0xb3,
|
||||
0x7b, 0x7a, 0xd4, 0x96, 0x51, 0x0a, 0x57, 0x00, 0x38, 0x70, 0xaf, 0xdd, 0xad, 0x0f, 0x50, 0x3a,
|
||||
0x6a, 0xb7, 0x3a, 0x83, 0xdb, 0x37, 0x51, 0x26, 0x52, 0x38, 0x15, 0x40, 0x36, 0x4e, 0xf8, 0xe4,
|
||||
0x00, 0xe5, 0x30, 0x82, 0xb2, 0x30, 0xd0, 0x7a, 0x20, 0x37, 0x6f, 0xdf, 0x44, 0xf9, 0x24, 0xf2,
|
||||
0xc9, 0x01, 0x5a, 0xc3, 0xeb, 0x50, 0xe4, 0xc8, 0x51, 0xb7, 0xdb, 0x46, 0x85, 0xc8, 0x66, 0x7f,
|
||||
0xa0, 0xb4, 0x3a, 0xc7, 0xa8, 0x18, 0xd9, 0x3c, 0x56, 0xba, 0xa7, 0x3d, 0x04, 0x91, 0x85, 0x13,
|
||||
0xb9, 0xdf, 0xaf, 0x1f, 0xcb, 0xa8, 0x14, 0x31, 0x8e, 0x1e, 0x0e, 0xe4, 0x3e, 0x2a, 0x27, 0xdc,
|
||||
0xfa, 0xe4, 0x00, 0xad, 0x47, 0x5d, 0xc8, 0x9d, 0xd3, 0x13, 0x54, 0xc1, 0x9b, 0xb0, 0x2e, 0xba,
|
||||
0x08, 0x9d, 0xd8, 0x98, 0x83, 0x6e, 0xdf, 0x44, 0x68, 0xe6, 0x88, 0xb0, 0xb2, 0x99, 0x00, 0x6e,
|
||||
0xdf, 0x44, 0xb8, 0xda, 0x80, 0x1c, 0xcf, 0x2e, 0x8c, 0xa1, 0xd2, 0xae, 0x1f, 0xc9, 0x6d, 0xb5,
|
||||
0xdb, 0x1b, 0xb4, 0xba, 0x9d, 0x7a, 0x1b, 0xa5, 0x66, 0x98, 0x22, 0xff, 0xea, 0xb4, 0xa5, 0xc8,
|
||||
0x4d, 0x94, 0x8e, 0x63, 0x3d, 0xb9, 0x3e, 0x90, 0x9b, 0x28, 0x53, 0xd5, 0x60, 0x7b, 0xd9, 0x3e,
|
||||
0xb3, 0x74, 0x65, 0xc4, 0xa6, 0x38, 0xbd, 0x62, 0x8a, 0xb9, 0xad, 0x85, 0x29, 0xfe, 0x36, 0x05,
|
||||
0x5b, 0x4b, 0xf6, 0xda, 0xa5, 0x9d, 0xfc, 0x02, 0x72, 0x22, 0x45, 0xc5, 0xe9, 0x73, 0x63, 0xe9,
|
||||
0xa6, 0xcd, 0x13, 0x76, 0xe1, 0x04, 0xe2, 0x7a, 0xf1, 0x13, 0x38, 0xb3, 0xe2, 0x04, 0x66, 0x26,
|
||||
0x16, 0x9c, 0xfc, 0x4d, 0x0a, 0xa4, 0x55, 0xb6, 0x5f, 0xb2, 0x51, 0xa4, 0x13, 0x1b, 0xc5, 0xe7,
|
||||
0xf3, 0x0e, 0x5c, 0x5b, 0x3d, 0x86, 0x05, 0x2f, 0xbe, 0x4b, 0xc1, 0xa5, 0xe5, 0x85, 0xca, 0x52,
|
||||
0x1f, 0xee, 0x42, 0x7e, 0x42, 0xfd, 0xb1, 0x1d, 0x1e, 0xd6, 0xef, 0x2f, 0x39, 0x02, 0x98, 0x78,
|
||||
0x3e, 0x56, 0x81, 0x56, 0xfc, 0x0c, 0xc9, 0xac, 0xaa, 0x36, 0x84, 0x37, 0x0b, 0x9e, 0xfe, 0x36,
|
||||
0x0d, 0xaf, 0x2f, 0x35, 0xbe, 0xd4, 0xd1, 0xb7, 0x00, 0x0c, 0xcb, 0x99, 0xfa, 0xe2, 0x40, 0x16,
|
||||
// 2519 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xc4, 0x59, 0xdd, 0x6e, 0x1b, 0xc7,
|
||||
0x15, 0x0e, 0x7f, 0x45, 0x1e, 0x52, 0xd4, 0x68, 0xa4, 0xd8, 0x6b, 0xe5, 0xc7, 0x32, 0xf3, 0x63,
|
||||
0xd9, 0x69, 0xa8, 0x40, 0xb1, 0x1d, 0x47, 0x29, 0xd2, 0x52, 0xe4, 0x5a, 0xa1, 0x4a, 0x91, 0xec,
|
||||
0x92, 0x6a, 0x7e, 0x6e, 0x16, 0xa3, 0xdd, 0x21, 0xb9, 0xf6, 0x72, 0x77, 0xb3, 0xbb, 0xb4, 0xad,
|
||||
0xa0, 0x17, 0x06, 0x7a, 0x55, 0xa0, 0x0f, 0x50, 0x14, 0x45, 0x2f, 0x72, 0x13, 0xa0, 0x0f, 0x50,
|
||||
0x20, 0x77, 0x7d, 0x82, 0x02, 0x79, 0x83, 0xa2, 0x28, 0xd0, 0x3e, 0x46, 0x31, 0x33, 0xbb, 0xcb,
|
||||
0x5d, 0xfe, 0xc4, 0x6a, 0x80, 0x38, 0x57, 0xe4, 0x7c, 0xe7, 0x3b, 0x67, 0xce, 0x9c, 0x39, 0x33,
|
||||
0x73, 0x66, 0x16, 0x76, 0x47, 0xb6, 0x3d, 0x32, 0xe9, 0xbe, 0xe3, 0xda, 0xbe, 0x7d, 0x3e, 0x1d,
|
||||
0xee, 0xeb, 0xd4, 0xd3, 0x5c, 0xc3, 0xf1, 0x6d, 0xb7, 0xc6, 0x31, 0xbc, 0x21, 0x18, 0xb5, 0x90,
|
||||
0x51, 0x3d, 0x85, 0xcd, 0x07, 0x86, 0x49, 0x9b, 0x11, 0xb1, 0x4f, 0x7d, 0x7c, 0x1f, 0xb2, 0x43,
|
||||
0xc3, 0xa4, 0x52, 0x6a, 0x37, 0xb3, 0x57, 0x3a, 0x78, 0xb3, 0x36, 0xa7, 0x54, 0x4b, 0x6a, 0xf4,
|
||||
0x18, 0xac, 0x70, 0x8d, 0xea, 0xbf, 0xb3, 0xb0, 0xb5, 0x44, 0x8a, 0x31, 0x64, 0x2d, 0x32, 0x61,
|
||||
0x16, 0x53, 0x7b, 0x45, 0x85, 0xff, 0xc7, 0x12, 0xac, 0x39, 0x44, 0x7b, 0x44, 0x46, 0x54, 0x4a,
|
||||
0x73, 0x38, 0x6c, 0xe2, 0xd7, 0x01, 0x74, 0xea, 0x50, 0x4b, 0xa7, 0x96, 0x76, 0x21, 0x65, 0x76,
|
||||
0x33, 0x7b, 0x45, 0x25, 0x86, 0xe0, 0x77, 0x60, 0xd3, 0x99, 0x9e, 0x9b, 0x86, 0xa6, 0xc6, 0x68,
|
||||
0xb0, 0x9b, 0xd9, 0xcb, 0x29, 0x48, 0x08, 0x9a, 0x33, 0xf2, 0x4d, 0xd8, 0x78, 0x42, 0xc9, 0xa3,
|
||||
0x38, 0xb5, 0xc4, 0xa9, 0x15, 0x06, 0xc7, 0x88, 0x0d, 0x28, 0x4f, 0xa8, 0xe7, 0x91, 0x11, 0x55,
|
||||
0xfd, 0x0b, 0x87, 0x4a, 0x59, 0x3e, 0xfa, 0xdd, 0x85, 0xd1, 0xcf, 0x8f, 0xbc, 0x14, 0x68, 0x0d,
|
||||
0x2e, 0x1c, 0x8a, 0xeb, 0x50, 0xa4, 0xd6, 0x74, 0x22, 0x2c, 0xe4, 0x56, 0xc4, 0x4f, 0xb6, 0xa6,
|
||||
0x93, 0x79, 0x2b, 0x05, 0xa6, 0x16, 0x98, 0x58, 0xf3, 0xa8, 0xfb, 0xd8, 0xd0, 0xa8, 0x94, 0xe7,
|
||||
0x06, 0x6e, 0x2e, 0x18, 0xe8, 0x0b, 0xf9, 0xbc, 0x8d, 0x50, 0x0f, 0x37, 0xa0, 0x48, 0x9f, 0xfa,
|
||||
0xd4, 0xf2, 0x0c, 0xdb, 0x92, 0xd6, 0xb8, 0x91, 0xb7, 0x96, 0xcc, 0x22, 0x35, 0xf5, 0x79, 0x13,
|
||||
0x33, 0x3d, 0x7c, 0x0f, 0xd6, 0x6c, 0xc7, 0x37, 0x6c, 0xcb, 0x93, 0x0a, 0xbb, 0xa9, 0xbd, 0xd2,
|
||||
0xc1, 0xab, 0x4b, 0x13, 0xa1, 0x2b, 0x38, 0x4a, 0x48, 0xc6, 0x2d, 0x40, 0x9e, 0x3d, 0x75, 0x35,
|
||||
0xaa, 0x6a, 0xb6, 0x4e, 0x55, 0xc3, 0x1a, 0xda, 0x52, 0x91, 0x1b, 0xb8, 0xbe, 0x38, 0x10, 0x4e,
|
||||
0x6c, 0xd8, 0x3a, 0x6d, 0x59, 0x43, 0x5b, 0xa9, 0x78, 0x89, 0x36, 0xbe, 0x02, 0x79, 0xef, 0xc2,
|
||||
0xf2, 0xc9, 0x53, 0xa9, 0xcc, 0x33, 0x24, 0x68, 0x55, 0xbf, 0xcd, 0xc3, 0xc6, 0x65, 0x52, 0xec,
|
||||
0x23, 0xc8, 0x0d, 0xd9, 0x28, 0xa5, 0xf4, 0xff, 0x13, 0x03, 0xa1, 0x93, 0x0c, 0x62, 0xfe, 0x07,
|
||||
0x06, 0xb1, 0x0e, 0x25, 0x8b, 0x7a, 0x3e, 0xd5, 0x45, 0x46, 0x64, 0x2e, 0x99, 0x53, 0x20, 0x94,
|
||||
0x16, 0x53, 0x2a, 0xfb, 0x83, 0x52, 0xea, 0x33, 0xd8, 0x88, 0x5c, 0x52, 0x5d, 0x62, 0x8d, 0xc2,
|
||||
0xdc, 0xdc, 0x7f, 0x9e, 0x27, 0x35, 0x39, 0xd4, 0x53, 0x98, 0x9a, 0x52, 0xa1, 0x89, 0x36, 0x6e,
|
||||
0x02, 0xd8, 0x16, 0xb5, 0x87, 0xaa, 0x4e, 0x35, 0x53, 0x2a, 0xac, 0x88, 0x52, 0x97, 0x51, 0x16,
|
||||
0xa2, 0x64, 0x0b, 0x54, 0x33, 0xf1, 0x87, 0xb3, 0x54, 0x5b, 0x5b, 0x91, 0x29, 0xa7, 0x62, 0x91,
|
||||
0x2d, 0x64, 0xdb, 0x19, 0x54, 0x5c, 0xca, 0xf2, 0x9e, 0xea, 0xc1, 0xc8, 0x8a, 0xdc, 0x89, 0xda,
|
||||
0x73, 0x47, 0xa6, 0x04, 0x6a, 0x62, 0x60, 0xeb, 0x6e, 0xbc, 0x89, 0xdf, 0x80, 0x08, 0x50, 0x79,
|
||||
0x5a, 0x01, 0xdf, 0x85, 0xca, 0x21, 0xd8, 0x21, 0x13, 0xba, 0xf3, 0x15, 0x54, 0x92, 0xe1, 0xc1,
|
||||
0xdb, 0x90, 0xf3, 0x7c, 0xe2, 0xfa, 0x3c, 0x0b, 0x73, 0x8a, 0x68, 0x60, 0x04, 0x19, 0x6a, 0xe9,
|
||||
0x7c, 0x97, 0xcb, 0x29, 0xec, 0x2f, 0xfe, 0xe5, 0x6c, 0xc0, 0x19, 0x3e, 0xe0, 0xb7, 0x17, 0x67,
|
||||
0x34, 0x61, 0x79, 0x7e, 0xdc, 0x3b, 0x1f, 0xc0, 0x7a, 0x62, 0x00, 0x97, 0xed, 0xba, 0xfa, 0x5b,
|
||||
0x78, 0x79, 0xa9, 0x69, 0xfc, 0x19, 0x6c, 0x4f, 0x2d, 0xc3, 0xf2, 0xa9, 0xeb, 0xb8, 0x94, 0x65,
|
||||
0xac, 0xe8, 0x4a, 0xfa, 0xcf, 0xda, 0x8a, 0x9c, 0x3b, 0x8b, 0xb3, 0x85, 0x15, 0x65, 0x6b, 0xba,
|
||||
0x08, 0xde, 0x2e, 0x16, 0xfe, 0xbb, 0x86, 0x9e, 0x3d, 0x7b, 0xf6, 0x2c, 0x5d, 0xfd, 0x63, 0x1e,
|
||||
0xb6, 0x97, 0xad, 0x99, 0xa5, 0xcb, 0xf7, 0x0a, 0xe4, 0xad, 0xe9, 0xe4, 0x9c, 0xba, 0x3c, 0x48,
|
||||
0x39, 0x25, 0x68, 0xe1, 0x3a, 0xe4, 0x4c, 0x72, 0x4e, 0x4d, 0x29, 0xbb, 0x9b, 0xda, 0xab, 0x1c,
|
||||
0xbc, 0x73, 0xa9, 0x55, 0x59, 0x6b, 0x33, 0x15, 0x45, 0x68, 0xe2, 0x8f, 0x21, 0x1b, 0x6c, 0xd1,
|
||||
0xcc, 0xc2, 0xed, 0xcb, 0x59, 0x60, 0x6b, 0x49, 0xe1, 0x7a, 0xf8, 0x15, 0x28, 0xb2, 0x5f, 0x91,
|
||||
0x1b, 0x79, 0xee, 0x73, 0x81, 0x01, 0x2c, 0x2f, 0xf0, 0x0e, 0x14, 0xf8, 0x32, 0xd1, 0x69, 0x78,
|
||||
0xb4, 0x45, 0x6d, 0x96, 0x58, 0x3a, 0x1d, 0x92, 0xa9, 0xe9, 0xab, 0x8f, 0x89, 0x39, 0xa5, 0x3c,
|
||||
0xe1, 0x8b, 0x4a, 0x39, 0x00, 0x7f, 0xc3, 0x30, 0x7c, 0x1d, 0x4a, 0x62, 0x55, 0x19, 0x96, 0x4e,
|
||||
0x9f, 0xf2, 0xdd, 0x33, 0xa7, 0x88, 0x85, 0xd6, 0x62, 0x08, 0xeb, 0xfe, 0xa1, 0x67, 0x5b, 0x61,
|
||||
0x6a, 0xf2, 0x2e, 0x18, 0xc0, 0xbb, 0xff, 0x60, 0x7e, 0xe3, 0x7e, 0x6d, 0xf9, 0xf0, 0xe6, 0x73,
|
||||
0xaa, 0xfa, 0xb7, 0x34, 0x64, 0xf9, 0x7e, 0xb1, 0x01, 0xa5, 0xc1, 0xe7, 0x3d, 0x59, 0x6d, 0x76,
|
||||
0xcf, 0x8e, 0xda, 0x32, 0x4a, 0xe1, 0x0a, 0x00, 0x07, 0x1e, 0xb4, 0xbb, 0xf5, 0x01, 0x4a, 0x47,
|
||||
0xed, 0x56, 0x67, 0x70, 0xef, 0x0e, 0xca, 0x44, 0x0a, 0x67, 0x02, 0xc8, 0xc6, 0x09, 0xef, 0x1f,
|
||||
0xa0, 0x1c, 0x46, 0x50, 0x16, 0x06, 0x5a, 0x9f, 0xc9, 0xcd, 0x7b, 0x77, 0x50, 0x3e, 0x89, 0xbc,
|
||||
0x7f, 0x80, 0xd6, 0xf0, 0x3a, 0x14, 0x39, 0x72, 0xd4, 0xed, 0xb6, 0x51, 0x21, 0xb2, 0xd9, 0x1f,
|
||||
0x28, 0xad, 0xce, 0x31, 0x2a, 0x46, 0x36, 0x8f, 0x95, 0xee, 0x59, 0x0f, 0x41, 0x64, 0xe1, 0x54,
|
||||
0xee, 0xf7, 0xeb, 0xc7, 0x32, 0x2a, 0x45, 0x8c, 0xa3, 0xcf, 0x07, 0x72, 0x1f, 0x95, 0x13, 0x6e,
|
||||
0xbd, 0x7f, 0x80, 0xd6, 0xa3, 0x2e, 0xe4, 0xce, 0xd9, 0x29, 0xaa, 0xe0, 0x4d, 0x58, 0x17, 0x5d,
|
||||
0x84, 0x4e, 0x6c, 0xcc, 0x41, 0xf7, 0xee, 0x20, 0x34, 0x73, 0x44, 0x58, 0xd9, 0x4c, 0x00, 0xf7,
|
||||
0xee, 0x20, 0x5c, 0x6d, 0x40, 0x8e, 0x67, 0x17, 0xc6, 0x50, 0x69, 0xd7, 0x8f, 0xe4, 0xb6, 0xda,
|
||||
0xed, 0x0d, 0x5a, 0xdd, 0x4e, 0xbd, 0x8d, 0x52, 0x33, 0x4c, 0x91, 0x7f, 0x7d, 0xd6, 0x52, 0xe4,
|
||||
0x26, 0x4a, 0xc7, 0xb1, 0x9e, 0x5c, 0x1f, 0xc8, 0x4d, 0x94, 0xa9, 0x6a, 0xb0, 0xbd, 0x6c, 0x9f,
|
||||
0x5c, 0xba, 0x32, 0x62, 0x53, 0x9c, 0x5e, 0x31, 0xc5, 0xdc, 0xd6, 0xc2, 0x14, 0x7f, 0x9d, 0x82,
|
||||
0xad, 0x25, 0x67, 0xc5, 0xd2, 0x4e, 0x7e, 0x01, 0x39, 0x91, 0xa2, 0xe2, 0xf4, 0xbc, 0xb5, 0xf4,
|
||||
0xd0, 0xe1, 0x09, 0xbb, 0x70, 0x82, 0x72, 0xbd, 0x78, 0x05, 0x91, 0x59, 0x51, 0x41, 0x30, 0x13,
|
||||
0x0b, 0x4e, 0xfe, 0x2e, 0x05, 0xd2, 0x2a, 0xdb, 0xcf, 0xd9, 0x28, 0xd2, 0x89, 0x8d, 0xe2, 0xa3,
|
||||
0x79, 0x07, 0x6e, 0xac, 0x1e, 0xc3, 0x82, 0x17, 0xdf, 0xa4, 0xe0, 0xca, 0xf2, 0x42, 0x6b, 0xa9,
|
||||
0x0f, 0x1f, 0x43, 0x7e, 0x42, 0xfd, 0xb1, 0x1d, 0x16, 0x1b, 0x6f, 0x2f, 0x39, 0xc2, 0x98, 0x78,
|
||||
0x3e, 0x56, 0x81, 0x56, 0xfc, 0x0c, 0xcc, 0xac, 0xaa, 0x96, 0x84, 0x37, 0x0b, 0x9e, 0xfe, 0x3e,
|
||||
0x0d, 0x2f, 0x2f, 0x35, 0xbe, 0xd4, 0xd1, 0xd7, 0x00, 0x0c, 0xcb, 0x99, 0xfa, 0xa2, 0xa0, 0x10,
|
||||
0xfb, 0x53, 0x91, 0x23, 0x7c, 0xed, 0xb3, 0xbd, 0x67, 0xea, 0x47, 0xf2, 0x0c, 0x97, 0x83, 0x80,
|
||||
0x38, 0xe1, 0xce, 0xcc, 0xd1, 0x2c, 0x77, 0xf4, 0xed, 0x15, 0x23, 0x5d, 0x38, 0xeb, 0x3e, 0x06,
|
||||
0x38, 0xe1, 0xfe, 0xcc, 0xd1, 0x2c, 0x77, 0xf4, 0xf5, 0x15, 0x23, 0x5d, 0x38, 0xab, 0xdf, 0x03,
|
||||
0xa4, 0x99, 0x06, 0xb5, 0x7c, 0xd5, 0xf3, 0x5d, 0x4a, 0x26, 0x86, 0x35, 0xe2, 0x1b, 0x70, 0xe1,
|
||||
0x30, 0x37, 0x24, 0xa6, 0x47, 0x95, 0x0d, 0x21, 0xee, 0x87, 0x52, 0xa6, 0xc1, 0x4f, 0x19, 0x37,
|
||||
0xa6, 0x91, 0x4f, 0x68, 0x08, 0x71, 0xa4, 0x51, 0xfd, 0x6b, 0x01, 0x4a, 0xb1, 0xb2, 0x0e, 0x5f,
|
||||
0x83, 0xf2, 0x23, 0xf2, 0x84, 0xa8, 0x61, 0xa9, 0x2e, 0x22, 0x51, 0x62, 0x58, 0x2f, 0x28, 0xd7,
|
||||
0x3f, 0x86, 0x6d, 0x4e, 0xb1, 0xa7, 0x3e, 0x75, 0x55, 0xcd, 0x24, 0x9e, 0xc7, 0x83, 0x56, 0xe0,
|
||||
0x54, 0xcc, 0x64, 0x5d, 0x26, 0x6a, 0x84, 0x12, 0x7c, 0x0b, 0xb6, 0xb8, 0xc6, 0x64, 0x6a, 0xfa,
|
||||
0x86, 0x63, 0x52, 0x95, 0x5d, 0x1e, 0x3c, 0xbe, 0x11, 0x47, 0x9e, 0x6d, 0x32, 0xc6, 0x49, 0x40,
|
||||
0x60, 0x1e, 0x79, 0xb8, 0x09, 0x6f, 0x71, 0xb5, 0x11, 0xb5, 0xa8, 0x4b, 0x7c, 0xaa, 0xd2, 0xaf,
|
||||
0xa7, 0xc4, 0xf4, 0x54, 0x62, 0xe9, 0xea, 0x98, 0x78, 0x63, 0x69, 0x9b, 0x19, 0x38, 0x4a, 0x4b,
|
||||
0x29, 0xe5, 0x0a, 0x23, 0x1e, 0x07, 0x3c, 0x99, 0xd3, 0xea, 0x96, 0xfe, 0x05, 0xf1, 0xc6, 0xf8,
|
||||
0x10, 0x2e, 0x71, 0x2b, 0x9e, 0xef, 0x1a, 0xd6, 0x48, 0xd5, 0xc6, 0x54, 0x7b, 0xac, 0x4e, 0xfd,
|
||||
0xe1, 0x1d, 0xe9, 0x8d, 0x78, 0xff, 0xdc, 0xc3, 0x3e, 0xe7, 0x34, 0x18, 0xe5, 0xd4, 0x1f, 0xde,
|
||||
0xc1, 0x7d, 0x28, 0xb3, 0xc9, 0x98, 0x18, 0xdf, 0x50, 0x75, 0x68, 0xbb, 0xfc, 0x64, 0xa9, 0x2c,
|
||||
0x59, 0xd9, 0xb1, 0x08, 0xd6, 0xba, 0x81, 0xc2, 0x89, 0xad, 0xd3, 0xc3, 0x5c, 0xbf, 0x27, 0xcb,
|
||||
0x4d, 0xa5, 0x14, 0x5a, 0xb9, 0x67, 0xbb, 0x2c, 0xa1, 0x46, 0x76, 0x14, 0xe0, 0x92, 0x48, 0xa8,
|
||||
0x91, 0x1d, 0x86, 0xf7, 0x16, 0x6c, 0x69, 0x9a, 0x18, 0xb3, 0xa1, 0xa9, 0x41, 0x89, 0xef, 0x49,
|
||||
0x28, 0x11, 0x2c, 0x4d, 0x3b, 0x16, 0x84, 0x20, 0xc7, 0x3d, 0xfc, 0x19, 0xbc, 0x3e, 0x0b, 0x56,
|
||||
0x5c, 0x71, 0x73, 0x61, 0x94, 0xf3, 0xaa, 0xb7, 0x60, 0xcb, 0x39, 0x5f, 0x54, 0xc4, 0x89, 0x1e,
|
||||
0x9d, 0xf3, 0x79, 0xb5, 0x4f, 0x61, 0xdb, 0x19, 0x3b, 0x8b, 0x7a, 0x5b, 0x71, 0x3d, 0xec, 0x8c,
|
||||
0x9d, 0x79, 0xc5, 0xf7, 0xf8, 0x7d, 0xcf, 0xa5, 0x1a, 0xf1, 0xa9, 0x2e, 0x5d, 0x8e, 0xd3, 0x63,
|
||||
0x02, 0xbc, 0x0f, 0x48, 0xd3, 0x54, 0x6a, 0x91, 0x33, 0x93, 0xaa, 0xc4, 0xa5, 0x16, 0xf1, 0xa4,
|
||||
0xab, 0x71, 0x72, 0x45, 0xd3, 0x64, 0x2e, 0xad, 0x73, 0x21, 0xfe, 0x00, 0x36, 0xed, 0xb3, 0x47,
|
||||
0x9a, 0x48, 0x49, 0xd5, 0x71, 0xe9, 0xd0, 0x78, 0x26, 0xbd, 0xcb, 0xe3, 0xbb, 0xc1, 0x04, 0x3c,
|
||||
0x21, 0x7b, 0x1c, 0xc6, 0x37, 0x00, 0x69, 0xde, 0x98, 0xb8, 0x0e, 0xaf, 0x09, 0x3c, 0x87, 0x68,
|
||||
0x54, 0x7a, 0x4f, 0x50, 0x05, 0xde, 0x09, 0x61, 0xb6, 0x24, 0xbc, 0xa7, 0xc6, 0xd0, 0x0f, 0x2d,
|
||||
0x5e, 0x17, 0x4b, 0x82, 0x63, 0x81, 0xb5, 0x3d, 0x40, 0x2c, 0x14, 0x89, 0x8e, 0xf7, 0x38, 0xad,
|
||||
0xe2, 0x8c, 0x9d, 0x78, 0xbf, 0xef, 0xc0, 0x3a, 0x63, 0xce, 0x3a, 0xbd, 0x21, 0xea, 0x19, 0x67,
|
||||
0x1c, 0xeb, 0xf1, 0x01, 0x6c, 0x4f, 0x2d, 0xc3, 0xf2, 0xa9, 0xeb, 0xb8, 0x94, 0x5d, 0x26, 0xc4,
|
||||
0x8e, 0x20, 0xfd, 0x7b, 0x6d, 0xc5, 0x75, 0xe0, 0x34, 0xce, 0x16, 0x89, 0xa8, 0x6c, 0x4d, 0x17,
|
||||
0xc1, 0xea, 0x21, 0x94, 0xe3, 0xf9, 0x89, 0x8b, 0x20, 0x32, 0x14, 0xa5, 0xd8, 0x59, 0xdf, 0xe8,
|
||||
0x36, 0xd9, 0x29, 0xfd, 0x95, 0x8c, 0xd2, 0xac, 0x5a, 0x68, 0xb7, 0x06, 0xb2, 0xaa, 0x9c, 0x76,
|
||||
0x06, 0xad, 0x13, 0x19, 0x65, 0x3e, 0x28, 0x16, 0xfe, 0xb3, 0x86, 0x9e, 0x3f, 0x7f, 0xfe, 0x3c,
|
||||
0x7d, 0x3f, 0x5b, 0x78, 0x1f, 0x5d, 0xaf, 0x7e, 0x9f, 0x86, 0x4a, 0xb2, 0x4e, 0xc7, 0x3f, 0x87,
|
||||
0xcb, 0xe1, 0xa5, 0xda, 0xa3, 0xbe, 0xfa, 0xd4, 0x70, 0xf9, 0xc2, 0x99, 0x10, 0x51, 0xe9, 0x46,
|
||||
0x53, 0xb7, 0x1d, 0xb0, 0xfa, 0xd4, 0xff, 0xd2, 0x70, 0xd9, 0xb2, 0x98, 0x10, 0x1f, 0xb7, 0xe1,
|
||||
0xaa, 0x65, 0xab, 0x9e, 0x4f, 0x2c, 0x9d, 0xb8, 0xba, 0x3a, 0x7b, 0xce, 0x50, 0x89, 0xa6, 0x51,
|
||||
0xcf, 0xb3, 0xc5, 0x81, 0x15, 0x59, 0x79, 0xd3, 0xb2, 0xfb, 0x01, 0x79, 0xb6, 0x93, 0xd7, 0x03,
|
||||
0xea, 0x5c, 0x9a, 0x65, 0x56, 0xa5, 0xd9, 0x1b, 0x50, 0x9c, 0x10, 0x47, 0xa5, 0x96, 0xef, 0x9e,
|
||||
0xf3, 0xea, 0xb2, 0xa0, 0x14, 0x26, 0xc4, 0x91, 0x59, 0xfb, 0xd5, 0xcd, 0x44, 0x32, 0x9a, 0x05,
|
||||
0x54, 0xbc, 0x9f, 0x2d, 0x14, 0x11, 0x54, 0xff, 0x99, 0x81, 0x72, 0xbc, 0xda, 0x64, 0xc5, 0xbb,
|
||||
0xc6, 0x4f, 0x96, 0x14, 0xdf, 0x7b, 0xde, 0x79, 0x61, 0x6d, 0x5a, 0x6b, 0xb0, 0x23, 0xe7, 0x30,
|
||||
0x2f, 0x6a, 0x40, 0x45, 0x68, 0xb2, 0xe3, 0x9e, 0xed, 0x36, 0x54, 0xdc, 0x2c, 0x0a, 0x4a, 0xd0,
|
||||
0xc2, 0xc7, 0x90, 0x7f, 0xe4, 0x71, 0xdb, 0x79, 0x6e, 0xfb, 0xdd, 0x17, 0xdb, 0xbe, 0xdf, 0xe7,
|
||||
0xc6, 0x8b, 0xf7, 0xfb, 0x6a, 0xa7, 0xab, 0x9c, 0xd4, 0xdb, 0x4a, 0xa0, 0x8e, 0xaf, 0x40, 0xd6,
|
||||
0x24, 0xdf, 0x9c, 0x27, 0x0f, 0x27, 0x0e, 0x5d, 0x74, 0x12, 0xae, 0x40, 0xf6, 0x29, 0x25, 0x8f,
|
||||
0x93, 0x47, 0x02, 0x87, 0x5e, 0xe1, 0x62, 0xd8, 0x87, 0x1c, 0x8f, 0x17, 0x06, 0x08, 0x22, 0x86,
|
||||
0x5e, 0xc3, 0x05, 0xc8, 0x36, 0xba, 0x0a, 0x5b, 0x10, 0x08, 0xca, 0x02, 0x55, 0x7b, 0x2d, 0xb9,
|
||||
0x21, 0xa3, 0x74, 0xf5, 0x16, 0xe4, 0x45, 0x10, 0xd8, 0x62, 0x89, 0xc2, 0x80, 0x5e, 0x0b, 0x9a,
|
||||
0x81, 0x8d, 0x54, 0x28, 0x3d, 0x3d, 0x39, 0x92, 0x15, 0x94, 0x4e, 0x4e, 0x75, 0x16, 0xe5, 0xaa,
|
||||
0x1e, 0x94, 0xe3, 0xe5, 0xe6, 0x8f, 0x92, 0x65, 0xd5, 0xbf, 0xa5, 0xa0, 0x14, 0x2b, 0x1f, 0x59,
|
||||
0xe1, 0x42, 0x4c, 0xd3, 0x7e, 0xaa, 0x12, 0xd3, 0x20, 0x5e, 0x90, 0x1a, 0xc0, 0xa1, 0x3a, 0x43,
|
||||
0x2e, 0x3a, 0x75, 0x3f, 0xd2, 0x12, 0xc9, 0xa1, 0x7c, 0xf5, 0x4f, 0x29, 0x40, 0xf3, 0x05, 0xe8,
|
||||
0x9c, 0x9b, 0xa9, 0x9f, 0xd2, 0xcd, 0xea, 0x1f, 0x53, 0x50, 0x49, 0x56, 0x9d, 0x73, 0xee, 0x5d,
|
||||
0xfb, 0x49, 0xdd, 0xfb, 0x47, 0x1a, 0xd6, 0x13, 0xb5, 0xe6, 0x45, 0xbd, 0xfb, 0x1a, 0x36, 0x0d,
|
||||
0x9d, 0x4e, 0x1c, 0xdb, 0xa7, 0x96, 0x76, 0xae, 0x9a, 0xf4, 0x09, 0x35, 0xa5, 0x2a, 0xdf, 0x34,
|
||||
0xf6, 0x5f, 0x5c, 0xcd, 0xd6, 0x5a, 0x33, 0xbd, 0x36, 0x53, 0x3b, 0xdc, 0x6a, 0x35, 0xe5, 0x93,
|
||||
0x5e, 0x77, 0x20, 0x77, 0x1a, 0x0f, 0xd5, 0xd3, 0xce, 0x2f, 0x3b, 0xdd, 0x2f, 0x3b, 0x0a, 0x32,
|
||||
0xe6, 0x68, 0xaf, 0x70, 0xd9, 0xf7, 0x00, 0xcd, 0x3b, 0x85, 0x2f, 0xc3, 0x32, 0xb7, 0xd0, 0x6b,
|
||||
0x78, 0x0b, 0x36, 0x3a, 0x5d, 0xb5, 0xdf, 0x6a, 0xca, 0xaa, 0x7c, 0xef, 0x9e, 0xdc, 0x18, 0xf4,
|
||||
0xc5, 0xf5, 0x3e, 0x62, 0x0f, 0x12, 0x0b, 0xbc, 0xfa, 0x87, 0x0c, 0x6c, 0x2d, 0xf1, 0x04, 0xd7,
|
||||
0x83, 0x9b, 0x85, 0xb8, 0xec, 0x7c, 0x74, 0x11, 0xef, 0x6b, 0xac, 0x20, 0xe8, 0x11, 0xd7, 0x0f,
|
||||
0x2e, 0x22, 0x37, 0x80, 0x45, 0xc9, 0xf2, 0x8d, 0xa1, 0x41, 0xdd, 0xe0, 0x35, 0x44, 0x5c, 0x37,
|
||||
0x36, 0x66, 0xb8, 0x78, 0x10, 0xf9, 0x19, 0x60, 0xc7, 0xf6, 0x0c, 0xdf, 0x78, 0x42, 0x55, 0xc3,
|
||||
0x0a, 0x9f, 0x4e, 0xd8, 0xf5, 0x23, 0xab, 0xa0, 0x50, 0xd2, 0xb2, 0xfc, 0x88, 0x6d, 0xd1, 0x11,
|
||||
0x99, 0x63, 0xb3, 0xcd, 0x3c, 0xa3, 0xa0, 0x50, 0x12, 0xb1, 0xaf, 0x41, 0x59, 0xb7, 0xa7, 0xac,
|
||||
0x26, 0x13, 0x3c, 0x76, 0x76, 0xa4, 0x94, 0x92, 0xc0, 0x22, 0x4a, 0x50, 0x6d, 0xcf, 0xde, 0x6c,
|
||||
0xca, 0x4a, 0x49, 0x60, 0x82, 0x72, 0x1d, 0x36, 0xc8, 0x68, 0xe4, 0x32, 0xe3, 0xa1, 0x21, 0x71,
|
||||
0x7f, 0xa8, 0x44, 0x30, 0x27, 0xee, 0xdc, 0x87, 0x42, 0x18, 0x07, 0x76, 0x54, 0xb3, 0x48, 0xa8,
|
||||
0x8e, 0x78, 0x39, 0x4b, 0xef, 0x15, 0x95, 0x82, 0x15, 0x0a, 0xaf, 0x41, 0xd9, 0xf0, 0xd4, 0xd9,
|
||||
0x13, 0x6e, 0x7a, 0x37, 0xbd, 0x57, 0x50, 0x4a, 0x86, 0x17, 0xbd, 0xd9, 0x55, 0xbf, 0x4b, 0x43,
|
||||
0x25, 0xf9, 0x04, 0x8d, 0x9b, 0x50, 0x30, 0x6d, 0x8d, 0xf0, 0xd4, 0x12, 0xdf, 0x3f, 0xf6, 0x5e,
|
||||
0xf2, 0x6a, 0x5d, 0x6b, 0x07, 0x7c, 0x25, 0xd2, 0xdc, 0xf9, 0x7b, 0x0a, 0x0a, 0x21, 0x8c, 0x2f,
|
||||
0x41, 0xd6, 0x21, 0xfe, 0x98, 0x9b, 0xcb, 0x1d, 0xa5, 0x51, 0x4a, 0xe1, 0x6d, 0x86, 0x7b, 0x0e,
|
||||
0xb1, 0x78, 0x0a, 0x04, 0x38, 0x6b, 0xb3, 0x79, 0x35, 0x29, 0xd1, 0xf9, 0xe5, 0xc4, 0x9e, 0x4c,
|
||||
0xa8, 0xe5, 0x7b, 0xe1, 0xbc, 0x06, 0x78, 0x23, 0x80, 0xf1, 0x87, 0xb0, 0xe9, 0xbb, 0xc4, 0x30,
|
||||
0x13, 0xdc, 0x2c, 0xe7, 0xa2, 0x50, 0x10, 0x91, 0x0f, 0xe1, 0x4a, 0x68, 0x57, 0xa7, 0x3e, 0xd1,
|
||||
0xc6, 0x54, 0x9f, 0x29, 0xe5, 0xf9, 0xfb, 0xe6, 0xe5, 0x80, 0xd0, 0x0c, 0xe4, 0xa1, 0x6e, 0xf5,
|
||||
0xfb, 0x14, 0x6c, 0x86, 0xd7, 0x29, 0x3d, 0x0a, 0xd6, 0x09, 0x00, 0xb1, 0x2c, 0xdb, 0x8f, 0x87,
|
||||
0x6b, 0x31, 0x95, 0x17, 0xf4, 0x6a, 0xf5, 0x48, 0x49, 0x89, 0x19, 0xd8, 0x99, 0x00, 0xcc, 0x24,
|
||||
0x2b, 0xc3, 0x76, 0x15, 0x4a, 0xc1, 0xf7, 0x05, 0xfe, 0x91, 0x4a, 0x5c, 0xc0, 0x41, 0x40, 0xec,
|
||||
0xde, 0x85, 0xb7, 0x21, 0x77, 0x46, 0x47, 0x86, 0x15, 0xbc, 0x7a, 0x8a, 0x46, 0xf8, 0x96, 0x9a,
|
||||
0x8d, 0xde, 0x52, 0x8f, 0x7e, 0x97, 0x82, 0x2d, 0xcd, 0x9e, 0xcc, 0xfb, 0x7b, 0x84, 0xe6, 0x5e,
|
||||
0x01, 0xbc, 0x2f, 0x52, 0x5f, 0xdd, 0x1d, 0x19, 0xfe, 0x78, 0x7a, 0x56, 0xd3, 0xec, 0xc9, 0xfe,
|
||||
0xc8, 0x36, 0x89, 0x35, 0x9a, 0x7d, 0x65, 0xe3, 0x7f, 0xb4, 0x8f, 0x46, 0xd4, 0xfa, 0x68, 0x64,
|
||||
0xc7, 0xbe, 0xb9, 0x7d, 0x3e, 0xfb, 0xfb, 0x6d, 0x3a, 0x73, 0xdc, 0x3b, 0xfa, 0x73, 0x7a, 0xe7,
|
||||
0x58, 0xf4, 0xd5, 0x0b, 0x63, 0xa3, 0xd0, 0xa1, 0x49, 0x35, 0x36, 0xde, 0xff, 0x05, 0x00, 0x00,
|
||||
0xff, 0xff, 0xa2, 0xc3, 0x4e, 0x18, 0xbe, 0x1b, 0x00, 0x00,
|
||||
0x30, 0x37, 0x24, 0xa6, 0x47, 0x95, 0x0d, 0x21, 0xee, 0x87, 0x52, 0xa6, 0xc1, 0xcf, 0x38, 0x37,
|
||||
0xa6, 0x91, 0x4f, 0x68, 0x08, 0x71, 0xa4, 0x51, 0xfd, 0xb6, 0x00, 0xa5, 0x58, 0x59, 0x8a, 0x6f,
|
||||
0x40, 0xf9, 0x21, 0x79, 0x4c, 0xd4, 0xf0, 0xaa, 0x21, 0x22, 0x51, 0x62, 0x58, 0x2f, 0xb8, 0x6e,
|
||||
0xbc, 0x07, 0xdb, 0x9c, 0x62, 0x4f, 0x7d, 0xea, 0xaa, 0x9a, 0x49, 0x3c, 0x8f, 0x07, 0xad, 0xc0,
|
||||
0xa9, 0x98, 0xc9, 0xba, 0x4c, 0xd4, 0x08, 0x25, 0xf8, 0x2e, 0x6c, 0x71, 0x8d, 0xc9, 0xd4, 0xf4,
|
||||
0x0d, 0xc7, 0xa4, 0x2a, 0xbb, 0xfc, 0x78, 0x7c, 0x23, 0x8e, 0x3c, 0xdb, 0x64, 0x8c, 0xd3, 0x80,
|
||||
0xc0, 0x3c, 0xf2, 0x70, 0x13, 0x5e, 0xe3, 0x6a, 0x23, 0x6a, 0x51, 0x97, 0xf8, 0x54, 0xa5, 0x5f,
|
||||
0x4e, 0x89, 0xe9, 0xa9, 0xc4, 0xd2, 0xd5, 0x31, 0xf1, 0xc6, 0xd2, 0x36, 0x33, 0x70, 0x94, 0x96,
|
||||
0x52, 0xca, 0x35, 0x46, 0x3c, 0x0e, 0x78, 0x32, 0xa7, 0xd5, 0x2d, 0xfd, 0x13, 0xe2, 0x8d, 0xf1,
|
||||
0x21, 0x5c, 0xe1, 0x56, 0x3c, 0xdf, 0x35, 0xac, 0x91, 0xaa, 0x8d, 0xa9, 0xf6, 0x48, 0x9d, 0xfa,
|
||||
0xc3, 0xfb, 0xd2, 0x2b, 0xf1, 0xfe, 0xb9, 0x87, 0x7d, 0xce, 0x69, 0x30, 0xca, 0x99, 0x3f, 0xbc,
|
||||
0x8f, 0xfb, 0x50, 0x66, 0x93, 0x31, 0x31, 0xbe, 0xa2, 0xea, 0xd0, 0x76, 0xf9, 0xc9, 0x52, 0x59,
|
||||
0xb2, 0xb2, 0x63, 0x11, 0xac, 0x75, 0x03, 0x85, 0x53, 0x5b, 0xa7, 0x87, 0xb9, 0x7e, 0x4f, 0x96,
|
||||
0x9b, 0x4a, 0x29, 0xb4, 0xf2, 0xc0, 0x76, 0x59, 0x42, 0x8d, 0xec, 0x28, 0xc0, 0x25, 0x91, 0x50,
|
||||
0x23, 0x3b, 0x0c, 0xef, 0x5d, 0xd8, 0xd2, 0x34, 0x31, 0x66, 0x43, 0x53, 0x83, 0x2b, 0x8a, 0x27,
|
||||
0xa1, 0x44, 0xb0, 0x34, 0xed, 0x58, 0x10, 0x82, 0x1c, 0xf7, 0xf0, 0x87, 0xf0, 0xf2, 0x2c, 0x58,
|
||||
0x71, 0xc5, 0xcd, 0x85, 0x51, 0xce, 0xab, 0xde, 0x85, 0x2d, 0xe7, 0x62, 0x51, 0x11, 0x27, 0x7a,
|
||||
0x74, 0x2e, 0xe6, 0xd5, 0x3e, 0x80, 0x6d, 0x67, 0xec, 0x2c, 0xea, 0xdd, 0x8e, 0xeb, 0x61, 0x67,
|
||||
0xec, 0xcc, 0x2b, 0xbe, 0xc5, 0xef, 0xab, 0x2e, 0xd5, 0x88, 0x4f, 0x75, 0xe9, 0x6a, 0x9c, 0x1e,
|
||||
0x13, 0xe0, 0x7d, 0x40, 0x9a, 0xa6, 0x52, 0x8b, 0x9c, 0x9b, 0x54, 0x25, 0x2e, 0xb5, 0x88, 0x27,
|
||||
0x5d, 0x8f, 0x93, 0x2b, 0x9a, 0x26, 0x73, 0x69, 0x9d, 0x0b, 0xf1, 0x6d, 0xd8, 0xb4, 0xcf, 0x1f,
|
||||
0x6a, 0x22, 0x25, 0x55, 0xc7, 0xa5, 0x43, 0xe3, 0xa9, 0xf4, 0x26, 0x8f, 0xef, 0x06, 0x13, 0xf0,
|
||||
0x84, 0xec, 0x71, 0x18, 0xdf, 0x02, 0xa4, 0x79, 0x63, 0xe2, 0x3a, 0xbc, 0x26, 0xf0, 0x1c, 0xa2,
|
||||
0x51, 0xe9, 0x2d, 0x41, 0x15, 0x78, 0x27, 0x84, 0xd9, 0x92, 0xf0, 0x9e, 0x18, 0x43, 0x3f, 0xb4,
|
||||
0x78, 0x53, 0x2c, 0x09, 0x8e, 0x05, 0xd6, 0xf6, 0x00, 0xb1, 0x50, 0x24, 0x3a, 0xde, 0xe3, 0xb4,
|
||||
0x8a, 0x33, 0x76, 0xe2, 0xfd, 0xbe, 0x01, 0xeb, 0x8c, 0x39, 0xeb, 0xf4, 0x96, 0xa8, 0x67, 0x9c,
|
||||
0x71, 0xac, 0xc7, 0x1f, 0xad, 0xb4, 0xac, 0x1e, 0x42, 0x39, 0x9e, 0x9f, 0xb8, 0x08, 0x22, 0x43,
|
||||
0x51, 0x8a, 0x9d, 0xf5, 0x8d, 0x6e, 0x93, 0x9d, 0xd2, 0x5f, 0xc8, 0x28, 0xcd, 0xaa, 0x85, 0x76,
|
||||
0x6b, 0x20, 0xab, 0xca, 0x59, 0x67, 0xd0, 0x3a, 0x95, 0x51, 0x26, 0x56, 0x96, 0x9e, 0x64, 0x0b,
|
||||
0x6f, 0xa3, 0x9b, 0xd5, 0xef, 0xd2, 0x50, 0x49, 0xde, 0x33, 0xf0, 0xcf, 0xe1, 0x6a, 0xf8, 0x28,
|
||||
0xe0, 0x51, 0x5f, 0x7d, 0x62, 0xb8, 0x7c, 0xe1, 0x4c, 0x88, 0xa8, 0xb3, 0xa3, 0xa9, 0xdb, 0x0e,
|
||||
0x58, 0x7d, 0xea, 0x7f, 0x6a, 0xb8, 0x6c, 0x59, 0x4c, 0x88, 0x8f, 0xdb, 0x70, 0xdd, 0xb2, 0x55,
|
||||
0xcf, 0x27, 0x96, 0x4e, 0x5c, 0x5d, 0x9d, 0x3d, 0xc7, 0xa8, 0x44, 0xd3, 0xa8, 0xe7, 0xd9, 0xe2,
|
||||
0xc0, 0x8a, 0xac, 0xbc, 0x6a, 0xd9, 0xfd, 0x80, 0x3c, 0xdb, 0xc9, 0xeb, 0x01, 0x75, 0x2e, 0xcd,
|
||||
0x32, 0xab, 0xd2, 0xec, 0x15, 0x28, 0x4e, 0x88, 0xa3, 0x52, 0xcb, 0x77, 0x2f, 0x78, 0x75, 0x59,
|
||||
0x50, 0x0a, 0x13, 0xe2, 0xc8, 0xac, 0xfd, 0x42, 0x8a, 0xfc, 0x93, 0x6c, 0xa1, 0x80, 0x8a, 0x27,
|
||||
0xd9, 0x42, 0x11, 0x41, 0xf5, 0x5f, 0x19, 0x28, 0xc7, 0xab, 0x4d, 0x56, 0xbc, 0x6b, 0xfc, 0x64,
|
||||
0x49, 0xf1, 0xbd, 0xe7, 0x8d, 0xef, 0xad, 0x4d, 0x6b, 0x0d, 0x76, 0xe4, 0x1c, 0xe6, 0x45, 0x0d,
|
||||
0xa8, 0x08, 0x4d, 0x76, 0xdc, 0xb3, 0xdd, 0x86, 0x8a, 0x7b, 0x4d, 0x41, 0x09, 0x5a, 0xf8, 0x18,
|
||||
0xf2, 0x0f, 0x3d, 0x6e, 0x3b, 0xcf, 0x6d, 0xbf, 0xf9, 0xfd, 0xb6, 0x4f, 0xfa, 0xdc, 0x78, 0xf1,
|
||||
0xa4, 0xaf, 0x76, 0xba, 0xca, 0x69, 0xbd, 0xad, 0x04, 0xea, 0xf8, 0x1a, 0x64, 0x4d, 0xf2, 0xd5,
|
||||
0x45, 0xf2, 0x70, 0xe2, 0xd0, 0x65, 0x27, 0xe1, 0x1a, 0x64, 0x9f, 0x50, 0xf2, 0x28, 0x79, 0x24,
|
||||
0x70, 0xe8, 0x47, 0x5c, 0x0c, 0xfb, 0x90, 0xe3, 0xf1, 0xc2, 0x00, 0x41, 0xc4, 0xd0, 0x4b, 0xb8,
|
||||
0x00, 0xd9, 0x46, 0x57, 0x61, 0x0b, 0x02, 0x41, 0x59, 0xa0, 0x6a, 0xaf, 0x25, 0x37, 0x64, 0x94,
|
||||
0xae, 0xde, 0x85, 0xbc, 0x08, 0x02, 0x5b, 0x2c, 0x51, 0x18, 0xd0, 0x4b, 0x41, 0x33, 0xb0, 0x91,
|
||||
0x0a, 0xa5, 0x67, 0xa7, 0x47, 0xb2, 0x82, 0xd2, 0xc9, 0xa9, 0xce, 0xa2, 0x5c, 0xd5, 0x83, 0x72,
|
||||
0xbc, 0xdc, 0x7c, 0x31, 0x57, 0xc9, 0xbf, 0xa7, 0xa0, 0x14, 0x2b, 0x1f, 0x59, 0xe1, 0x42, 0x4c,
|
||||
0xd3, 0x7e, 0xa2, 0x12, 0xd3, 0x20, 0x5e, 0x90, 0x1a, 0xc0, 0xa1, 0x3a, 0x43, 0x2e, 0x3b, 0x75,
|
||||
0x2f, 0x68, 0x89, 0xe4, 0x50, 0xbe, 0xfa, 0x97, 0x14, 0xa0, 0xf9, 0x02, 0x74, 0xce, 0xcd, 0xd4,
|
||||
0x4f, 0xe9, 0x66, 0xf5, 0xcf, 0x29, 0xa8, 0x24, 0xab, 0xce, 0x39, 0xf7, 0x6e, 0xfc, 0xa4, 0xee,
|
||||
0xfd, 0x33, 0x0d, 0xeb, 0x89, 0x5a, 0xf3, 0xb2, 0xde, 0x7d, 0x09, 0x9b, 0x86, 0x4e, 0x27, 0x8e,
|
||||
0xed, 0x53, 0x4b, 0xbb, 0x50, 0x4d, 0xfa, 0x98, 0x9a, 0x52, 0x95, 0x6f, 0x1a, 0xfb, 0xdf, 0x5f,
|
||||
0xcd, 0xd6, 0x5a, 0x33, 0xbd, 0x36, 0x53, 0x3b, 0xdc, 0x6a, 0x35, 0xe5, 0xd3, 0x5e, 0x77, 0x20,
|
||||
0x77, 0x1a, 0x9f, 0xab, 0x67, 0x9d, 0x5f, 0x75, 0xba, 0x9f, 0x76, 0x14, 0x64, 0xcc, 0xd1, 0x7e,
|
||||
0xc4, 0x65, 0xdf, 0x03, 0x34, 0xef, 0x14, 0xbe, 0x0a, 0xcb, 0xdc, 0x42, 0x2f, 0xe1, 0x2d, 0xd8,
|
||||
0xe8, 0x74, 0xd5, 0x7e, 0xab, 0x29, 0xab, 0xf2, 0x83, 0x07, 0x72, 0x63, 0xd0, 0x17, 0xd7, 0xfb,
|
||||
0x88, 0x3d, 0x48, 0x2c, 0xf0, 0xea, 0x9f, 0x32, 0xb0, 0xb5, 0xc4, 0x13, 0x5c, 0x0f, 0x6e, 0x16,
|
||||
0xe2, 0xb2, 0xf3, 0xee, 0x65, 0xbc, 0xaf, 0xb1, 0x82, 0xa0, 0x47, 0x5c, 0x3f, 0xb8, 0x88, 0xdc,
|
||||
0x02, 0x16, 0x25, 0xcb, 0x37, 0x86, 0x06, 0x75, 0x83, 0xd7, 0x10, 0x71, 0xdd, 0xd8, 0x98, 0xe1,
|
||||
0xe2, 0x41, 0xe4, 0x67, 0x80, 0x1d, 0xdb, 0x33, 0x7c, 0xe3, 0x31, 0x55, 0x0d, 0x2b, 0x7c, 0x3a,
|
||||
0x61, 0xd7, 0x8f, 0xac, 0x82, 0x42, 0x49, 0xcb, 0xf2, 0x23, 0xb6, 0x45, 0x47, 0x64, 0x8e, 0xcd,
|
||||
0x36, 0xf3, 0x8c, 0x82, 0x42, 0x49, 0xc4, 0xbe, 0x01, 0x65, 0xdd, 0x9e, 0xb2, 0x9a, 0x4c, 0xf0,
|
||||
0xd8, 0xd9, 0x91, 0x52, 0x4a, 0x02, 0x8b, 0x28, 0x41, 0xb5, 0x3d, 0x7b, 0xb3, 0x29, 0x2b, 0x25,
|
||||
0x81, 0x09, 0xca, 0x4d, 0xd8, 0x20, 0xa3, 0x91, 0xcb, 0x8c, 0x87, 0x86, 0xc4, 0xfd, 0xa1, 0x12,
|
||||
0xc1, 0x9c, 0xb8, 0x73, 0x02, 0x85, 0x30, 0x0e, 0xec, 0xa8, 0x66, 0x91, 0x50, 0x1d, 0xf1, 0x6e,
|
||||
0x97, 0xde, 0x2b, 0x2a, 0x05, 0x2b, 0x14, 0xde, 0x80, 0xb2, 0xe1, 0xa9, 0xb3, 0x27, 0xe8, 0xf4,
|
||||
0x6e, 0x7a, 0xaf, 0xa0, 0x94, 0x0c, 0x2f, 0x7a, 0xbe, 0xab, 0x7e, 0x93, 0x86, 0x4a, 0xf2, 0x09,
|
||||
0x1d, 0x37, 0xa1, 0x60, 0xda, 0x1a, 0xe1, 0xa9, 0x25, 0xbe, 0xdf, 0xec, 0x3d, 0xe7, 0xd5, 0xbd,
|
||||
0xd6, 0x0e, 0xf8, 0x4a, 0xa4, 0xb9, 0xf3, 0x8f, 0x14, 0x14, 0x42, 0x18, 0x5f, 0x81, 0xac, 0x43,
|
||||
0xfc, 0x31, 0x37, 0x97, 0x3b, 0x4a, 0xa3, 0x94, 0xc2, 0xdb, 0x0c, 0xf7, 0x1c, 0x62, 0xf1, 0x14,
|
||||
0x08, 0x70, 0xd6, 0x66, 0xf3, 0x6a, 0x52, 0xa2, 0xf3, 0xcb, 0x89, 0x3d, 0x99, 0x50, 0xcb, 0xf7,
|
||||
0xc2, 0x79, 0x0d, 0xf0, 0x46, 0x00, 0xe3, 0x77, 0x60, 0xd3, 0x77, 0x89, 0x61, 0x26, 0xb8, 0x59,
|
||||
0xce, 0x45, 0xa1, 0x20, 0x22, 0x1f, 0xc2, 0xb5, 0xd0, 0xae, 0x4e, 0x7d, 0xa2, 0x8d, 0xa9, 0x3e,
|
||||
0x53, 0xca, 0xf3, 0xf7, 0xd9, 0xab, 0x01, 0xa1, 0x19, 0xc8, 0x43, 0xdd, 0xea, 0x77, 0x29, 0xd8,
|
||||
0x0c, 0xaf, 0x53, 0x7a, 0x14, 0xac, 0x53, 0x00, 0x62, 0x59, 0xb6, 0x1f, 0x0f, 0xd7, 0x62, 0x2a,
|
||||
0x2f, 0xe8, 0xd5, 0xea, 0x91, 0x92, 0x12, 0x33, 0xb0, 0x33, 0x01, 0x98, 0x49, 0x56, 0x86, 0xed,
|
||||
0x3a, 0x94, 0x82, 0xef, 0x23, 0xfc, 0x23, 0x9b, 0xb8, 0x80, 0x83, 0x80, 0xd8, 0xbd, 0x0b, 0x6f,
|
||||
0x43, 0xee, 0x9c, 0x8e, 0x0c, 0x2b, 0x78, 0xf5, 0x14, 0x8d, 0xf0, 0x25, 0x37, 0x1b, 0xbd, 0xe4,
|
||||
0x1e, 0xfd, 0x21, 0x05, 0x5b, 0x9a, 0x3d, 0x99, 0xf7, 0xf7, 0x08, 0xcd, 0xbd, 0x02, 0x78, 0x9f,
|
||||
0xa4, 0xbe, 0xf8, 0x78, 0x64, 0xf8, 0xe3, 0xe9, 0x79, 0x4d, 0xb3, 0x27, 0xfb, 0x23, 0xdb, 0x24,
|
||||
0xd6, 0x68, 0xf6, 0x95, 0x90, 0xff, 0xd1, 0xde, 0x1d, 0x51, 0xeb, 0xdd, 0x91, 0x1d, 0xfb, 0x66,
|
||||
0xf8, 0xd1, 0xec, 0xef, 0xd7, 0xe9, 0xcc, 0x71, 0xef, 0xe8, 0xaf, 0xe9, 0x9d, 0x63, 0xd1, 0x57,
|
||||
0x2f, 0x8c, 0x8d, 0x42, 0x87, 0x26, 0xd5, 0xd8, 0x78, 0xff, 0x17, 0x00, 0x00, 0xff, 0xff, 0x0c,
|
||||
0xab, 0xb6, 0x37, 0x7e, 0x1c, 0x00, 0x00,
|
||||
}
|
||||
|
|
|
|||
28
vendor/github.com/golang/protobuf/protoc-gen-go/descriptor/descriptor.proto
generated
vendored
28
vendor/github.com/golang/protobuf/protoc-gen-go/descriptor/descriptor.proto
generated
vendored
|
|
@ -101,6 +101,8 @@ message DescriptorProto {
|
|||
message ExtensionRange {
|
||||
optional int32 start = 1;
|
||||
optional int32 end = 2;
|
||||
|
||||
optional ExtensionRangeOptions options = 3;
|
||||
}
|
||||
repeated ExtensionRange extension_range = 5;
|
||||
|
||||
|
|
@ -121,6 +123,14 @@ message DescriptorProto {
|
|||
repeated string reserved_name = 10;
|
||||
}
|
||||
|
||||
message ExtensionRangeOptions {
|
||||
// The parser stores options it doesn't recognize here. See above.
|
||||
repeated UninterpretedOption uninterpreted_option = 999;
|
||||
|
||||
// Clients can define custom options in extensions of this message. See above.
|
||||
extensions 1000 to max;
|
||||
}
|
||||
|
||||
// Describes a field within a message.
|
||||
message FieldDescriptorProto {
|
||||
enum Type {
|
||||
|
|
@ -351,7 +361,7 @@ message FileOptions {
|
|||
optional bool cc_generic_services = 16 [default=false];
|
||||
optional bool java_generic_services = 17 [default=false];
|
||||
optional bool py_generic_services = 18 [default=false];
|
||||
optional bool php_generic_services = 19 [default=false];
|
||||
optional bool php_generic_services = 42 [default=false];
|
||||
|
||||
// Is this file deprecated?
|
||||
// Depending on the target platform, this can emit Deprecated annotations
|
||||
|
|
@ -483,13 +493,15 @@ message FieldOptions {
|
|||
|
||||
// The jstype option determines the JavaScript type used for values of the
|
||||
// field. The option is permitted only for 64 bit integral and fixed types
|
||||
// (int64, uint64, sint64, fixed64, sfixed64). By default these types are
|
||||
// represented as JavaScript strings. This avoids loss of precision that can
|
||||
// happen when a large value is converted to a floating point JavaScript
|
||||
// numbers. Specifying JS_NUMBER for the jstype causes the generated
|
||||
// JavaScript code to use the JavaScript "number" type instead of strings.
|
||||
// This option is an enum to permit additional types to be added,
|
||||
// e.g. goog.math.Integer.
|
||||
// (int64, uint64, sint64, fixed64, sfixed64). A field with jstype JS_STRING
|
||||
// is represented as JavaScript string, which avoids loss of precision that
|
||||
// can happen when a large value is converted to a floating point JavaScript.
|
||||
// Specifying JS_NUMBER for the jstype causes the generated JavaScript code to
|
||||
// use the JavaScript "number" type. The behavior of the default option
|
||||
// JS_NORMAL is implementation dependent.
|
||||
//
|
||||
// This option is an enum to permit additional types to be added, e.g.
|
||||
// goog.math.Integer.
|
||||
optional JSType jstype = 6 [default = JS_NORMAL];
|
||||
enum JSType {
|
||||
// Use the default type.
|
||||
|
|
|
|||
63
vendor/github.com/golang/protobuf/protoc-gen-go/generator/generator.go
generated
vendored
63
vendor/github.com/golang/protobuf/protoc-gen-go/generator/generator.go
generated
vendored
|
|
@ -1984,7 +1984,7 @@ func (g *Generator) generateMessage(message *Descriptor) {
|
|||
case typename == "string":
|
||||
def = strconv.Quote(def)
|
||||
case typename == "[]byte":
|
||||
def = "[]byte(" + strconv.Quote(def) + ")"
|
||||
def = "[]byte(" + strconv.Quote(unescape(def)) + ")"
|
||||
kind = "var "
|
||||
case def == "inf", def == "-inf", def == "nan":
|
||||
// These names are known to, and defined by, the protocol language.
|
||||
|
|
@ -2508,6 +2508,67 @@ func (g *Generator) generateMessage(message *Descriptor) {
|
|||
g.addInitf("%s.RegisterType((*%s)(nil), %q)", g.Pkg["proto"], ccTypeName, fullName)
|
||||
}
|
||||
|
||||
var escapeChars = [256]byte{
|
||||
'a': '\a', 'b': '\b', 'f': '\f', 'n': '\n', 'r': '\r', 't': '\t', 'v': '\v', '\\': '\\', '"': '"', '\'': '\'', '?': '?',
|
||||
}
|
||||
|
||||
// unescape reverses the "C" escaping that protoc does for default values of bytes fields.
|
||||
// It is best effort in that it effectively ignores malformed input. Seemingly invalid escape
|
||||
// sequences are conveyed, unmodified, into the decoded result.
|
||||
func unescape(s string) string {
|
||||
// NB: Sadly, we can't use strconv.Unquote because protoc will escape both
|
||||
// single and double quotes, but strconv.Unquote only allows one or the
|
||||
// other (based on actual surrounding quotes of its input argument).
|
||||
|
||||
var out []byte
|
||||
for len(s) > 0 {
|
||||
// regular character, or too short to be valid escape
|
||||
if s[0] != '\\' || len(s) < 2 {
|
||||
out = append(out, s[0])
|
||||
s = s[1:]
|
||||
} else if c := escapeChars[s[1]]; c != 0 {
|
||||
// escape sequence
|
||||
out = append(out, c)
|
||||
s = s[2:]
|
||||
} else if s[1] == 'x' || s[1] == 'X' {
|
||||
// hex escape, e.g. "\x80
|
||||
if len(s) < 4 {
|
||||
// too short to be valid
|
||||
out = append(out, s[:2]...)
|
||||
s = s[2:]
|
||||
continue
|
||||
}
|
||||
v, err := strconv.ParseUint(s[2:4], 16, 8)
|
||||
if err != nil {
|
||||
out = append(out, s[:4]...)
|
||||
} else {
|
||||
out = append(out, byte(v))
|
||||
}
|
||||
s = s[4:]
|
||||
} else if '0' <= s[1] && s[1] <= '7' {
|
||||
// octal escape, can vary from 1 to 3 octal digits; e.g., "\0" "\40" or "\164"
|
||||
// so consume up to 2 more bytes or up to end-of-string
|
||||
n := len(s[1:]) - len(strings.TrimLeft(s[1:], "01234567"))
|
||||
if n > 3 {
|
||||
n = 3
|
||||
}
|
||||
v, err := strconv.ParseUint(s[1:1+n], 8, 8)
|
||||
if err != nil {
|
||||
out = append(out, s[:1+n]...)
|
||||
} else {
|
||||
out = append(out, byte(v))
|
||||
}
|
||||
s = s[1+n:]
|
||||
} else {
|
||||
// bad escape, just propagate the slash as-is
|
||||
out = append(out, s[0])
|
||||
s = s[1:]
|
||||
}
|
||||
}
|
||||
|
||||
return string(out)
|
||||
}
|
||||
|
||||
func (g *Generator) generateExtension(ext *ExtensionDescriptor) {
|
||||
ccTypeName := ext.DescName()
|
||||
|
||||
|
|
|
|||
29
vendor/github.com/golang/protobuf/protoc-gen-go/generator/name_test.go
generated
vendored
29
vendor/github.com/golang/protobuf/protoc-gen-go/generator/name_test.go
generated
vendored
|
|
@ -83,3 +83,32 @@ func TestGoPackageOption(t *testing.T) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestUnescape(t *testing.T) {
|
||||
tests := []struct {
|
||||
in string
|
||||
out string
|
||||
}{
|
||||
// successful cases, including all kinds of escapes
|
||||
{"", ""},
|
||||
{"foo bar baz frob nitz", "foo bar baz frob nitz"},
|
||||
{`\000\001\002\003\004\005\006\007`, string([]byte{0, 1, 2, 3, 4, 5, 6, 7})},
|
||||
{`\a\b\f\n\r\t\v\\\?\'\"`, string([]byte{'\a', '\b', '\f', '\n', '\r', '\t', '\v', '\\', '?', '\'', '"'})},
|
||||
{`\x10\x20\x30\x40\x50\x60\x70\x80`, string([]byte{16, 32, 48, 64, 80, 96, 112, 128})},
|
||||
// variable length octal escapes
|
||||
{`\0\018\222\377\3\04\005\6\07`, string([]byte{0, 1, '8', 0222, 255, 3, 4, 5, 6, 7})},
|
||||
// malformed escape sequences left as is
|
||||
{"foo \\g bar", "foo \\g bar"},
|
||||
{"foo \\xg0 bar", "foo \\xg0 bar"},
|
||||
{"\\", "\\"},
|
||||
{"\\x", "\\x"},
|
||||
{"\\xf", "\\xf"},
|
||||
{"\\777", "\\777"}, // overflows byte
|
||||
}
|
||||
for _, tc := range tests {
|
||||
s := unescape(tc.in)
|
||||
if s != tc.out {
|
||||
t.Errorf("doUnescape(%q) = %q; should have been %q", tc.in, s, tc.out)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
1
vendor/github.com/golang/protobuf/protoc-gen-go/plugin/plugin.proto
generated
vendored
1
vendor/github.com/golang/protobuf/protoc-gen-go/plugin/plugin.proto
generated
vendored
|
|
@ -91,6 +91,7 @@ message CodeGeneratorRequest {
|
|||
|
||||
// The version number of protocol compiler.
|
||||
optional Version compiler_version = 3;
|
||||
|
||||
}
|
||||
|
||||
// The plugin writes an encoded CodeGeneratorResponse to stdout.
|
||||
|
|
|
|||
10
vendor/github.com/golang/protobuf/ptypes/any/any.pb.go
generated
vendored
10
vendor/github.com/golang/protobuf/ptypes/any/any.pb.go
generated
vendored
|
|
@ -62,6 +62,16 @@ const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
|
|||
// any.Unpack(foo)
|
||||
// ...
|
||||
//
|
||||
// Example 4: Pack and unpack a message in Go
|
||||
//
|
||||
// foo := &pb.Foo{...}
|
||||
// any, err := ptypes.MarshalAny(foo)
|
||||
// ...
|
||||
// foo := &pb.Foo{}
|
||||
// if err := ptypes.UnmarshalAny(any, foo); err != nil {
|
||||
// ...
|
||||
// }
|
||||
//
|
||||
// The pack methods provided by protobuf library will by default use
|
||||
// 'type.googleapis.com/full.type.name' as the type URL and the unpack
|
||||
// methods only use the fully qualified type name after the last '/'
|
||||
|
|
|
|||
10
vendor/github.com/golang/protobuf/ptypes/any/any.proto
generated
vendored
10
vendor/github.com/golang/protobuf/ptypes/any/any.proto
generated
vendored
|
|
@ -74,6 +74,16 @@ option objc_class_prefix = "GPB";
|
|||
// any.Unpack(foo)
|
||||
// ...
|
||||
//
|
||||
// Example 4: Pack and unpack a message in Go
|
||||
//
|
||||
// foo := &pb.Foo{...}
|
||||
// any, err := ptypes.MarshalAny(foo)
|
||||
// ...
|
||||
// foo := &pb.Foo{}
|
||||
// if err := ptypes.UnmarshalAny(any, foo); err != nil {
|
||||
// ...
|
||||
// }
|
||||
//
|
||||
// The pack methods provided by protobuf library will by default use
|
||||
// 'type.googleapis.com/full.type.name' as the type URL and the unpack
|
||||
// methods only use the fully qualified type name after the last '/'
|
||||
|
|
|
|||
50
vendor/github.com/gorilla/mux/README.md
generated
vendored
50
vendor/github.com/gorilla/mux/README.md
generated
vendored
|
|
@ -15,7 +15,7 @@ The name mux stands for "HTTP request multiplexer". Like the standard `http.Serv
|
|||
|
||||
* It implements the `http.Handler` interface so it is compatible with the standard `http.ServeMux`.
|
||||
* Requests can be matched based on URL host, path, path prefix, schemes, header and query values, HTTP methods or using custom matchers.
|
||||
* URL hosts and paths can have variables with an optional regular expression.
|
||||
* URL hosts, paths and query values can have variables with an optional regular expression.
|
||||
* Registered URLs can be built, or "reversed", which helps maintaining references to resources.
|
||||
* Routes can be used as subrouters: nested routes are only tested if the parent route matches. This is useful to define groups of routes that share common conditions like a host, a path prefix or other repeated attributes. As a bonus, this optimizes request matching.
|
||||
|
||||
|
|
@ -24,9 +24,9 @@ The name mux stands for "HTTP request multiplexer". Like the standard `http.Serv
|
|||
* [Install](#install)
|
||||
* [Examples](#examples)
|
||||
* [Matching Routes](#matching-routes)
|
||||
* [Listing Routes](#listing-routes)
|
||||
* [Static Files](#static-files)
|
||||
* [Registered URLs](#registered-urls)
|
||||
* [Walking Routes](#walking-routes)
|
||||
* [Full Example](#full-example)
|
||||
|
||||
---
|
||||
|
|
@ -168,7 +168,6 @@ s.HandleFunc("/{key}/", ProductHandler)
|
|||
// "/products/{key}/details"
|
||||
s.HandleFunc("/{key}/details", ProductDetailsHandler)
|
||||
```
|
||||
|
||||
### Listing Routes
|
||||
|
||||
Routes on a mux can be listed using the Router.Walk method—useful for generating documentation:
|
||||
|
|
@ -191,9 +190,9 @@ func handler(w http.ResponseWriter, r *http.Request) {
|
|||
func main() {
|
||||
r := mux.NewRouter()
|
||||
r.HandleFunc("/", handler)
|
||||
r.Methods("POST").HandleFunc("/products", handler)
|
||||
r.Methods("GET").HandleFunc("/articles", handler)
|
||||
r.Methods("GET", "PUT").HandleFunc("/articles/{id}", handler)
|
||||
r.HandleFunc("/products", handler).Methods("POST")
|
||||
r.HandleFunc("/articles", handler).Methods("GET")
|
||||
r.HandleFunc("/articles/{id}", handler).Methods("GET", "PUT")
|
||||
r.Walk(func(route *mux.Route, router *mux.Router, ancestors []*mux.Route) error {
|
||||
t, err := route.GetPathTemplate()
|
||||
if err != nil {
|
||||
|
|
@ -269,19 +268,21 @@ url, err := r.Get("article").URL("category", "technology", "id", "42")
|
|||
"/articles/technology/42"
|
||||
```
|
||||
|
||||
This also works for host variables:
|
||||
This also works for host and query value variables:
|
||||
|
||||
```go
|
||||
r := mux.NewRouter()
|
||||
r.Host("{subdomain}.domain.com").
|
||||
Path("/articles/{category}/{id:[0-9]+}").
|
||||
Queries("filter", "{filter}").
|
||||
HandlerFunc(ArticleHandler).
|
||||
Name("article")
|
||||
|
||||
// url.String() will be "http://news.domain.com/articles/technology/42"
|
||||
// url.String() will be "http://news.domain.com/articles/technology/42?filter=gorilla"
|
||||
url, err := r.Get("article").URL("subdomain", "news",
|
||||
"category", "technology",
|
||||
"id", "42")
|
||||
"id", "42",
|
||||
"filter", "gorilla")
|
||||
```
|
||||
|
||||
All variables defined in the route are required, and their values must conform to the corresponding patterns. These requirements guarantee that a generated URL will always match a registered route -- the only exception is for explicitly defined "build-only" routes which never match.
|
||||
|
|
@ -319,6 +320,37 @@ url, err := r.Get("article").URL("subdomain", "news",
|
|||
"id", "42")
|
||||
```
|
||||
|
||||
### Walking Routes
|
||||
|
||||
The `Walk` function on `mux.Router` can be used to visit all of the routes that are registered on a router. For example,
|
||||
the following prints all of the registered routes:
|
||||
|
||||
```go
|
||||
r := mux.NewRouter()
|
||||
r.HandleFunc("/", handler)
|
||||
r.HandleFunc("/products", handler).Methods("POST")
|
||||
r.HandleFunc("/articles", handler).Methods("GET")
|
||||
r.HandleFunc("/articles/{id}", handler).Methods("GET", "PUT")
|
||||
r.Walk(func(route *mux.Route, router *mux.Router, ancestors []*mux.Route) error {
|
||||
t, err := route.GetPathTemplate()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// p will contain a regular expression that is compatible with regular expressions in Perl, Python, and other languages.
|
||||
// For example, the regular expression for path '/articles/{id}' will be '^/articles/(?P<v0>[^/]+)$'.
|
||||
p, err := route.GetPathRegexp()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
m, err := route.GetMethods()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Println(strings.Join(m, ","), t, p)
|
||||
return nil
|
||||
})
|
||||
```
|
||||
|
||||
## Full Example
|
||||
|
||||
Here's a complete, runnable example of a small `mux` based server:
|
||||
|
|
|
|||
12
vendor/github.com/gorilla/mux/doc.go
generated
vendored
12
vendor/github.com/gorilla/mux/doc.go
generated
vendored
|
|
@ -12,8 +12,8 @@ or other conditions. The main features are:
|
|||
|
||||
* Requests can be matched based on URL host, path, path prefix, schemes,
|
||||
header and query values, HTTP methods or using custom matchers.
|
||||
* URL hosts and paths can have variables with an optional regular
|
||||
expression.
|
||||
* URL hosts, paths and query values can have variables with an optional
|
||||
regular expression.
|
||||
* Registered URLs can be built, or "reversed", which helps maintaining
|
||||
references to resources.
|
||||
* Routes can be used as subrouters: nested routes are only tested if the
|
||||
|
|
@ -188,18 +188,20 @@ key/value pairs for the route variables. For the previous route, we would do:
|
|||
|
||||
"/articles/technology/42"
|
||||
|
||||
This also works for host variables:
|
||||
This also works for host and query value variables:
|
||||
|
||||
r := mux.NewRouter()
|
||||
r.Host("{subdomain}.domain.com").
|
||||
Path("/articles/{category}/{id:[0-9]+}").
|
||||
Queries("filter", "{filter}").
|
||||
HandlerFunc(ArticleHandler).
|
||||
Name("article")
|
||||
|
||||
// url.String() will be "http://news.domain.com/articles/technology/42"
|
||||
// url.String() will be "http://news.domain.com/articles/technology/42?filter=gorilla"
|
||||
url, err := r.Get("article").URL("subdomain", "news",
|
||||
"category", "technology",
|
||||
"id", "42")
|
||||
"id", "42",
|
||||
"filter", "gorilla")
|
||||
|
||||
All variables defined in the route are required, and their values must
|
||||
conform to the corresponding patterns. These requirements guarantee that a
|
||||
|
|
|
|||
48
vendor/github.com/gorilla/mux/mux.go
generated
vendored
48
vendor/github.com/gorilla/mux/mux.go
generated
vendored
|
|
@ -13,6 +13,10 @@ import (
|
|||
"strings"
|
||||
)
|
||||
|
||||
var (
|
||||
ErrMethodMismatch = errors.New("method is not allowed")
|
||||
)
|
||||
|
||||
// NewRouter returns a new router instance.
|
||||
func NewRouter() *Router {
|
||||
return &Router{namedRoutes: make(map[string]*Route), KeepContext: false}
|
||||
|
|
@ -39,6 +43,10 @@ func NewRouter() *Router {
|
|||
type Router struct {
|
||||
// Configurable Handler to be used when no route matches.
|
||||
NotFoundHandler http.Handler
|
||||
|
||||
// Configurable Handler to be used when the request method does not match the route.
|
||||
MethodNotAllowedHandler http.Handler
|
||||
|
||||
// Parent route, if this is a subrouter.
|
||||
parent parentRoute
|
||||
// Routes to be matched, in order.
|
||||
|
|
@ -65,6 +73,11 @@ func (r *Router) Match(req *http.Request, match *RouteMatch) bool {
|
|||
}
|
||||
}
|
||||
|
||||
if match.MatchErr == ErrMethodMismatch && r.MethodNotAllowedHandler != nil {
|
||||
match.Handler = r.MethodNotAllowedHandler
|
||||
return true
|
||||
}
|
||||
|
||||
// Closest match for a router (includes sub-routers)
|
||||
if r.NotFoundHandler != nil {
|
||||
match.Handler = r.NotFoundHandler
|
||||
|
|
@ -105,9 +118,15 @@ func (r *Router) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
|||
req = setVars(req, match.Vars)
|
||||
req = setCurrentRoute(req, match.Route)
|
||||
}
|
||||
|
||||
if handler == nil && match.MatchErr == ErrMethodMismatch {
|
||||
handler = methodNotAllowedHandler()
|
||||
}
|
||||
|
||||
if handler == nil {
|
||||
handler = http.NotFoundHandler()
|
||||
}
|
||||
|
||||
if !r.KeepContext {
|
||||
defer contextClear(req)
|
||||
}
|
||||
|
|
@ -176,6 +195,13 @@ func (r *Router) UseEncodedPath() *Router {
|
|||
// parentRoute
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
func (r *Router) getBuildScheme() string {
|
||||
if r.parent != nil {
|
||||
return r.parent.getBuildScheme()
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// getNamedRoutes returns the map where named routes are registered.
|
||||
func (r *Router) getNamedRoutes() map[string]*Route {
|
||||
if r.namedRoutes == nil {
|
||||
|
|
@ -299,10 +325,6 @@ type WalkFunc func(route *Route, router *Router, ancestors []*Route) error
|
|||
|
||||
func (r *Router) walk(walkFn WalkFunc, ancestors []*Route) error {
|
||||
for _, t := range r.routes {
|
||||
if t.regexp == nil || t.regexp.path == nil || t.regexp.path.template == "" {
|
||||
continue
|
||||
}
|
||||
|
||||
err := walkFn(t, r, ancestors)
|
||||
if err == SkipRouter {
|
||||
continue
|
||||
|
|
@ -312,10 +334,12 @@ func (r *Router) walk(walkFn WalkFunc, ancestors []*Route) error {
|
|||
}
|
||||
for _, sr := range t.matchers {
|
||||
if h, ok := sr.(*Router); ok {
|
||||
ancestors = append(ancestors, t)
|
||||
err := h.walk(walkFn, ancestors)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
ancestors = ancestors[:len(ancestors)-1]
|
||||
}
|
||||
}
|
||||
if h, ok := t.handler.(*Router); ok {
|
||||
|
|
@ -339,6 +363,11 @@ type RouteMatch struct {
|
|||
Route *Route
|
||||
Handler http.Handler
|
||||
Vars map[string]string
|
||||
|
||||
// MatchErr is set to appropriate matching error
|
||||
// It is set to ErrMethodMismatch if there is a mismatch in
|
||||
// the request method and route method
|
||||
MatchErr error
|
||||
}
|
||||
|
||||
type contextKey int
|
||||
|
|
@ -458,7 +487,7 @@ func mapFromPairsToString(pairs ...string) (map[string]string, error) {
|
|||
return m, nil
|
||||
}
|
||||
|
||||
// mapFromPairsToRegex converts variadic string paramers to a
|
||||
// mapFromPairsToRegex converts variadic string parameters to a
|
||||
// string to regex map.
|
||||
func mapFromPairsToRegex(pairs ...string) (map[string]*regexp.Regexp, error) {
|
||||
length, err := checkPairs(pairs...)
|
||||
|
|
@ -540,3 +569,12 @@ func matchMapWithRegex(toCheck map[string]*regexp.Regexp, toMatch map[string][]s
|
|||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// methodNotAllowed replies to the request with an HTTP status code 405.
|
||||
func methodNotAllowed(w http.ResponseWriter, r *http.Request) {
|
||||
w.WriteHeader(http.StatusMethodNotAllowed)
|
||||
}
|
||||
|
||||
// methodNotAllowedHandler returns a simple request handler
|
||||
// that replies to each request with a status code 405.
|
||||
func methodNotAllowedHandler() http.Handler { return http.HandlerFunc(methodNotAllowed) }
|
||||
|
|
|
|||
145
vendor/github.com/gorilla/mux/mux_test.go
generated
vendored
145
vendor/github.com/gorilla/mux/mux_test.go
generated
vendored
|
|
@ -11,6 +11,7 @@ import (
|
|||
"fmt"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"reflect"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
|
@ -35,6 +36,7 @@ type routeTest struct {
|
|||
scheme string // the expected scheme of the built URL
|
||||
host string // the expected host of the built URL
|
||||
path string // the expected path of the built URL
|
||||
query string // the expected query string of the built URL
|
||||
pathTemplate string // the expected path template of the route
|
||||
hostTemplate string // the expected host template of the route
|
||||
methods []string // the expected route methods
|
||||
|
|
@ -743,6 +745,7 @@ func TestQueries(t *testing.T) {
|
|||
vars: map[string]string{},
|
||||
host: "",
|
||||
path: "",
|
||||
query: "foo=bar&baz=ding",
|
||||
shouldMatch: true,
|
||||
},
|
||||
{
|
||||
|
|
@ -752,6 +755,7 @@ func TestQueries(t *testing.T) {
|
|||
vars: map[string]string{},
|
||||
host: "",
|
||||
path: "",
|
||||
query: "foo=bar&baz=ding",
|
||||
pathTemplate: `/api`,
|
||||
hostTemplate: `www.example.com`,
|
||||
shouldMatch: true,
|
||||
|
|
@ -763,6 +767,7 @@ func TestQueries(t *testing.T) {
|
|||
vars: map[string]string{},
|
||||
host: "",
|
||||
path: "",
|
||||
query: "foo=bar&baz=ding",
|
||||
pathTemplate: `/api`,
|
||||
hostTemplate: `www.example.com`,
|
||||
shouldMatch: true,
|
||||
|
|
@ -783,6 +788,7 @@ func TestQueries(t *testing.T) {
|
|||
vars: map[string]string{"v1": "bar"},
|
||||
host: "",
|
||||
path: "",
|
||||
query: "foo=bar",
|
||||
shouldMatch: true,
|
||||
},
|
||||
{
|
||||
|
|
@ -792,6 +798,7 @@ func TestQueries(t *testing.T) {
|
|||
vars: map[string]string{"v1": "bar", "v2": "ding"},
|
||||
host: "",
|
||||
path: "",
|
||||
query: "foo=bar&baz=ding",
|
||||
shouldMatch: true,
|
||||
},
|
||||
{
|
||||
|
|
@ -801,6 +808,7 @@ func TestQueries(t *testing.T) {
|
|||
vars: map[string]string{"v1": "10"},
|
||||
host: "",
|
||||
path: "",
|
||||
query: "foo=10",
|
||||
shouldMatch: true,
|
||||
},
|
||||
{
|
||||
|
|
@ -819,6 +827,7 @@ func TestQueries(t *testing.T) {
|
|||
vars: map[string]string{"v1": "1"},
|
||||
host: "",
|
||||
path: "",
|
||||
query: "foo=1",
|
||||
shouldMatch: true,
|
||||
},
|
||||
{
|
||||
|
|
@ -828,6 +837,7 @@ func TestQueries(t *testing.T) {
|
|||
vars: map[string]string{"v1": "1"},
|
||||
host: "",
|
||||
path: "",
|
||||
query: "foo=1",
|
||||
shouldMatch: true,
|
||||
},
|
||||
{
|
||||
|
|
@ -846,6 +856,7 @@ func TestQueries(t *testing.T) {
|
|||
vars: map[string]string{"v1": "1a"},
|
||||
host: "",
|
||||
path: "",
|
||||
query: "foo=1a",
|
||||
shouldMatch: true,
|
||||
},
|
||||
{
|
||||
|
|
@ -864,6 +875,7 @@ func TestQueries(t *testing.T) {
|
|||
vars: map[string]string{"v-1": "bar"},
|
||||
host: "",
|
||||
path: "",
|
||||
query: "foo=bar",
|
||||
shouldMatch: true,
|
||||
},
|
||||
{
|
||||
|
|
@ -873,6 +885,7 @@ func TestQueries(t *testing.T) {
|
|||
vars: map[string]string{"v-1": "bar", "v-2": "ding"},
|
||||
host: "",
|
||||
path: "",
|
||||
query: "foo=bar&baz=ding",
|
||||
shouldMatch: true,
|
||||
},
|
||||
{
|
||||
|
|
@ -882,6 +895,7 @@ func TestQueries(t *testing.T) {
|
|||
vars: map[string]string{"v-1": "10"},
|
||||
host: "",
|
||||
path: "",
|
||||
query: "foo=10",
|
||||
shouldMatch: true,
|
||||
},
|
||||
{
|
||||
|
|
@ -891,6 +905,7 @@ func TestQueries(t *testing.T) {
|
|||
vars: map[string]string{"v-1": "1a"},
|
||||
host: "",
|
||||
path: "",
|
||||
query: "foo=1a",
|
||||
shouldMatch: true,
|
||||
},
|
||||
{
|
||||
|
|
@ -900,6 +915,7 @@ func TestQueries(t *testing.T) {
|
|||
vars: map[string]string{},
|
||||
host: "",
|
||||
path: "",
|
||||
query: "foo=",
|
||||
shouldMatch: true,
|
||||
},
|
||||
{
|
||||
|
|
@ -918,6 +934,7 @@ func TestQueries(t *testing.T) {
|
|||
vars: map[string]string{},
|
||||
host: "",
|
||||
path: "",
|
||||
query: "foo=",
|
||||
shouldMatch: true,
|
||||
},
|
||||
{
|
||||
|
|
@ -945,6 +962,7 @@ func TestQueries(t *testing.T) {
|
|||
vars: map[string]string{"foo": ""},
|
||||
host: "",
|
||||
path: "",
|
||||
query: "foo=",
|
||||
shouldMatch: true,
|
||||
},
|
||||
{
|
||||
|
|
@ -956,6 +974,16 @@ func TestQueries(t *testing.T) {
|
|||
path: "",
|
||||
shouldMatch: false,
|
||||
},
|
||||
{
|
||||
title: "Queries route with pattern, match, escaped value",
|
||||
route: new(Route).Queries("foo", "{v1}"),
|
||||
request: newRequest("GET", "http://localhost?foo=%25bar%26%20%2F%3D%3F"),
|
||||
vars: map[string]string{"v1": "%bar& /=?"},
|
||||
host: "",
|
||||
path: "",
|
||||
query: "foo=%25bar%26+%2F%3D%3F",
|
||||
shouldMatch: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
|
|
@ -1187,6 +1215,28 @@ func TestSubRouter(t *testing.T) {
|
|||
pathTemplate: `/{category}`,
|
||||
shouldMatch: true,
|
||||
},
|
||||
{
|
||||
title: "Build with scheme on parent router",
|
||||
route: new(Route).Schemes("ftp").Host("google.com").Subrouter().Path("/"),
|
||||
request: newRequest("GET", "ftp://google.com/"),
|
||||
scheme: "ftp",
|
||||
host: "google.com",
|
||||
path: "/",
|
||||
pathTemplate: `/`,
|
||||
hostTemplate: `google.com`,
|
||||
shouldMatch: true,
|
||||
},
|
||||
{
|
||||
title: "Prefer scheme on child route when building URLs",
|
||||
route: new(Route).Schemes("https", "ftp").Host("google.com").Subrouter().Schemes("ftp").Path("/"),
|
||||
request: newRequest("GET", "ftp://google.com/"),
|
||||
scheme: "ftp",
|
||||
host: "google.com",
|
||||
path: "/",
|
||||
pathTemplate: `/`,
|
||||
hostTemplate: `google.com`,
|
||||
shouldMatch: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
|
|
@ -1382,11 +1432,55 @@ func TestWalkNested(t *testing.T) {
|
|||
l2 := l1.PathPrefix("/l").Subrouter()
|
||||
l2.Path("/a")
|
||||
|
||||
paths := []string{"/g", "/g/o", "/g/o/r", "/g/o/r/i", "/g/o/r/i/l", "/g/o/r/i/l/l", "/g/o/r/i/l/l/a"}
|
||||
testCases := []struct {
|
||||
path string
|
||||
ancestors []*Route
|
||||
}{
|
||||
{"/g", []*Route{}},
|
||||
{"/g/o", []*Route{g.parent.(*Route)}},
|
||||
{"/g/o/r", []*Route{g.parent.(*Route), o.parent.(*Route)}},
|
||||
{"/g/o/r/i", []*Route{g.parent.(*Route), o.parent.(*Route), r.parent.(*Route)}},
|
||||
{"/g/o/r/i/l", []*Route{g.parent.(*Route), o.parent.(*Route), r.parent.(*Route), i.parent.(*Route)}},
|
||||
{"/g/o/r/i/l/l", []*Route{g.parent.(*Route), o.parent.(*Route), r.parent.(*Route), i.parent.(*Route), l1.parent.(*Route)}},
|
||||
{"/g/o/r/i/l/l/a", []*Route{g.parent.(*Route), o.parent.(*Route), r.parent.(*Route), i.parent.(*Route), l1.parent.(*Route), l2.parent.(*Route)}},
|
||||
}
|
||||
|
||||
idx := 0
|
||||
err := router.Walk(func(route *Route, router *Router, ancestors []*Route) error {
|
||||
path := testCases[idx].path
|
||||
tpl := route.regexp.path.template
|
||||
if tpl != path {
|
||||
t.Errorf(`Expected %s got %s`, path, tpl)
|
||||
}
|
||||
currWantAncestors := testCases[idx].ancestors
|
||||
if !reflect.DeepEqual(currWantAncestors, ancestors) {
|
||||
t.Errorf(`Expected %+v got %+v`, currWantAncestors, ancestors)
|
||||
}
|
||||
idx++
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if idx != len(testCases) {
|
||||
t.Errorf("Expected %d routes, found %d", len(testCases), idx)
|
||||
}
|
||||
}
|
||||
|
||||
func TestWalkSubrouters(t *testing.T) {
|
||||
router := NewRouter()
|
||||
|
||||
g := router.Path("/g").Subrouter()
|
||||
o := g.PathPrefix("/o").Subrouter()
|
||||
o.Methods("GET")
|
||||
o.Methods("PUT")
|
||||
|
||||
// all 4 routes should be matched, but final 2 routes do not have path templates
|
||||
paths := []string{"/g", "/g/o", "", ""}
|
||||
idx := 0
|
||||
err := router.Walk(func(route *Route, router *Router, ancestors []*Route) error {
|
||||
path := paths[idx]
|
||||
tpl := route.regexp.path.template
|
||||
tpl, _ := route.GetPathTemplate()
|
||||
if tpl != path {
|
||||
t.Errorf(`Expected %s got %s`, path, tpl)
|
||||
}
|
||||
|
|
@ -1492,6 +1586,7 @@ func testRoute(t *testing.T, test routeTest) {
|
|||
route := test.route
|
||||
vars := test.vars
|
||||
shouldMatch := test.shouldMatch
|
||||
query := test.query
|
||||
shouldRedirect := test.shouldRedirect
|
||||
uri := url.URL{
|
||||
Scheme: test.scheme,
|
||||
|
|
@ -1561,6 +1656,13 @@ func testRoute(t *testing.T, test routeTest) {
|
|||
return
|
||||
}
|
||||
}
|
||||
if query != "" {
|
||||
u, _ := route.URL(mapToPairs(match.Vars)...)
|
||||
if query != u.RawQuery {
|
||||
t.Errorf("(%v) URL query not equal: expected %v, got %v", test.title, query, u.RawQuery)
|
||||
return
|
||||
}
|
||||
}
|
||||
if shouldRedirect && match.Handler == nil {
|
||||
t.Errorf("(%v) Did not redirect", test.title)
|
||||
return
|
||||
|
|
@ -1769,3 +1871,42 @@ func newRequest(method, url string) *http.Request {
|
|||
}
|
||||
return req
|
||||
}
|
||||
|
||||
func TestNoMatchMethodErrorHandler(t *testing.T) {
|
||||
func1 := func(w http.ResponseWriter, r *http.Request) {}
|
||||
|
||||
r := NewRouter()
|
||||
r.HandleFunc("/", func1).Methods("GET", "POST")
|
||||
|
||||
req, _ := http.NewRequest("PUT", "http://localhost/", nil)
|
||||
match := new(RouteMatch)
|
||||
matched := r.Match(req, match)
|
||||
|
||||
if matched {
|
||||
t.Error("Should not have matched route for methods")
|
||||
}
|
||||
|
||||
if match.MatchErr != ErrMethodMismatch {
|
||||
t.Error("Should get ErrMethodMismatch error")
|
||||
}
|
||||
|
||||
resp := NewRecorder()
|
||||
r.ServeHTTP(resp, req)
|
||||
if resp.Code != 405 {
|
||||
t.Errorf("Expecting code %v", 405)
|
||||
}
|
||||
|
||||
// Add matching route
|
||||
r.HandleFunc("/", func1).Methods("PUT")
|
||||
|
||||
match = new(RouteMatch)
|
||||
matched = r.Match(req, match)
|
||||
|
||||
if !matched {
|
||||
t.Error("Should have matched route for methods")
|
||||
}
|
||||
|
||||
if match.MatchErr != nil {
|
||||
t.Error("Should not have any matching error. Found:", match.MatchErr)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
8
vendor/github.com/gorilla/mux/old_test.go
generated
vendored
8
vendor/github.com/gorilla/mux/old_test.go
generated
vendored
|
|
@ -121,12 +121,7 @@ func TestRouteMatchers(t *testing.T) {
|
|||
var routeMatch RouteMatch
|
||||
matched := router.Match(request, &routeMatch)
|
||||
if matched != shouldMatch {
|
||||
// Need better messages. :)
|
||||
if matched {
|
||||
t.Errorf("Should match.")
|
||||
} else {
|
||||
t.Errorf("Should not match.")
|
||||
}
|
||||
t.Errorf("Expected: %v\nGot: %v\nRequest: %v %v", shouldMatch, matched, request.Method, url)
|
||||
}
|
||||
|
||||
if matched {
|
||||
|
|
@ -188,7 +183,6 @@ func TestRouteMatchers(t *testing.T) {
|
|||
match(true)
|
||||
|
||||
// 2nd route --------------------------------------------------------------
|
||||
|
||||
// Everything match.
|
||||
reset2()
|
||||
match(true)
|
||||
|
|
|
|||
5
vendor/github.com/gorilla/mux/regexp.go
generated
vendored
5
vendor/github.com/gorilla/mux/regexp.go
generated
vendored
|
|
@ -35,7 +35,7 @@ func newRouteRegexp(tpl string, matchHost, matchPrefix, matchQuery, strictSlash,
|
|||
// Now let's parse it.
|
||||
defaultPattern := "[^/]+"
|
||||
if matchQuery {
|
||||
defaultPattern = "[^?&]*"
|
||||
defaultPattern = ".*"
|
||||
} else if matchHost {
|
||||
defaultPattern = "[^.]+"
|
||||
matchPrefix = false
|
||||
|
|
@ -178,6 +178,9 @@ func (r *routeRegexp) url(values map[string]string) (string, error) {
|
|||
if !ok {
|
||||
return "", fmt.Errorf("mux: missing route variable %q", v)
|
||||
}
|
||||
if r.matchQuery {
|
||||
value = url.QueryEscape(value)
|
||||
}
|
||||
urlValues[k] = value
|
||||
}
|
||||
rv := fmt.Sprintf(r.reverse, urlValues...)
|
||||
|
|
|
|||
50
vendor/github.com/gorilla/mux/route.go
generated
vendored
50
vendor/github.com/gorilla/mux/route.go
generated
vendored
|
|
@ -52,12 +52,27 @@ func (r *Route) Match(req *http.Request, match *RouteMatch) bool {
|
|||
if r.buildOnly || r.err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
var matchErr error
|
||||
|
||||
// Match everything.
|
||||
for _, m := range r.matchers {
|
||||
if matched := m.Match(req, match); !matched {
|
||||
if _, ok := m.(methodMatcher); ok {
|
||||
matchErr = ErrMethodMismatch
|
||||
continue
|
||||
}
|
||||
matchErr = nil
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
if matchErr != nil {
|
||||
match.MatchErr = matchErr
|
||||
return false
|
||||
}
|
||||
|
||||
match.MatchErr = nil
|
||||
// Yay, we have a match. Let's collect some info about it.
|
||||
if match.Route == nil {
|
||||
match.Route = r
|
||||
|
|
@ -68,6 +83,7 @@ func (r *Route) Match(req *http.Request, match *RouteMatch) bool {
|
|||
if match.Vars == nil {
|
||||
match.Vars = make(map[string]string)
|
||||
}
|
||||
|
||||
// Set variables.
|
||||
if r.regexp != nil {
|
||||
r.regexp.setMatch(req, match, r)
|
||||
|
|
@ -482,13 +498,14 @@ func (r *Route) URL(pairs ...string) (*url.URL, error) {
|
|||
return nil, err
|
||||
}
|
||||
var scheme, host, path string
|
||||
queries := make([]string, 0, len(r.regexp.queries))
|
||||
if r.regexp.host != nil {
|
||||
if host, err = r.regexp.host.url(values); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
scheme = "http"
|
||||
if r.buildScheme != "" {
|
||||
scheme = r.buildScheme
|
||||
if s := r.getBuildScheme(); s != "" {
|
||||
scheme = s
|
||||
}
|
||||
}
|
||||
if r.regexp.path != nil {
|
||||
|
|
@ -496,10 +513,18 @@ func (r *Route) URL(pairs ...string) (*url.URL, error) {
|
|||
return nil, err
|
||||
}
|
||||
}
|
||||
for _, q := range r.regexp.queries {
|
||||
var query string
|
||||
if query, err = q.url(values); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
queries = append(queries, query)
|
||||
}
|
||||
return &url.URL{
|
||||
Scheme: scheme,
|
||||
Host: host,
|
||||
Path: path,
|
||||
Scheme: scheme,
|
||||
Host: host,
|
||||
Path: path,
|
||||
RawQuery: strings.Join(queries, "&"),
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
|
@ -525,8 +550,8 @@ func (r *Route) URLHost(pairs ...string) (*url.URL, error) {
|
|||
Scheme: "http",
|
||||
Host: host,
|
||||
}
|
||||
if r.buildScheme != "" {
|
||||
u.Scheme = r.buildScheme
|
||||
if s := r.getBuildScheme(); s != "" {
|
||||
u.Scheme = s
|
||||
}
|
||||
return u, nil
|
||||
}
|
||||
|
|
@ -640,11 +665,22 @@ func (r *Route) buildVars(m map[string]string) map[string]string {
|
|||
|
||||
// parentRoute allows routes to know about parent host and path definitions.
|
||||
type parentRoute interface {
|
||||
getBuildScheme() string
|
||||
getNamedRoutes() map[string]*Route
|
||||
getRegexpGroup() *routeRegexpGroup
|
||||
buildVars(map[string]string) map[string]string
|
||||
}
|
||||
|
||||
func (r *Route) getBuildScheme() string {
|
||||
if r.buildScheme != "" {
|
||||
return r.buildScheme
|
||||
}
|
||||
if r.parent != nil {
|
||||
return r.parent.getBuildScheme()
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// getNamedRoutes returns the map where named routes are registered.
|
||||
func (r *Route) getNamedRoutes() map[string]*Route {
|
||||
if r.parent == nil {
|
||||
|
|
|
|||
2
vendor/github.com/hashicorp/hcl/decoder.go
generated
vendored
2
vendor/github.com/hashicorp/hcl/decoder.go
generated
vendored
|
|
@ -137,7 +137,7 @@ func (d *decoder) decodeBool(name string, node ast.Node, result reflect.Value) e
|
|||
func (d *decoder) decodeFloat(name string, node ast.Node, result reflect.Value) error {
|
||||
switch n := node.(type) {
|
||||
case *ast.LiteralType:
|
||||
if n.Token.Type == token.FLOAT {
|
||||
if n.Token.Type == token.FLOAT || n.Token.Type == token.NUMBER {
|
||||
v, err := strconv.ParseFloat(n.Token.Text, 64)
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
|
|||
9
vendor/github.com/hashicorp/hcl/decoder_test.go
generated
vendored
9
vendor/github.com/hashicorp/hcl/decoder_test.go
generated
vendored
|
|
@ -73,6 +73,7 @@ func TestDecode_interface(t *testing.T) {
|
|||
false,
|
||||
map[string]interface{}{
|
||||
"a": 1.02,
|
||||
"b": 2,
|
||||
},
|
||||
},
|
||||
{
|
||||
|
|
@ -811,6 +812,7 @@ func TestDecode_intString(t *testing.T) {
|
|||
func TestDecode_float32(t *testing.T) {
|
||||
var value struct {
|
||||
A float32 `hcl:"a"`
|
||||
B float32 `hcl:"b"`
|
||||
}
|
||||
|
||||
err := Decode(&value, testReadFile(t, "float.hcl"))
|
||||
|
|
@ -821,11 +823,15 @@ func TestDecode_float32(t *testing.T) {
|
|||
if got, want := value.A, float32(1.02); got != want {
|
||||
t.Fatalf("wrong result %#v; want %#v", got, want)
|
||||
}
|
||||
if got, want := value.B, float32(2); got != want {
|
||||
t.Fatalf("wrong result %#v; want %#v", got, want)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDecode_float64(t *testing.T) {
|
||||
var value struct {
|
||||
A float64 `hcl:"a"`
|
||||
B float64 `hcl:"b"`
|
||||
}
|
||||
|
||||
err := Decode(&value, testReadFile(t, "float.hcl"))
|
||||
|
|
@ -836,6 +842,9 @@ func TestDecode_float64(t *testing.T) {
|
|||
if got, want := value.A, float64(1.02); got != want {
|
||||
t.Fatalf("wrong result %#v; want %#v", got, want)
|
||||
}
|
||||
if got, want := value.B, float64(2); got != want {
|
||||
t.Fatalf("wrong result %#v; want %#v", got, want)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDecode_intStringAliased(t *testing.T) {
|
||||
|
|
|
|||
14
vendor/github.com/hashicorp/hcl/hcl/parser/parser.go
generated
vendored
14
vendor/github.com/hashicorp/hcl/hcl/parser/parser.go
generated
vendored
|
|
@ -197,9 +197,12 @@ func (p *Parser) objectItem() (*ast.ObjectItem, error) {
|
|||
keyStr = append(keyStr, k.Token.Text)
|
||||
}
|
||||
|
||||
return nil, fmt.Errorf(
|
||||
"key '%s' expected start of object ('{') or assignment ('=')",
|
||||
strings.Join(keyStr, " "))
|
||||
return nil, &PosError{
|
||||
Pos: p.tok.Pos,
|
||||
Err: fmt.Errorf(
|
||||
"key '%s' expected start of object ('{') or assignment ('=')",
|
||||
strings.Join(keyStr, " ")),
|
||||
}
|
||||
}
|
||||
|
||||
// do a look-ahead for line comment
|
||||
|
|
@ -319,7 +322,10 @@ func (p *Parser) objectType() (*ast.ObjectType, error) {
|
|||
|
||||
// No error, scan and expect the ending to be a brace
|
||||
if tok := p.scan(); tok.Type != token.RBRACE {
|
||||
return nil, fmt.Errorf("object expected closing RBRACE got: %s", tok.Type)
|
||||
return nil, &PosError{
|
||||
Pos: tok.Pos,
|
||||
Err: fmt.Errorf("object expected closing RBRACE got: %s", tok.Type),
|
||||
}
|
||||
}
|
||||
|
||||
o.List = l
|
||||
|
|
|
|||
1
vendor/github.com/hashicorp/hcl/test-fixtures/float.hcl
generated
vendored
1
vendor/github.com/hashicorp/hcl/test-fixtures/float.hcl
generated
vendored
|
|
@ -1 +1,2 @@
|
|||
a = 1.02
|
||||
b = 2
|
||||
|
|
|
|||
3
vendor/github.com/hashicorp/hcl/test-fixtures/float.json
generated
vendored
3
vendor/github.com/hashicorp/hcl/test-fixtures/float.json
generated
vendored
|
|
@ -1,3 +1,4 @@
|
|||
{
|
||||
"a": 1.02
|
||||
"a": 1.02,
|
||||
"b": 2
|
||||
}
|
||||
|
|
|
|||
4
vendor/github.com/hashicorp/memberlist/memberlist.go
generated
vendored
4
vendor/github.com/hashicorp/memberlist/memberlist.go
generated
vendored
|
|
@ -127,7 +127,7 @@ func newMemberlist(conf *Config) (*Memberlist, error) {
|
|||
return nt, nil
|
||||
}
|
||||
if strings.Contains(err.Error(), "address already in use") {
|
||||
logger.Printf("[DEBUG] Got bind error: %v", err)
|
||||
logger.Printf("[DEBUG] memberlist: Got bind error: %v", err)
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
|
@ -154,7 +154,7 @@ func newMemberlist(conf *Config) (*Memberlist, error) {
|
|||
port := nt.GetAutoBindPort()
|
||||
conf.BindPort = port
|
||||
conf.AdvertisePort = port
|
||||
logger.Printf("[DEBUG] Using dynamic bind port %d", port)
|
||||
logger.Printf("[DEBUG] memberlist: Using dynamic bind port %d", port)
|
||||
}
|
||||
transport = nt
|
||||
}
|
||||
|
|
|
|||
1
vendor/github.com/lib/pq/.travis.yml
generated
vendored
1
vendor/github.com/lib/pq/.travis.yml
generated
vendored
|
|
@ -5,6 +5,7 @@ go:
|
|||
- 1.6.x
|
||||
- 1.7.x
|
||||
- 1.8.x
|
||||
- 1.9.x
|
||||
- master
|
||||
|
||||
sudo: true
|
||||
|
|
|
|||
34
vendor/github.com/lib/pq/conn.go
generated
vendored
34
vendor/github.com/lib/pq/conn.go
generated
vendored
|
|
@ -706,7 +706,7 @@ func (noRows) RowsAffected() (int64, error) {
|
|||
|
||||
// Decides which column formats to use for a prepared statement. The input is
|
||||
// an array of type oids, one element per result column.
|
||||
func decideColumnFormats(colTyps []oid.Oid, forceText bool) (colFmts []format, colFmtData []byte) {
|
||||
func decideColumnFormats(colTyps []fieldDesc, forceText bool) (colFmts []format, colFmtData []byte) {
|
||||
if len(colTyps) == 0 {
|
||||
return nil, colFmtDataAllText
|
||||
}
|
||||
|
|
@ -718,8 +718,8 @@ func decideColumnFormats(colTyps []oid.Oid, forceText bool) (colFmts []format, c
|
|||
|
||||
allBinary := true
|
||||
allText := true
|
||||
for i, o := range colTyps {
|
||||
switch o {
|
||||
for i, t := range colTyps {
|
||||
switch t.OID {
|
||||
// This is the list of types to use binary mode for when receiving them
|
||||
// through a prepared statement. If a type appears in this list, it
|
||||
// must also be implemented in binaryDecode in encode.go.
|
||||
|
|
@ -1155,7 +1155,7 @@ type stmt struct {
|
|||
colNames []string
|
||||
colFmts []format
|
||||
colFmtData []byte
|
||||
colTyps []oid.Oid
|
||||
colTyps []fieldDesc
|
||||
paramTyps []oid.Oid
|
||||
closed bool
|
||||
}
|
||||
|
|
@ -1318,7 +1318,7 @@ type rows struct {
|
|||
cn *conn
|
||||
finish func()
|
||||
colNames []string
|
||||
colTyps []oid.Oid
|
||||
colTyps []fieldDesc
|
||||
colFmts []format
|
||||
done bool
|
||||
rb readBuf
|
||||
|
|
@ -1406,7 +1406,7 @@ func (rs *rows) Next(dest []driver.Value) (err error) {
|
|||
dest[i] = nil
|
||||
continue
|
||||
}
|
||||
dest[i] = decode(&conn.parameterStatus, rs.rb.next(l), rs.colTyps[i], rs.colFmts[i])
|
||||
dest[i] = decode(&conn.parameterStatus, rs.rb.next(l), rs.colTyps[i].OID, rs.colFmts[i])
|
||||
}
|
||||
return
|
||||
case 'T':
|
||||
|
|
@ -1573,7 +1573,7 @@ func (cn *conn) readParseResponse() {
|
|||
}
|
||||
}
|
||||
|
||||
func (cn *conn) readStatementDescribeResponse() (paramTyps []oid.Oid, colNames []string, colTyps []oid.Oid) {
|
||||
func (cn *conn) readStatementDescribeResponse() (paramTyps []oid.Oid, colNames []string, colTyps []fieldDesc) {
|
||||
for {
|
||||
t, r := cn.recv1()
|
||||
switch t {
|
||||
|
|
@ -1599,7 +1599,7 @@ func (cn *conn) readStatementDescribeResponse() (paramTyps []oid.Oid, colNames [
|
|||
}
|
||||
}
|
||||
|
||||
func (cn *conn) readPortalDescribeResponse() (colNames []string, colFmts []format, colTyps []oid.Oid) {
|
||||
func (cn *conn) readPortalDescribeResponse() (colNames []string, colFmts []format, colTyps []fieldDesc) {
|
||||
t, r := cn.recv1()
|
||||
switch t {
|
||||
case 'T':
|
||||
|
|
@ -1695,31 +1695,33 @@ func (cn *conn) readExecuteResponse(protocolState string) (res driver.Result, co
|
|||
}
|
||||
}
|
||||
|
||||
func parseStatementRowDescribe(r *readBuf) (colNames []string, colTyps []oid.Oid) {
|
||||
func parseStatementRowDescribe(r *readBuf) (colNames []string, colTyps []fieldDesc) {
|
||||
n := r.int16()
|
||||
colNames = make([]string, n)
|
||||
colTyps = make([]oid.Oid, n)
|
||||
colTyps = make([]fieldDesc, n)
|
||||
for i := range colNames {
|
||||
colNames[i] = r.string()
|
||||
r.next(6)
|
||||
colTyps[i] = r.oid()
|
||||
r.next(6)
|
||||
colTyps[i].OID = r.oid()
|
||||
colTyps[i].Len = r.int16()
|
||||
colTyps[i].Mod = r.int32()
|
||||
// format code not known when describing a statement; always 0
|
||||
r.next(2)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func parsePortalRowDescribe(r *readBuf) (colNames []string, colFmts []format, colTyps []oid.Oid) {
|
||||
func parsePortalRowDescribe(r *readBuf) (colNames []string, colFmts []format, colTyps []fieldDesc) {
|
||||
n := r.int16()
|
||||
colNames = make([]string, n)
|
||||
colFmts = make([]format, n)
|
||||
colTyps = make([]oid.Oid, n)
|
||||
colTyps = make([]fieldDesc, n)
|
||||
for i := range colNames {
|
||||
colNames[i] = r.string()
|
||||
r.next(6)
|
||||
colTyps[i] = r.oid()
|
||||
r.next(6)
|
||||
colTyps[i].OID = r.oid()
|
||||
colTyps[i].Len = r.int16()
|
||||
colTyps[i].Mod = r.int32()
|
||||
colFmts[i] = format(r.int16())
|
||||
}
|
||||
return
|
||||
|
|
|
|||
12
vendor/github.com/lib/pq/encode.go
generated
vendored
12
vendor/github.com/lib/pq/encode.go
generated
vendored
|
|
@ -367,8 +367,15 @@ func ParseTimestamp(currentLocation *time.Location, str string) (time.Time, erro
|
|||
timeSep := daySep + 3
|
||||
day := p.mustAtoi(str, daySep+1, timeSep)
|
||||
|
||||
minLen := monSep + len("01-01") + 1
|
||||
|
||||
isBC := strings.HasSuffix(str, " BC")
|
||||
if isBC {
|
||||
minLen += 3
|
||||
}
|
||||
|
||||
var hour, minute, second int
|
||||
if len(str) > monSep+len("01-01")+1 {
|
||||
if len(str) > minLen {
|
||||
p.expect(str, ' ', timeSep)
|
||||
minSep := timeSep + 3
|
||||
p.expect(str, ':', minSep)
|
||||
|
|
@ -424,7 +431,8 @@ func ParseTimestamp(currentLocation *time.Location, str string) (time.Time, erro
|
|||
tzOff = tzSign * ((tzHours * 60 * 60) + (tzMin * 60) + tzSec)
|
||||
}
|
||||
var isoYear int
|
||||
if remainderIdx+3 <= len(str) && str[remainderIdx:remainderIdx+3] == " BC" {
|
||||
|
||||
if isBC {
|
||||
isoYear = 1 - year
|
||||
remainderIdx += 3
|
||||
} else {
|
||||
|
|
|
|||
9
vendor/github.com/lib/pq/encode_test.go
generated
vendored
9
vendor/github.com/lib/pq/encode_test.go
generated
vendored
|
|
@ -37,6 +37,8 @@ var timeTests = []struct {
|
|||
}{
|
||||
{"22001-02-03", time.Date(22001, time.February, 3, 0, 0, 0, 0, time.FixedZone("", 0))},
|
||||
{"2001-02-03", time.Date(2001, time.February, 3, 0, 0, 0, 0, time.FixedZone("", 0))},
|
||||
{"0001-12-31 BC", time.Date(0, time.December, 31, 0, 0, 0, 0, time.FixedZone("", 0))},
|
||||
{"2001-02-03 BC", time.Date(-2000, time.February, 3, 0, 0, 0, 0, time.FixedZone("", 0))},
|
||||
{"2001-02-03 04:05:06", time.Date(2001, time.February, 3, 4, 5, 6, 0, time.FixedZone("", 0))},
|
||||
{"2001-02-03 04:05:06.000001", time.Date(2001, time.February, 3, 4, 5, 6, 1000, time.FixedZone("", 0))},
|
||||
{"2001-02-03 04:05:06.00001", time.Date(2001, time.February, 3, 4, 5, 6, 10000, time.FixedZone("", 0))},
|
||||
|
|
@ -86,15 +88,22 @@ func TestParseTs(t *testing.T) {
|
|||
}
|
||||
|
||||
var timeErrorTests = []string{
|
||||
"BC",
|
||||
" BC",
|
||||
"2001",
|
||||
"2001-2-03",
|
||||
"2001-02-3",
|
||||
"2001-02-03 ",
|
||||
"2001-02-03 B",
|
||||
"2001-02-03 04",
|
||||
"2001-02-03 04:",
|
||||
"2001-02-03 04:05",
|
||||
"2001-02-03 04:05 B",
|
||||
"2001-02-03 04:05 BC",
|
||||
"2001-02-03 04:05:",
|
||||
"2001-02-03 04:05:6",
|
||||
"2001-02-03 04:05:06 B",
|
||||
"2001-02-03 04:05:06BC",
|
||||
"2001-02-03 04:05:06.123 B",
|
||||
}
|
||||
|
||||
|
|
|
|||
59
vendor/github.com/lib/pq/oid/gen.go
generated
vendored
59
vendor/github.com/lib/pq/oid/gen.go
generated
vendored
|
|
@ -10,10 +10,22 @@ import (
|
|||
"log"
|
||||
"os"
|
||||
"os/exec"
|
||||
"strings"
|
||||
|
||||
_ "github.com/lib/pq"
|
||||
)
|
||||
|
||||
// OID represent a postgres Object Identifier Type.
|
||||
type OID struct {
|
||||
ID int
|
||||
Type string
|
||||
}
|
||||
|
||||
// Name returns an upper case version of the oid type.
|
||||
func (o OID) Name() string {
|
||||
return strings.ToUpper(o.Type)
|
||||
}
|
||||
|
||||
func main() {
|
||||
datname := os.Getenv("PGDATABASE")
|
||||
sslmode := os.Getenv("PGSSLMODE")
|
||||
|
|
@ -30,6 +42,25 @@ func main() {
|
|||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
rows, err := db.Query(`
|
||||
SELECT typname, oid
|
||||
FROM pg_type WHERE oid < 10000
|
||||
ORDER BY oid;
|
||||
`)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
oids := make([]*OID, 0)
|
||||
for rows.Next() {
|
||||
var oid OID
|
||||
if err = rows.Scan(&oid.Type, &oid.ID); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
oids = append(oids, &oid)
|
||||
}
|
||||
if err = rows.Err(); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
cmd := exec.Command("gofmt")
|
||||
cmd.Stderr = os.Stderr
|
||||
w, err := cmd.StdinPipe()
|
||||
|
|
@ -45,30 +76,18 @@ func main() {
|
|||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
fmt.Fprintln(w, "// generated by 'go run gen.go'; do not edit")
|
||||
fmt.Fprintln(w, "// Code generated by gen.go. DO NOT EDIT.")
|
||||
fmt.Fprintln(w, "\npackage oid")
|
||||
fmt.Fprintln(w, "const (")
|
||||
rows, err := db.Query(`
|
||||
SELECT typname, oid
|
||||
FROM pg_type WHERE oid < 10000
|
||||
ORDER BY oid;
|
||||
`)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
var name string
|
||||
var oid int
|
||||
for rows.Next() {
|
||||
err = rows.Scan(&name, &oid)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
fmt.Fprintf(w, "T_%s Oid = %d\n", name, oid)
|
||||
}
|
||||
if err = rows.Err(); err != nil {
|
||||
log.Fatal(err)
|
||||
for _, oid := range oids {
|
||||
fmt.Fprintf(w, "T_%s Oid = %d\n", oid.Type, oid.ID)
|
||||
}
|
||||
fmt.Fprintln(w, ")")
|
||||
fmt.Fprintln(w, "var TypeName = map[Oid]string{")
|
||||
for _, oid := range oids {
|
||||
fmt.Fprintf(w, "T_%s: \"%s\",\n", oid.Type, oid.Name())
|
||||
}
|
||||
fmt.Fprintln(w, "}")
|
||||
w.Close()
|
||||
cmd.Wait()
|
||||
}
|
||||
|
|
|
|||
172
vendor/github.com/lib/pq/oid/types.go
generated
vendored
172
vendor/github.com/lib/pq/oid/types.go
generated
vendored
|
|
@ -1,4 +1,4 @@
|
|||
// generated by 'go run gen.go'; do not edit
|
||||
// Code generated by gen.go. DO NOT EDIT.
|
||||
|
||||
package oid
|
||||
|
||||
|
|
@ -171,3 +171,173 @@ const (
|
|||
T_regrole Oid = 4096
|
||||
T__regrole Oid = 4097
|
||||
)
|
||||
|
||||
var TypeName = map[Oid]string{
|
||||
T_bool: "BOOL",
|
||||
T_bytea: "BYTEA",
|
||||
T_char: "CHAR",
|
||||
T_name: "NAME",
|
||||
T_int8: "INT8",
|
||||
T_int2: "INT2",
|
||||
T_int2vector: "INT2VECTOR",
|
||||
T_int4: "INT4",
|
||||
T_regproc: "REGPROC",
|
||||
T_text: "TEXT",
|
||||
T_oid: "OID",
|
||||
T_tid: "TID",
|
||||
T_xid: "XID",
|
||||
T_cid: "CID",
|
||||
T_oidvector: "OIDVECTOR",
|
||||
T_pg_ddl_command: "PG_DDL_COMMAND",
|
||||
T_pg_type: "PG_TYPE",
|
||||
T_pg_attribute: "PG_ATTRIBUTE",
|
||||
T_pg_proc: "PG_PROC",
|
||||
T_pg_class: "PG_CLASS",
|
||||
T_json: "JSON",
|
||||
T_xml: "XML",
|
||||
T__xml: "_XML",
|
||||
T_pg_node_tree: "PG_NODE_TREE",
|
||||
T__json: "_JSON",
|
||||
T_smgr: "SMGR",
|
||||
T_index_am_handler: "INDEX_AM_HANDLER",
|
||||
T_point: "POINT",
|
||||
T_lseg: "LSEG",
|
||||
T_path: "PATH",
|
||||
T_box: "BOX",
|
||||
T_polygon: "POLYGON",
|
||||
T_line: "LINE",
|
||||
T__line: "_LINE",
|
||||
T_cidr: "CIDR",
|
||||
T__cidr: "_CIDR",
|
||||
T_float4: "FLOAT4",
|
||||
T_float8: "FLOAT8",
|
||||
T_abstime: "ABSTIME",
|
||||
T_reltime: "RELTIME",
|
||||
T_tinterval: "TINTERVAL",
|
||||
T_unknown: "UNKNOWN",
|
||||
T_circle: "CIRCLE",
|
||||
T__circle: "_CIRCLE",
|
||||
T_money: "MONEY",
|
||||
T__money: "_MONEY",
|
||||
T_macaddr: "MACADDR",
|
||||
T_inet: "INET",
|
||||
T__bool: "_BOOL",
|
||||
T__bytea: "_BYTEA",
|
||||
T__char: "_CHAR",
|
||||
T__name: "_NAME",
|
||||
T__int2: "_INT2",
|
||||
T__int2vector: "_INT2VECTOR",
|
||||
T__int4: "_INT4",
|
||||
T__regproc: "_REGPROC",
|
||||
T__text: "_TEXT",
|
||||
T__tid: "_TID",
|
||||
T__xid: "_XID",
|
||||
T__cid: "_CID",
|
||||
T__oidvector: "_OIDVECTOR",
|
||||
T__bpchar: "_BPCHAR",
|
||||
T__varchar: "_VARCHAR",
|
||||
T__int8: "_INT8",
|
||||
T__point: "_POINT",
|
||||
T__lseg: "_LSEG",
|
||||
T__path: "_PATH",
|
||||
T__box: "_BOX",
|
||||
T__float4: "_FLOAT4",
|
||||
T__float8: "_FLOAT8",
|
||||
T__abstime: "_ABSTIME",
|
||||
T__reltime: "_RELTIME",
|
||||
T__tinterval: "_TINTERVAL",
|
||||
T__polygon: "_POLYGON",
|
||||
T__oid: "_OID",
|
||||
T_aclitem: "ACLITEM",
|
||||
T__aclitem: "_ACLITEM",
|
||||
T__macaddr: "_MACADDR",
|
||||
T__inet: "_INET",
|
||||
T_bpchar: "BPCHAR",
|
||||
T_varchar: "VARCHAR",
|
||||
T_date: "DATE",
|
||||
T_time: "TIME",
|
||||
T_timestamp: "TIMESTAMP",
|
||||
T__timestamp: "_TIMESTAMP",
|
||||
T__date: "_DATE",
|
||||
T__time: "_TIME",
|
||||
T_timestamptz: "TIMESTAMPTZ",
|
||||
T__timestamptz: "_TIMESTAMPTZ",
|
||||
T_interval: "INTERVAL",
|
||||
T__interval: "_INTERVAL",
|
||||
T__numeric: "_NUMERIC",
|
||||
T_pg_database: "PG_DATABASE",
|
||||
T__cstring: "_CSTRING",
|
||||
T_timetz: "TIMETZ",
|
||||
T__timetz: "_TIMETZ",
|
||||
T_bit: "BIT",
|
||||
T__bit: "_BIT",
|
||||
T_varbit: "VARBIT",
|
||||
T__varbit: "_VARBIT",
|
||||
T_numeric: "NUMERIC",
|
||||
T_refcursor: "REFCURSOR",
|
||||
T__refcursor: "_REFCURSOR",
|
||||
T_regprocedure: "REGPROCEDURE",
|
||||
T_regoper: "REGOPER",
|
||||
T_regoperator: "REGOPERATOR",
|
||||
T_regclass: "REGCLASS",
|
||||
T_regtype: "REGTYPE",
|
||||
T__regprocedure: "_REGPROCEDURE",
|
||||
T__regoper: "_REGOPER",
|
||||
T__regoperator: "_REGOPERATOR",
|
||||
T__regclass: "_REGCLASS",
|
||||
T__regtype: "_REGTYPE",
|
||||
T_record: "RECORD",
|
||||
T_cstring: "CSTRING",
|
||||
T_any: "ANY",
|
||||
T_anyarray: "ANYARRAY",
|
||||
T_void: "VOID",
|
||||
T_trigger: "TRIGGER",
|
||||
T_language_handler: "LANGUAGE_HANDLER",
|
||||
T_internal: "INTERNAL",
|
||||
T_opaque: "OPAQUE",
|
||||
T_anyelement: "ANYELEMENT",
|
||||
T__record: "_RECORD",
|
||||
T_anynonarray: "ANYNONARRAY",
|
||||
T_pg_authid: "PG_AUTHID",
|
||||
T_pg_auth_members: "PG_AUTH_MEMBERS",
|
||||
T__txid_snapshot: "_TXID_SNAPSHOT",
|
||||
T_uuid: "UUID",
|
||||
T__uuid: "_UUID",
|
||||
T_txid_snapshot: "TXID_SNAPSHOT",
|
||||
T_fdw_handler: "FDW_HANDLER",
|
||||
T_pg_lsn: "PG_LSN",
|
||||
T__pg_lsn: "_PG_LSN",
|
||||
T_tsm_handler: "TSM_HANDLER",
|
||||
T_anyenum: "ANYENUM",
|
||||
T_tsvector: "TSVECTOR",
|
||||
T_tsquery: "TSQUERY",
|
||||
T_gtsvector: "GTSVECTOR",
|
||||
T__tsvector: "_TSVECTOR",
|
||||
T__gtsvector: "_GTSVECTOR",
|
||||
T__tsquery: "_TSQUERY",
|
||||
T_regconfig: "REGCONFIG",
|
||||
T__regconfig: "_REGCONFIG",
|
||||
T_regdictionary: "REGDICTIONARY",
|
||||
T__regdictionary: "_REGDICTIONARY",
|
||||
T_jsonb: "JSONB",
|
||||
T__jsonb: "_JSONB",
|
||||
T_anyrange: "ANYRANGE",
|
||||
T_event_trigger: "EVENT_TRIGGER",
|
||||
T_int4range: "INT4RANGE",
|
||||
T__int4range: "_INT4RANGE",
|
||||
T_numrange: "NUMRANGE",
|
||||
T__numrange: "_NUMRANGE",
|
||||
T_tsrange: "TSRANGE",
|
||||
T__tsrange: "_TSRANGE",
|
||||
T_tstzrange: "TSTZRANGE",
|
||||
T__tstzrange: "_TSTZRANGE",
|
||||
T_daterange: "DATERANGE",
|
||||
T__daterange: "_DATERANGE",
|
||||
T_int8range: "INT8RANGE",
|
||||
T__int8range: "_INT8RANGE",
|
||||
T_pg_shseclabel: "PG_SHSECLABEL",
|
||||
T_regnamespace: "REGNAMESPACE",
|
||||
T__regnamespace: "_REGNAMESPACE",
|
||||
T_regrole: "REGROLE",
|
||||
T__regrole: "_REGROLE",
|
||||
}
|
||||
|
|
|
|||
93
vendor/github.com/lib/pq/rows.go
generated
vendored
Normal file
93
vendor/github.com/lib/pq/rows.go
generated
vendored
Normal file
|
|
@ -0,0 +1,93 @@
|
|||
package pq
|
||||
|
||||
import (
|
||||
"math"
|
||||
"reflect"
|
||||
"time"
|
||||
|
||||
"github.com/lib/pq/oid"
|
||||
)
|
||||
|
||||
const headerSize = 4
|
||||
|
||||
type fieldDesc struct {
|
||||
// The object ID of the data type.
|
||||
OID oid.Oid
|
||||
// The data type size (see pg_type.typlen).
|
||||
// Note that negative values denote variable-width types.
|
||||
Len int
|
||||
// The type modifier (see pg_attribute.atttypmod).
|
||||
// The meaning of the modifier is type-specific.
|
||||
Mod int
|
||||
}
|
||||
|
||||
func (fd fieldDesc) Type() reflect.Type {
|
||||
switch fd.OID {
|
||||
case oid.T_int8:
|
||||
return reflect.TypeOf(int64(0))
|
||||
case oid.T_int4:
|
||||
return reflect.TypeOf(int32(0))
|
||||
case oid.T_int2:
|
||||
return reflect.TypeOf(int16(0))
|
||||
case oid.T_varchar, oid.T_text:
|
||||
return reflect.TypeOf("")
|
||||
case oid.T_bool:
|
||||
return reflect.TypeOf(false)
|
||||
case oid.T_date, oid.T_time, oid.T_timetz, oid.T_timestamp, oid.T_timestamptz:
|
||||
return reflect.TypeOf(time.Time{})
|
||||
case oid.T_bytea:
|
||||
return reflect.TypeOf([]byte(nil))
|
||||
default:
|
||||
return reflect.TypeOf(new(interface{})).Elem()
|
||||
}
|
||||
}
|
||||
|
||||
func (fd fieldDesc) Name() string {
|
||||
return oid.TypeName[fd.OID]
|
||||
}
|
||||
|
||||
func (fd fieldDesc) Length() (length int64, ok bool) {
|
||||
switch fd.OID {
|
||||
case oid.T_text, oid.T_bytea:
|
||||
return math.MaxInt64, true
|
||||
case oid.T_varchar, oid.T_bpchar:
|
||||
return int64(fd.Mod - headerSize), true
|
||||
default:
|
||||
return 0, false
|
||||
}
|
||||
}
|
||||
|
||||
func (fd fieldDesc) PrecisionScale() (precision, scale int64, ok bool) {
|
||||
switch fd.OID {
|
||||
case oid.T_numeric, oid.T__numeric:
|
||||
mod := fd.Mod - headerSize
|
||||
precision = int64((mod >> 16) & 0xffff)
|
||||
scale = int64(mod & 0xffff)
|
||||
return precision, scale, true
|
||||
default:
|
||||
return 0, 0, false
|
||||
}
|
||||
}
|
||||
|
||||
// ColumnTypeScanType returns the value type that can be used to scan types into.
|
||||
func (rs *rows) ColumnTypeScanType(index int) reflect.Type {
|
||||
return rs.colTyps[index].Type()
|
||||
}
|
||||
|
||||
// ColumnTypeDatabaseTypeName return the database system type name.
|
||||
func (rs *rows) ColumnTypeDatabaseTypeName(index int) string {
|
||||
return rs.colTyps[index].Name()
|
||||
}
|
||||
|
||||
// ColumnTypeLength returns the length of the column type if the column is a
|
||||
// variable length type. If the column is not a variable length type ok
|
||||
// should return false.
|
||||
func (rs *rows) ColumnTypeLength(index int) (length int64, ok bool) {
|
||||
return rs.colTyps[index].Length()
|
||||
}
|
||||
|
||||
// ColumnTypePrecisionScale should return the precision and scale for decimal
|
||||
// types. If not applicable, ok should be false.
|
||||
func (rs *rows) ColumnTypePrecisionScale(index int) (precision, scale int64, ok bool) {
|
||||
return rs.colTyps[index].PrecisionScale()
|
||||
}
|
||||
220
vendor/github.com/lib/pq/rows_test.go
generated
vendored
Normal file
220
vendor/github.com/lib/pq/rows_test.go
generated
vendored
Normal file
|
|
@ -0,0 +1,220 @@
|
|||
// +build go1.8
|
||||
|
||||
package pq
|
||||
|
||||
import (
|
||||
"math"
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"github.com/lib/pq/oid"
|
||||
)
|
||||
|
||||
func TestDataTypeName(t *testing.T) {
|
||||
tts := []struct {
|
||||
typ oid.Oid
|
||||
name string
|
||||
}{
|
||||
{oid.T_int8, "INT8"},
|
||||
{oid.T_int4, "INT4"},
|
||||
{oid.T_int2, "INT2"},
|
||||
{oid.T_varchar, "VARCHAR"},
|
||||
{oid.T_text, "TEXT"},
|
||||
{oid.T_bool, "BOOL"},
|
||||
{oid.T_numeric, "NUMERIC"},
|
||||
{oid.T_date, "DATE"},
|
||||
{oid.T_time, "TIME"},
|
||||
{oid.T_timetz, "TIMETZ"},
|
||||
{oid.T_timestamp, "TIMESTAMP"},
|
||||
{oid.T_timestamptz, "TIMESTAMPTZ"},
|
||||
{oid.T_bytea, "BYTEA"},
|
||||
}
|
||||
|
||||
for i, tt := range tts {
|
||||
dt := fieldDesc{OID: tt.typ}
|
||||
if name := dt.Name(); name != tt.name {
|
||||
t.Errorf("(%d) got: %s want: %s", i, name, tt.name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestDataType(t *testing.T) {
|
||||
tts := []struct {
|
||||
typ oid.Oid
|
||||
kind reflect.Kind
|
||||
}{
|
||||
{oid.T_int8, reflect.Int64},
|
||||
{oid.T_int4, reflect.Int32},
|
||||
{oid.T_int2, reflect.Int16},
|
||||
{oid.T_varchar, reflect.String},
|
||||
{oid.T_text, reflect.String},
|
||||
{oid.T_bool, reflect.Bool},
|
||||
{oid.T_date, reflect.Struct},
|
||||
{oid.T_time, reflect.Struct},
|
||||
{oid.T_timetz, reflect.Struct},
|
||||
{oid.T_timestamp, reflect.Struct},
|
||||
{oid.T_timestamptz, reflect.Struct},
|
||||
{oid.T_bytea, reflect.Slice},
|
||||
}
|
||||
|
||||
for i, tt := range tts {
|
||||
dt := fieldDesc{OID: tt.typ}
|
||||
if kind := dt.Type().Kind(); kind != tt.kind {
|
||||
t.Errorf("(%d) got: %s want: %s", i, kind, tt.kind)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestDataTypeLength(t *testing.T) {
|
||||
tts := []struct {
|
||||
typ oid.Oid
|
||||
len int
|
||||
mod int
|
||||
length int64
|
||||
ok bool
|
||||
}{
|
||||
{oid.T_int4, 0, -1, 0, false},
|
||||
{oid.T_varchar, 65535, 9, 5, true},
|
||||
{oid.T_text, 65535, -1, math.MaxInt64, true},
|
||||
{oid.T_bytea, 65535, -1, math.MaxInt64, true},
|
||||
}
|
||||
|
||||
for i, tt := range tts {
|
||||
dt := fieldDesc{OID: tt.typ, Len: tt.len, Mod: tt.mod}
|
||||
if l, k := dt.Length(); k != tt.ok || l != tt.length {
|
||||
t.Errorf("(%d) got: %d, %t want: %d, %t", i, l, k, tt.length, tt.ok)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestDataTypePrecisionScale(t *testing.T) {
|
||||
tts := []struct {
|
||||
typ oid.Oid
|
||||
mod int
|
||||
precision, scale int64
|
||||
ok bool
|
||||
}{
|
||||
{oid.T_int4, -1, 0, 0, false},
|
||||
{oid.T_numeric, 589830, 9, 2, true},
|
||||
{oid.T_text, -1, 0, 0, false},
|
||||
}
|
||||
|
||||
for i, tt := range tts {
|
||||
dt := fieldDesc{OID: tt.typ, Mod: tt.mod}
|
||||
p, s, k := dt.PrecisionScale()
|
||||
if k != tt.ok {
|
||||
t.Errorf("(%d) got: %t want: %t", i, k, tt.ok)
|
||||
}
|
||||
if p != tt.precision {
|
||||
t.Errorf("(%d) wrong precision got: %d want: %d", i, p, tt.precision)
|
||||
}
|
||||
if s != tt.scale {
|
||||
t.Errorf("(%d) wrong scale got: %d want: %d", i, s, tt.scale)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestRowsColumnTypes(t *testing.T) {
|
||||
columnTypesTests := []struct {
|
||||
Name string
|
||||
TypeName string
|
||||
Length struct {
|
||||
Len int64
|
||||
OK bool
|
||||
}
|
||||
DecimalSize struct {
|
||||
Precision int64
|
||||
Scale int64
|
||||
OK bool
|
||||
}
|
||||
ScanType reflect.Type
|
||||
}{
|
||||
{
|
||||
Name: "a",
|
||||
TypeName: "INT4",
|
||||
Length: struct {
|
||||
Len int64
|
||||
OK bool
|
||||
}{
|
||||
Len: 0,
|
||||
OK: false,
|
||||
},
|
||||
DecimalSize: struct {
|
||||
Precision int64
|
||||
Scale int64
|
||||
OK bool
|
||||
}{
|
||||
Precision: 0,
|
||||
Scale: 0,
|
||||
OK: false,
|
||||
},
|
||||
ScanType: reflect.TypeOf(int32(0)),
|
||||
}, {
|
||||
Name: "bar",
|
||||
TypeName: "TEXT",
|
||||
Length: struct {
|
||||
Len int64
|
||||
OK bool
|
||||
}{
|
||||
Len: math.MaxInt64,
|
||||
OK: true,
|
||||
},
|
||||
DecimalSize: struct {
|
||||
Precision int64
|
||||
Scale int64
|
||||
OK bool
|
||||
}{
|
||||
Precision: 0,
|
||||
Scale: 0,
|
||||
OK: false,
|
||||
},
|
||||
ScanType: reflect.TypeOf(""),
|
||||
},
|
||||
}
|
||||
|
||||
db := openTestConn(t)
|
||||
defer db.Close()
|
||||
|
||||
rows, err := db.Query("SELECT 1 AS a, text 'bar' AS bar, 1.28::numeric(9, 2) AS dec")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
columns, err := rows.ColumnTypes()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if len(columns) != 3 {
|
||||
t.Errorf("expected 3 columns found %d", len(columns))
|
||||
}
|
||||
|
||||
for i, tt := range columnTypesTests {
|
||||
c := columns[i]
|
||||
if c.Name() != tt.Name {
|
||||
t.Errorf("(%d) got: %s, want: %s", i, c.Name(), tt.Name)
|
||||
}
|
||||
if c.DatabaseTypeName() != tt.TypeName {
|
||||
t.Errorf("(%d) got: %s, want: %s", i, c.DatabaseTypeName(), tt.TypeName)
|
||||
}
|
||||
l, ok := c.Length()
|
||||
if l != tt.Length.Len {
|
||||
t.Errorf("(%d) got: %d, want: %d", i, l, tt.Length.Len)
|
||||
}
|
||||
if ok != tt.Length.OK {
|
||||
t.Errorf("(%d) got: %t, want: %t", i, ok, tt.Length.OK)
|
||||
}
|
||||
p, s, ok := c.DecimalSize()
|
||||
if p != tt.DecimalSize.Precision {
|
||||
t.Errorf("(%d) got: %d, want: %d", i, p, tt.DecimalSize.Precision)
|
||||
}
|
||||
if s != tt.DecimalSize.Scale {
|
||||
t.Errorf("(%d) got: %d, want: %d", i, s, tt.DecimalSize.Scale)
|
||||
}
|
||||
if ok != tt.DecimalSize.OK {
|
||||
t.Errorf("(%d) got: %t, want: %t", i, ok, tt.DecimalSize.OK)
|
||||
}
|
||||
if c.ScanType() != tt.ScanType {
|
||||
t.Errorf("(%d) got: %v, want: %v", i, c.ScanType(), tt.ScanType)
|
||||
}
|
||||
}
|
||||
}
|
||||
1
vendor/github.com/magiconair/properties/.travis.yml
generated
vendored
1
vendor/github.com/magiconair/properties/.travis.yml
generated
vendored
|
|
@ -5,4 +5,5 @@ go:
|
|||
- 1.6.x
|
||||
- 1.7.x
|
||||
- 1.8.x
|
||||
- 1.9.x
|
||||
- tip
|
||||
|
|
|
|||
5
vendor/github.com/magiconair/properties/CHANGELOG.md
generated
vendored
5
vendor/github.com/magiconair/properties/CHANGELOG.md
generated
vendored
|
|
@ -1,5 +1,10 @@
|
|||
## Changelog
|
||||
|
||||
### Unreleased
|
||||
|
||||
* [PR #24](https://github.com/magiconair/properties/pull/24): Update keys when DisableExpansion is enabled
|
||||
Thanks to @mgurov for the fix.
|
||||
|
||||
### [1.7.3](https://github.com/magiconair/properties/tags/v1.7.3) - 10 Jul 2017
|
||||
|
||||
* [Issue #17](https://github.com/magiconair/properties/issues/17): Add [SetValue()](http://godoc.org/github.com/magiconair/properties#Properties.SetValue) method to set values generically
|
||||
|
|
|
|||
3
vendor/github.com/magiconair/properties/properties.go
generated
vendored
3
vendor/github.com/magiconair/properties/properties.go
generated
vendored
|
|
@ -511,6 +511,9 @@ func (p *Properties) Set(key, value string) (prev string, ok bool, err error) {
|
|||
if p.DisableExpansion {
|
||||
prev, ok = p.Get(key)
|
||||
p.m[key] = value
|
||||
if !ok {
|
||||
p.k = append(p.k, key)
|
||||
}
|
||||
return prev, ok, nil
|
||||
}
|
||||
|
||||
|
|
|
|||
13
vendor/github.com/magiconair/properties/properties_test.go
generated
vendored
13
vendor/github.com/magiconair/properties/properties_test.go
generated
vendored
|
|
@ -458,6 +458,19 @@ func TestDisableExpansion(t *testing.T) {
|
|||
assert.Equal(t, p.MustGet("keyB"), "${keyA}")
|
||||
}
|
||||
|
||||
func TestDisableExpansionStillUpdatesKeys(t *testing.T) {
|
||||
p := NewProperties()
|
||||
p.MustSet("p1", "a")
|
||||
assert.Equal(t, p.Keys(), []string{"p1"})
|
||||
assert.Equal(t, p.String(), "p1 = a\n")
|
||||
|
||||
p.DisableExpansion = true
|
||||
p.MustSet("p2", "b")
|
||||
|
||||
assert.Equal(t, p.Keys(), []string{"p1", "p2"})
|
||||
assert.Equal(t, p.String(), "p1 = a\np2 = b\n")
|
||||
}
|
||||
|
||||
func TestMustGet(t *testing.T) {
|
||||
input := "key = value\nkey2 = ghi"
|
||||
p := mustParse(t, input)
|
||||
|
|
|
|||
1
vendor/github.com/mattermost/html2text/LICENSE
generated
vendored
1
vendor/github.com/mattermost/html2text/LICENSE
generated
vendored
|
|
@ -1,6 +1,7 @@
|
|||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015 Jay Taylor
|
||||
Modified work: Copyright (c) 2017-present Mattermost, Inc. All Rights Reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
|
|
|||
1
vendor/github.com/miekg/dns/CONTRIBUTORS
generated
vendored
1
vendor/github.com/miekg/dns/CONTRIBUTORS
generated
vendored
|
|
@ -7,3 +7,4 @@ Marek Majkowski
|
|||
Peter van Dijk
|
||||
Omri Bahumi
|
||||
Alex Sergeyev
|
||||
James Hartig
|
||||
|
|
|
|||
340
vendor/github.com/miekg/dns/client.go
generated
vendored
340
vendor/github.com/miekg/dns/client.go
generated
vendored
|
|
@ -9,6 +9,7 @@ import (
|
|||
"encoding/binary"
|
||||
"io"
|
||||
"net"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
|
|
@ -27,11 +28,15 @@ type Conn struct {
|
|||
|
||||
// A Client defines parameters for a DNS client.
|
||||
type Client struct {
|
||||
Net string // if "tcp" or "tcp-tls" (DNS over TLS) a TCP query will be initiated, otherwise an UDP one (default is "" for UDP)
|
||||
UDPSize uint16 // minimum receive buffer for UDP messages
|
||||
TLSConfig *tls.Config // TLS connection configuration
|
||||
Timeout time.Duration // a cumulative timeout for dial, write and read, defaults to 0 (disabled) - overrides DialTimeout, ReadTimeout and WriteTimeout when non-zero
|
||||
DialTimeout time.Duration // net.DialTimeout, defaults to 2 seconds - overridden by Timeout when that value is non-zero
|
||||
Net string // if "tcp" or "tcp-tls" (DNS over TLS) a TCP query will be initiated, otherwise an UDP one (default is "" for UDP)
|
||||
UDPSize uint16 // minimum receive buffer for UDP messages
|
||||
TLSConfig *tls.Config // TLS connection configuration
|
||||
Dialer *net.Dialer // a net.Dialer used to set local address, timeouts and more
|
||||
// Timeout is a cumulative timeout for dial, write and read, defaults to 0 (disabled) - overrides DialTimeout, ReadTimeout,
|
||||
// WriteTimeout when non-zero. Can be overridden with net.Dialer.Timeout (see Client.ExchangeWithDialer and
|
||||
// Client.Dialer) or context.Context.Deadline (see the deprecated ExchangeContext)
|
||||
Timeout time.Duration
|
||||
DialTimeout time.Duration // net.DialTimeout, defaults to 2 seconds, or net.Dialer.Timeout if expiring earlier - overridden by Timeout when that value is non-zero
|
||||
ReadTimeout time.Duration // net.Conn.SetReadTimeout value for connections, defaults to 2 seconds - overridden by Timeout when that value is non-zero
|
||||
WriteTimeout time.Duration // net.Conn.SetWriteTimeout value for connections, defaults to 2 seconds - overridden by Timeout when that value is non-zero
|
||||
TsigSecret map[string]string // secret(s) for Tsig map[<zonename>]<base64 secret>, zonename must be fully qualified
|
||||
|
|
@ -44,140 +49,11 @@ type Client struct {
|
|||
// will it fall back to TCP in case of truncation.
|
||||
// See client.Exchange for more information on setting larger buffer sizes.
|
||||
func Exchange(m *Msg, a string) (r *Msg, err error) {
|
||||
var co *Conn
|
||||
co, err = DialTimeout("udp", a, dnsTimeout)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
defer co.Close()
|
||||
|
||||
opt := m.IsEdns0()
|
||||
// If EDNS0 is used use that for size.
|
||||
if opt != nil && opt.UDPSize() >= MinMsgSize {
|
||||
co.UDPSize = opt.UDPSize()
|
||||
}
|
||||
|
||||
co.SetWriteDeadline(time.Now().Add(dnsTimeout))
|
||||
if err = co.WriteMsg(m); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
co.SetReadDeadline(time.Now().Add(dnsTimeout))
|
||||
r, err = co.ReadMsg()
|
||||
if err == nil && r.Id != m.Id {
|
||||
err = ErrId
|
||||
}
|
||||
client := Client{Net: "udp"}
|
||||
r, _, err = client.Exchange(m, a)
|
||||
return r, err
|
||||
}
|
||||
|
||||
// ExchangeContext performs a synchronous UDP query, like Exchange. It
|
||||
// additionally obeys deadlines from the passed Context.
|
||||
func ExchangeContext(ctx context.Context, m *Msg, a string) (r *Msg, err error) {
|
||||
// Combine context deadline with built-in timeout. Context chooses whichever
|
||||
// is sooner.
|
||||
timeoutCtx, cancel := context.WithTimeout(ctx, dnsTimeout)
|
||||
defer cancel()
|
||||
deadline, _ := timeoutCtx.Deadline()
|
||||
|
||||
co := new(Conn)
|
||||
dialer := net.Dialer{}
|
||||
co.Conn, err = dialer.DialContext(timeoutCtx, "udp", a)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
defer co.Conn.Close()
|
||||
|
||||
opt := m.IsEdns0()
|
||||
// If EDNS0 is used use that for size.
|
||||
if opt != nil && opt.UDPSize() >= MinMsgSize {
|
||||
co.UDPSize = opt.UDPSize()
|
||||
}
|
||||
|
||||
co.SetWriteDeadline(deadline)
|
||||
if err = co.WriteMsg(m); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
co.SetReadDeadline(deadline)
|
||||
r, err = co.ReadMsg()
|
||||
if err == nil && r.Id != m.Id {
|
||||
err = ErrId
|
||||
}
|
||||
return r, err
|
||||
}
|
||||
|
||||
// ExchangeConn performs a synchronous query. It sends the message m via the connection
|
||||
// c and waits for a reply. The connection c is not closed by ExchangeConn.
|
||||
// This function is going away, but can easily be mimicked:
|
||||
//
|
||||
// co := &dns.Conn{Conn: c} // c is your net.Conn
|
||||
// co.WriteMsg(m)
|
||||
// in, _ := co.ReadMsg()
|
||||
// co.Close()
|
||||
//
|
||||
func ExchangeConn(c net.Conn, m *Msg) (r *Msg, err error) {
|
||||
println("dns: this function is deprecated")
|
||||
co := new(Conn)
|
||||
co.Conn = c
|
||||
if err = co.WriteMsg(m); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
r, err = co.ReadMsg()
|
||||
if err == nil && r.Id != m.Id {
|
||||
err = ErrId
|
||||
}
|
||||
return r, err
|
||||
}
|
||||
|
||||
// Exchange performs a synchronous query. It sends the message m to the address
|
||||
// contained in a and waits for a reply. Basic use pattern with a *dns.Client:
|
||||
//
|
||||
// c := new(dns.Client)
|
||||
// in, rtt, err := c.Exchange(message, "127.0.0.1:53")
|
||||
//
|
||||
// Exchange does not retry a failed query, nor will it fall back to TCP in
|
||||
// case of truncation.
|
||||
// It is up to the caller to create a message that allows for larger responses to be
|
||||
// returned. Specifically this means adding an EDNS0 OPT RR that will advertise a larger
|
||||
// buffer, see SetEdns0. Messages without an OPT RR will fallback to the historic limit
|
||||
// of 512 bytes.
|
||||
func (c *Client) Exchange(m *Msg, a string) (r *Msg, rtt time.Duration, err error) {
|
||||
return c.ExchangeContext(context.Background(), m, a)
|
||||
}
|
||||
|
||||
// ExchangeContext acts like Exchange, but honors the deadline on the provided
|
||||
// context, if present. If there is both a context deadline and a configured
|
||||
// timeout on the client, the earliest of the two takes effect.
|
||||
func (c *Client) ExchangeContext(ctx context.Context, m *Msg, a string) (
|
||||
r *Msg,
|
||||
rtt time.Duration,
|
||||
err error) {
|
||||
if !c.SingleInflight {
|
||||
return c.exchange(ctx, m, a)
|
||||
}
|
||||
// This adds a bunch of garbage, TODO(miek).
|
||||
t := "nop"
|
||||
if t1, ok := TypeToString[m.Question[0].Qtype]; ok {
|
||||
t = t1
|
||||
}
|
||||
cl := "nop"
|
||||
if cl1, ok := ClassToString[m.Question[0].Qclass]; ok {
|
||||
cl = cl1
|
||||
}
|
||||
r, rtt, err, shared := c.group.Do(m.Question[0].Name+t+cl, func() (*Msg, time.Duration, error) {
|
||||
return c.exchange(ctx, m, a)
|
||||
})
|
||||
if r != nil && shared {
|
||||
r = r.Copy()
|
||||
}
|
||||
if err != nil {
|
||||
return r, rtt, err
|
||||
}
|
||||
return r, rtt, nil
|
||||
}
|
||||
|
||||
func (c *Client) dialTimeout() time.Duration {
|
||||
if c.Timeout != 0 {
|
||||
return c.Timeout
|
||||
|
|
@ -202,40 +78,87 @@ func (c *Client) writeTimeout() time.Duration {
|
|||
return dnsTimeout
|
||||
}
|
||||
|
||||
func (c *Client) exchange(ctx context.Context, m *Msg, a string) (r *Msg, rtt time.Duration, err error) {
|
||||
var co *Conn
|
||||
func (c *Client) Dial(address string) (conn *Conn, err error) {
|
||||
// create a new dialer with the appropriate timeout
|
||||
var d net.Dialer
|
||||
if c.Dialer == nil {
|
||||
d = net.Dialer{}
|
||||
} else {
|
||||
d = net.Dialer(*c.Dialer)
|
||||
}
|
||||
d.Timeout = c.getTimeoutForRequest(c.writeTimeout())
|
||||
|
||||
network := "udp"
|
||||
tls := false
|
||||
useTLS := false
|
||||
|
||||
switch c.Net {
|
||||
case "tcp-tls":
|
||||
network = "tcp"
|
||||
tls = true
|
||||
useTLS = true
|
||||
case "tcp4-tls":
|
||||
network = "tcp4"
|
||||
tls = true
|
||||
useTLS = true
|
||||
case "tcp6-tls":
|
||||
network = "tcp6"
|
||||
tls = true
|
||||
useTLS = true
|
||||
default:
|
||||
if c.Net != "" {
|
||||
network = c.Net
|
||||
}
|
||||
}
|
||||
|
||||
var deadline time.Time
|
||||
if c.Timeout != 0 {
|
||||
deadline = time.Now().Add(c.Timeout)
|
||||
}
|
||||
|
||||
dialDeadline := deadlineOrTimeoutOrCtx(ctx, deadline, c.dialTimeout())
|
||||
dialTimeout := dialDeadline.Sub(time.Now())
|
||||
|
||||
if tls {
|
||||
co, err = DialTimeoutWithTLS(network, a, c.TLSConfig, dialTimeout)
|
||||
conn = new(Conn)
|
||||
if useTLS {
|
||||
conn.Conn, err = tls.DialWithDialer(&d, network, address, c.TLSConfig)
|
||||
} else {
|
||||
co, err = DialTimeout(network, a, dialTimeout)
|
||||
conn.Conn, err = d.Dial(network, address)
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return conn, nil
|
||||
}
|
||||
|
||||
// Exchange performs a synchronous query. It sends the message m to the address
|
||||
// contained in a and waits for a reply. Basic use pattern with a *dns.Client:
|
||||
//
|
||||
// c := new(dns.Client)
|
||||
// in, rtt, err := c.Exchange(message, "127.0.0.1:53")
|
||||
//
|
||||
// Exchange does not retry a failed query, nor will it fall back to TCP in
|
||||
// case of truncation.
|
||||
// It is up to the caller to create a message that allows for larger responses to be
|
||||
// returned. Specifically this means adding an EDNS0 OPT RR that will advertise a larger
|
||||
// buffer, see SetEdns0. Messages without an OPT RR will fallback to the historic limit
|
||||
// of 512 bytes
|
||||
// To specify a local address or a timeout, the caller has to set the `Client.Dialer`
|
||||
// attribute appropriately
|
||||
func (c *Client) Exchange(m *Msg, address string) (r *Msg, rtt time.Duration, err error) {
|
||||
if !c.SingleInflight {
|
||||
return c.exchange(m, address)
|
||||
}
|
||||
|
||||
t := "nop"
|
||||
if t1, ok := TypeToString[m.Question[0].Qtype]; ok {
|
||||
t = t1
|
||||
}
|
||||
cl := "nop"
|
||||
if cl1, ok := ClassToString[m.Question[0].Qclass]; ok {
|
||||
cl = cl1
|
||||
}
|
||||
r, rtt, err, shared := c.group.Do(m.Question[0].Name+t+cl, func() (*Msg, time.Duration, error) {
|
||||
return c.exchange(m, address)
|
||||
})
|
||||
if r != nil && shared {
|
||||
r = r.Copy()
|
||||
}
|
||||
return r, rtt, err
|
||||
}
|
||||
|
||||
func (c *Client) exchange(m *Msg, a string) (r *Msg, rtt time.Duration, err error) {
|
||||
var co *Conn
|
||||
|
||||
co, err = c.Dial(a)
|
||||
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
|
|
@ -253,12 +176,13 @@ func (c *Client) exchange(ctx context.Context, m *Msg, a string) (r *Msg, rtt ti
|
|||
}
|
||||
|
||||
co.TsigSecret = c.TsigSecret
|
||||
co.SetWriteDeadline(deadlineOrTimeoutOrCtx(ctx, deadline, c.writeTimeout()))
|
||||
// write with the appropriate write timeout
|
||||
co.SetWriteDeadline(time.Now().Add(c.getTimeoutForRequest(c.writeTimeout())))
|
||||
if err = co.WriteMsg(m); err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
co.SetReadDeadline(deadlineOrTimeoutOrCtx(ctx, deadline, c.readTimeout()))
|
||||
co.SetReadDeadline(time.Now().Add(c.getTimeoutForRequest(c.readTimeout())))
|
||||
r, err = co.ReadMsg()
|
||||
if err == nil && r.Id != m.Id {
|
||||
err = ErrId
|
||||
|
|
@ -352,7 +276,7 @@ func tcpMsgLen(t io.Reader) (int, error) {
|
|||
return 0, err
|
||||
}
|
||||
|
||||
// As seen with my local router/switch, retursn 1 byte on the above read,
|
||||
// As seen with my local router/switch, returns 1 byte on the above read,
|
||||
// resulting a a ShortRead. Just write it out (instead of loop) and read the
|
||||
// other byte.
|
||||
if n == 1 {
|
||||
|
|
@ -467,6 +391,24 @@ func (co *Conn) Write(p []byte) (n int, err error) {
|
|||
return n, err
|
||||
}
|
||||
|
||||
// Return the appropriate timeout for a specific request
|
||||
func (c *Client) getTimeoutForRequest(timeout time.Duration) time.Duration {
|
||||
var requestTimeout time.Duration
|
||||
if c.Timeout != 0 {
|
||||
requestTimeout = c.Timeout
|
||||
} else {
|
||||
requestTimeout = timeout
|
||||
}
|
||||
// net.Dialer.Timeout has priority if smaller than the timeouts computed so
|
||||
// far
|
||||
if c.Dialer != nil && c.Dialer.Timeout != 0 {
|
||||
if c.Dialer.Timeout < requestTimeout {
|
||||
requestTimeout = c.Dialer.Timeout
|
||||
}
|
||||
}
|
||||
return requestTimeout
|
||||
}
|
||||
|
||||
// Dial connects to the address on the named network.
|
||||
func Dial(network, address string) (conn *Conn, err error) {
|
||||
conn = new(Conn)
|
||||
|
|
@ -477,10 +419,44 @@ func Dial(network, address string) (conn *Conn, err error) {
|
|||
return conn, nil
|
||||
}
|
||||
|
||||
// ExchangeContext performs a synchronous UDP query, like Exchange. It
|
||||
// additionally obeys deadlines from the passed Context.
|
||||
func ExchangeContext(ctx context.Context, m *Msg, a string) (r *Msg, err error) {
|
||||
client := Client{Net: "udp"}
|
||||
r, _, err = client.ExchangeContext(ctx, m, a)
|
||||
// ignorint rtt to leave the original ExchangeContext API unchanged, but
|
||||
// this function will go away
|
||||
return r, err
|
||||
}
|
||||
|
||||
// ExchangeConn performs a synchronous query. It sends the message m via the connection
|
||||
// c and waits for a reply. The connection c is not closed by ExchangeConn.
|
||||
// This function is going away, but can easily be mimicked:
|
||||
//
|
||||
// co := &dns.Conn{Conn: c} // c is your net.Conn
|
||||
// co.WriteMsg(m)
|
||||
// in, _ := co.ReadMsg()
|
||||
// co.Close()
|
||||
//
|
||||
func ExchangeConn(c net.Conn, m *Msg) (r *Msg, err error) {
|
||||
println("dns: ExchangeConn: this function is deprecated")
|
||||
co := new(Conn)
|
||||
co.Conn = c
|
||||
if err = co.WriteMsg(m); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
r, err = co.ReadMsg()
|
||||
if err == nil && r.Id != m.Id {
|
||||
err = ErrId
|
||||
}
|
||||
return r, err
|
||||
}
|
||||
|
||||
// DialTimeout acts like Dial but takes a timeout.
|
||||
func DialTimeout(network, address string, timeout time.Duration) (conn *Conn, err error) {
|
||||
conn = new(Conn)
|
||||
conn.Conn, err = net.DialTimeout(network, address, timeout)
|
||||
|
||||
client := Client{Net: "udp", Dialer: &net.Dialer{Timeout: timeout}}
|
||||
conn, err = client.Dial(address)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -489,8 +465,12 @@ func DialTimeout(network, address string, timeout time.Duration) (conn *Conn, er
|
|||
|
||||
// DialWithTLS connects to the address on the named network with TLS.
|
||||
func DialWithTLS(network, address string, tlsConfig *tls.Config) (conn *Conn, err error) {
|
||||
conn = new(Conn)
|
||||
conn.Conn, err = tls.Dial(network, address, tlsConfig)
|
||||
if !strings.HasSuffix(network, "-tls") {
|
||||
network += "-tls"
|
||||
}
|
||||
client := Client{Net: network, TLSConfig: tlsConfig}
|
||||
conn, err = client.Dial(address)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -499,33 +479,29 @@ func DialWithTLS(network, address string, tlsConfig *tls.Config) (conn *Conn, er
|
|||
|
||||
// DialTimeoutWithTLS acts like DialWithTLS but takes a timeout.
|
||||
func DialTimeoutWithTLS(network, address string, tlsConfig *tls.Config, timeout time.Duration) (conn *Conn, err error) {
|
||||
var dialer net.Dialer
|
||||
dialer.Timeout = timeout
|
||||
|
||||
conn = new(Conn)
|
||||
conn.Conn, err = tls.DialWithDialer(&dialer, network, address, tlsConfig)
|
||||
if !strings.HasSuffix(network, "-tls") {
|
||||
network += "-tls"
|
||||
}
|
||||
client := Client{Net: network, Dialer: &net.Dialer{Timeout: timeout}, TLSConfig: tlsConfig}
|
||||
conn, err = client.Dial(address)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return conn, nil
|
||||
}
|
||||
|
||||
// deadlineOrTimeout chooses between the provided deadline and timeout
|
||||
// by always preferring the deadline so long as it's non-zero (regardless
|
||||
// of which is bigger), and returns the equivalent deadline value.
|
||||
func deadlineOrTimeout(deadline time.Time, timeout time.Duration) time.Time {
|
||||
if deadline.IsZero() {
|
||||
return time.Now().Add(timeout)
|
||||
// ExchangeContext acts like Exchange, but honors the deadline on the provided
|
||||
// context, if present. If there is both a context deadline and a configured
|
||||
// timeout on the client, the earliest of the two takes effect.
|
||||
func (c *Client) ExchangeContext(ctx context.Context, m *Msg, a string) (r *Msg, rtt time.Duration, err error) {
|
||||
var timeout time.Duration
|
||||
if deadline, ok := ctx.Deadline(); !ok {
|
||||
timeout = 0
|
||||
} else {
|
||||
timeout = deadline.Sub(time.Now())
|
||||
}
|
||||
return deadline
|
||||
}
|
||||
|
||||
// deadlineOrTimeoutOrCtx returns the earliest of: a context deadline, or the
|
||||
// output of deadlineOrtimeout.
|
||||
func deadlineOrTimeoutOrCtx(ctx context.Context, deadline time.Time, timeout time.Duration) time.Time {
|
||||
result := deadlineOrTimeout(deadline, timeout)
|
||||
if ctxDeadline, ok := ctx.Deadline(); ok && ctxDeadline.Before(result) {
|
||||
result = ctxDeadline
|
||||
}
|
||||
return result
|
||||
// not passing the context to the underlying calls, as the API does not support
|
||||
// context. For timeouts you should set up Client.Dialer and call Client.Exchange.
|
||||
c.Dialer = &net.Dialer{Timeout: timeout}
|
||||
return c.Exchange(m, a)
|
||||
}
|
||||
|
|
|
|||
168
vendor/github.com/miekg/dns/client_test.go
generated
vendored
168
vendor/github.com/miekg/dns/client_test.go
generated
vendored
|
|
@ -11,6 +11,29 @@ import (
|
|||
"time"
|
||||
)
|
||||
|
||||
func TestDialUDP(t *testing.T) {
|
||||
HandleFunc("miek.nl.", HelloServer)
|
||||
defer HandleRemove("miek.nl.")
|
||||
|
||||
s, addrstr, err := RunLocalUDPServer("[::1]:0")
|
||||
if err != nil {
|
||||
t.Fatalf("unable to run test server: %v", err)
|
||||
}
|
||||
defer s.Shutdown()
|
||||
|
||||
m := new(Msg)
|
||||
m.SetQuestion("miek.nl.", TypeSOA)
|
||||
|
||||
c := new(Client)
|
||||
conn, err := c.Dial(addrstr)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to dial: %v", err)
|
||||
}
|
||||
if conn == nil {
|
||||
t.Fatalf("conn is nil")
|
||||
}
|
||||
}
|
||||
|
||||
func TestClientSync(t *testing.T) {
|
||||
HandleFunc("miek.nl.", HelloServer)
|
||||
defer HandleRemove("miek.nl.")
|
||||
|
|
@ -27,9 +50,12 @@ func TestClientSync(t *testing.T) {
|
|||
c := new(Client)
|
||||
r, _, err := c.Exchange(m, addrstr)
|
||||
if err != nil {
|
||||
t.Errorf("failed to exchange: %v", err)
|
||||
t.Fatalf("failed to exchange: %v", err)
|
||||
}
|
||||
if r != nil && r.Rcode != RcodeSuccess {
|
||||
if r == nil {
|
||||
t.Fatal("response is nil")
|
||||
}
|
||||
if r.Rcode != RcodeSuccess {
|
||||
t.Errorf("failed to get an valid answer\n%v", r)
|
||||
}
|
||||
// And now with plain Exchange().
|
||||
|
|
@ -42,7 +68,42 @@ func TestClientSync(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestClientTLSSync(t *testing.T) {
|
||||
func TestClientLocalAddress(t *testing.T) {
|
||||
HandleFunc("miek.nl.", HelloServerEchoAddrPort)
|
||||
defer HandleRemove("miek.nl.")
|
||||
|
||||
s, addrstr, err := RunLocalUDPServer("127.0.0.1:0")
|
||||
if err != nil {
|
||||
t.Fatalf("unable to run test server: %v", err)
|
||||
}
|
||||
defer s.Shutdown()
|
||||
|
||||
m := new(Msg)
|
||||
m.SetQuestion("miek.nl.", TypeSOA)
|
||||
|
||||
c := new(Client)
|
||||
laddr := net.UDPAddr{IP: net.ParseIP("127.0.0.1"), Port: 12345, Zone: ""}
|
||||
c.Dialer = &net.Dialer{LocalAddr: &laddr}
|
||||
r, _, err := c.Exchange(m, addrstr)
|
||||
if err != nil {
|
||||
t.Errorf("failed to exchange: %v", err)
|
||||
}
|
||||
if r != nil && r.Rcode != RcodeSuccess {
|
||||
t.Errorf("failed to get an valid answer\n%v", r)
|
||||
}
|
||||
if len(r.Extra) != 1 {
|
||||
t.Errorf("failed to get additional answers\n%v", r)
|
||||
}
|
||||
txt := r.Extra[0].(*TXT)
|
||||
if txt == nil {
|
||||
t.Errorf("invalid TXT response\n%v", txt)
|
||||
}
|
||||
if len(txt.Txt) != 1 || txt.Txt[0] != "127.0.0.1:12345" {
|
||||
t.Errorf("invalid TXT response\n%v", txt.Txt)
|
||||
}
|
||||
}
|
||||
|
||||
func TestClientTLSSyncV4(t *testing.T) {
|
||||
HandleFunc("miek.nl.", HelloServer)
|
||||
defer HandleRemove("miek.nl.")
|
||||
|
||||
|
|
@ -65,6 +126,8 @@ func TestClientTLSSync(t *testing.T) {
|
|||
m.SetQuestion("miek.nl.", TypeSOA)
|
||||
|
||||
c := new(Client)
|
||||
|
||||
// test tcp-tls
|
||||
c.Net = "tcp-tls"
|
||||
c.TLSConfig = &tls.Config{
|
||||
InsecureSkipVerify: true,
|
||||
|
|
@ -72,9 +135,88 @@ func TestClientTLSSync(t *testing.T) {
|
|||
|
||||
r, _, err := c.Exchange(m, addrstr)
|
||||
if err != nil {
|
||||
t.Errorf("failed to exchange: %v", err)
|
||||
t.Fatalf("failed to exchange: %v", err)
|
||||
}
|
||||
if r != nil && r.Rcode != RcodeSuccess {
|
||||
if r == nil {
|
||||
t.Fatal("response is nil")
|
||||
}
|
||||
if r.Rcode != RcodeSuccess {
|
||||
t.Errorf("failed to get an valid answer\n%v", r)
|
||||
}
|
||||
|
||||
// test tcp4-tls
|
||||
c.Net = "tcp4-tls"
|
||||
c.TLSConfig = &tls.Config{
|
||||
InsecureSkipVerify: true,
|
||||
}
|
||||
|
||||
r, _, err = c.Exchange(m, addrstr)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to exchange: %v", err)
|
||||
}
|
||||
if r == nil {
|
||||
t.Fatal("response is nil")
|
||||
}
|
||||
if r.Rcode != RcodeSuccess {
|
||||
t.Errorf("failed to get an valid answer\n%v", r)
|
||||
}
|
||||
}
|
||||
|
||||
func TestClientTLSSyncV6(t *testing.T) {
|
||||
HandleFunc("miek.nl.", HelloServer)
|
||||
defer HandleRemove("miek.nl.")
|
||||
|
||||
cert, err := tls.X509KeyPair(CertPEMBlock, KeyPEMBlock)
|
||||
if err != nil {
|
||||
t.Fatalf("unable to build certificate: %v", err)
|
||||
}
|
||||
|
||||
config := tls.Config{
|
||||
Certificates: []tls.Certificate{cert},
|
||||
}
|
||||
|
||||
s, addrstr, err := RunLocalTLSServer("[::1]:0", &config)
|
||||
if err != nil {
|
||||
t.Fatalf("unable to run test server: %v", err)
|
||||
}
|
||||
defer s.Shutdown()
|
||||
|
||||
m := new(Msg)
|
||||
m.SetQuestion("miek.nl.", TypeSOA)
|
||||
|
||||
c := new(Client)
|
||||
|
||||
// test tcp-tls
|
||||
c.Net = "tcp-tls"
|
||||
c.TLSConfig = &tls.Config{
|
||||
InsecureSkipVerify: true,
|
||||
}
|
||||
|
||||
r, _, err := c.Exchange(m, addrstr)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to exchange: %v", err)
|
||||
}
|
||||
if r == nil {
|
||||
t.Fatal("response is nil")
|
||||
}
|
||||
if r.Rcode != RcodeSuccess {
|
||||
t.Errorf("failed to get an valid answer\n%v", r)
|
||||
}
|
||||
|
||||
// test tcp6-tls
|
||||
c.Net = "tcp6-tls"
|
||||
c.TLSConfig = &tls.Config{
|
||||
InsecureSkipVerify: true,
|
||||
}
|
||||
|
||||
r, _, err = c.Exchange(m, addrstr)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to exchange: %v", err)
|
||||
}
|
||||
if r == nil {
|
||||
t.Fatal("response is nil")
|
||||
}
|
||||
if r.Rcode != RcodeSuccess {
|
||||
t.Errorf("failed to get an valid answer\n%v", r)
|
||||
}
|
||||
}
|
||||
|
|
@ -120,11 +262,11 @@ func TestClientEDNS0(t *testing.T) {
|
|||
c := new(Client)
|
||||
r, _, err := c.Exchange(m, addrstr)
|
||||
if err != nil {
|
||||
t.Errorf("failed to exchange: %v", err)
|
||||
t.Fatalf("failed to exchange: %v", err)
|
||||
}
|
||||
|
||||
if r != nil && r.Rcode != RcodeSuccess {
|
||||
t.Errorf("failed to get an valid answer\n%v", r)
|
||||
t.Errorf("failed to get a valid answer\n%v", r)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -171,11 +313,14 @@ func TestClientEDNS0Local(t *testing.T) {
|
|||
c := new(Client)
|
||||
r, _, err := c.Exchange(m, addrstr)
|
||||
if err != nil {
|
||||
t.Errorf("failed to exchange: %s", err)
|
||||
t.Fatalf("failed to exchange: %s", err)
|
||||
}
|
||||
|
||||
if r != nil && r.Rcode != RcodeSuccess {
|
||||
t.Error("failed to get a valid answer")
|
||||
if r == nil {
|
||||
t.Fatal("response is nil")
|
||||
}
|
||||
if r.Rcode != RcodeSuccess {
|
||||
t.Fatal("failed to get a valid answer")
|
||||
t.Logf("%v\n", r)
|
||||
}
|
||||
|
||||
|
|
@ -513,6 +658,9 @@ func TestConcurrentExchanges(t *testing.T) {
|
|||
for i := 0; i < len(r); i++ {
|
||||
go func(i int) {
|
||||
r[i], _, _ = c.Exchange(m.Copy(), addrstr)
|
||||
if r[i] == nil {
|
||||
t.Fatalf("response %d is nil", i)
|
||||
}
|
||||
wg.Done()
|
||||
}(i)
|
||||
}
|
||||
|
|
|
|||
2
vendor/github.com/miekg/dns/dnsutil/util.go
generated
vendored
2
vendor/github.com/miekg/dns/dnsutil/util.go
generated
vendored
|
|
@ -11,7 +11,7 @@ import (
|
|||
"github.com/miekg/dns"
|
||||
)
|
||||
|
||||
// AddDomain adds origin to s if s is not already a FQDN.
|
||||
// AddOrigin adds origin to s if s is not already a FQDN.
|
||||
// Note that the result may not be a FQDN. If origin does not end
|
||||
// with a ".", the result won't either.
|
||||
// This implements the zonefile convention (specified in RFC 1035,
|
||||
|
|
|
|||
30
vendor/github.com/miekg/dns/doc.go
generated
vendored
30
vendor/github.com/miekg/dns/doc.go
generated
vendored
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
Package dns implements a full featured interface to the Domain Name System.
|
||||
Server- and client-side programming is supported.
|
||||
The package allows complete control over what is send out to the DNS. The package
|
||||
The package allows complete control over what is sent out to the DNS. The package
|
||||
API follows the less-is-more principle, by presenting a small, clean interface.
|
||||
|
||||
The package dns supports (asynchronous) querying/replying, incoming/outgoing zone transfers,
|
||||
|
|
@ -14,7 +14,7 @@ Basic usage pattern for creating a new resource record:
|
|||
|
||||
r := new(dns.MX)
|
||||
r.Hdr = dns.RR_Header{Name: "miek.nl.", Rrtype: dns.TypeMX,
|
||||
Class: dns.ClassINET, Ttl: 3600}
|
||||
Class: dns.ClassINET, Ttl: 3600}
|
||||
r.Preference = 10
|
||||
r.Mx = "mx.miek.nl."
|
||||
|
||||
|
|
@ -22,16 +22,16 @@ Or directly from a string:
|
|||
|
||||
mx, err := dns.NewRR("miek.nl. 3600 IN MX 10 mx.miek.nl.")
|
||||
|
||||
Or when the default TTL (3600) and class (IN) suit you:
|
||||
Or when the default origin (.) and TTL (3600) and class (IN) suit you:
|
||||
|
||||
mx, err := dns.NewRR("miek.nl. MX 10 mx.miek.nl.")
|
||||
mx, err := dns.NewRR("miek.nl MX 10 mx.miek.nl")
|
||||
|
||||
Or even:
|
||||
|
||||
mx, err := dns.NewRR("$ORIGIN nl.\nmiek 1H IN MX 10 mx.miek")
|
||||
|
||||
In the DNS messages are exchanged, these messages contain resource
|
||||
records (sets). Use pattern for creating a message:
|
||||
records (sets). Use pattern for creating a message:
|
||||
|
||||
m := new(dns.Msg)
|
||||
m.SetQuestion("miek.nl.", dns.TypeMX)
|
||||
|
|
@ -51,7 +51,7 @@ The following is slightly more verbose, but more flexible:
|
|||
m1.Question = make([]dns.Question, 1)
|
||||
m1.Question[0] = dns.Question{"miek.nl.", dns.TypeMX, dns.ClassINET}
|
||||
|
||||
After creating a message it can be send.
|
||||
After creating a message it can be sent.
|
||||
Basic use pattern for synchronous querying the DNS at a
|
||||
server configured on 127.0.0.1 and port 53:
|
||||
|
||||
|
|
@ -63,7 +63,23 @@ class) is as easy as setting:
|
|||
|
||||
c.SingleInflight = true
|
||||
|
||||
If these "advanced" features are not needed, a simple UDP query can be send,
|
||||
More advanced options are availabe using a net.Dialer and the corresponding API.
|
||||
For example it is possible to set a timeout, or to specify a source IP address
|
||||
and port to use for the connection:
|
||||
|
||||
c := new(dns.Client)
|
||||
laddr := net.UDPAddr{
|
||||
IP: net.ParseIP("[::1]"),
|
||||
Port: 12345,
|
||||
Zone: "",
|
||||
}
|
||||
d := net.Dialer{
|
||||
Timeout: 200 * time.Millisecond,
|
||||
LocalAddr: &laddr,
|
||||
}
|
||||
in, rtt, err := c.ExchangeWithDialer(&d, m1, "8.8.8.8:53")
|
||||
|
||||
If these "advanced" features are not needed, a simple UDP query can be sent,
|
||||
with:
|
||||
|
||||
in, err := dns.Exchange(m1, "127.0.0.1:53")
|
||||
|
|
|
|||
15
vendor/github.com/miekg/dns/edns.go
generated
vendored
15
vendor/github.com/miekg/dns/edns.go
generated
vendored
|
|
@ -21,6 +21,7 @@ const (
|
|||
EDNS0EXPIRE = 0x9 // EDNS0 expire
|
||||
EDNS0COOKIE = 0xa // EDNS0 Cookie
|
||||
EDNS0TCPKEEPALIVE = 0xb // EDNS0 tcp keep alive (RFC7828)
|
||||
EDNS0PADDING = 0xc // EDNS0 padding (RFC7830)
|
||||
EDNS0SUBNETDRAFT = 0x50fa // Don't use! Use EDNS0SUBNET
|
||||
EDNS0LOCALSTART = 0xFDE9 // Beginning of range reserved for local/experimental use (RFC6891)
|
||||
EDNS0LOCALEND = 0xFFFE // End of range reserved for local/experimental use (RFC6891)
|
||||
|
|
@ -74,6 +75,8 @@ func (rr *OPT) String() string {
|
|||
s += "\n; NSEC3 HASH UNDERSTOOD: " + o.String()
|
||||
case *EDNS0_LOCAL:
|
||||
s += "\n; LOCAL OPT: " + o.String()
|
||||
case *EDNS0_PADDING:
|
||||
s += "\n; PADDING: " + o.String()
|
||||
}
|
||||
}
|
||||
return s
|
||||
|
|
@ -595,3 +598,15 @@ func (e *EDNS0_TCP_KEEPALIVE) String() (s string) {
|
|||
}
|
||||
return
|
||||
}
|
||||
|
||||
// EDNS0_PADDING option is used to add padding to a request/response. The default
|
||||
// value of padding SHOULD be 0x0 but other values MAY be used, for instance if
|
||||
// compression is applied before encryption which may break signatures.
|
||||
type EDNS0_PADDING struct {
|
||||
Padding []byte
|
||||
}
|
||||
|
||||
func (e *EDNS0_PADDING) pack() ([]byte, error) { return e.Padding, nil }
|
||||
func (e *EDNS0_PADDING) Option() uint16 { return EDNS0PADDING }
|
||||
func (e *EDNS0_PADDING) unpack(b []byte) error { e.Padding = b; return nil }
|
||||
func (e *EDNS0_PADDING) String() string { return fmt.Sprintf("%0X", e.Padding) }
|
||||
|
|
|
|||
7
vendor/github.com/miekg/dns/internal/socket/cmsghdr.go
generated
vendored
Normal file
7
vendor/github.com/miekg/dns/internal/socket/cmsghdr.go
generated
vendored
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
// +build linux
|
||||
|
||||
package socket
|
||||
|
||||
func (h *cmsghdr) len() int { return int(h.Len) }
|
||||
func (h *cmsghdr) lvl() int { return int(h.Level) }
|
||||
func (h *cmsghdr) typ() int { return int(h.Type) }
|
||||
20
vendor/github.com/miekg/dns/internal/socket/cmsghdr_linux_32bit.go
generated
vendored
Normal file
20
vendor/github.com/miekg/dns/internal/socket/cmsghdr_linux_32bit.go
generated
vendored
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
// +build arm mips mipsle 386
|
||||
// +build linux
|
||||
|
||||
package socket
|
||||
|
||||
type cmsghdr struct {
|
||||
Len uint32
|
||||
Level int32
|
||||
Type int32
|
||||
}
|
||||
|
||||
const (
|
||||
sizeofCmsghdr = 0xc
|
||||
)
|
||||
|
||||
func (h *cmsghdr) set(l, lvl, typ int) {
|
||||
h.Len = uint32(l)
|
||||
h.Level = int32(lvl)
|
||||
h.Type = int32(typ)
|
||||
}
|
||||
20
vendor/github.com/miekg/dns/internal/socket/cmsghdr_linux_64bit.go
generated
vendored
Normal file
20
vendor/github.com/miekg/dns/internal/socket/cmsghdr_linux_64bit.go
generated
vendored
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
// +build arm64 amd64 ppc64 ppc64le mips64 mips64le s390x
|
||||
// +build linux
|
||||
|
||||
package socket
|
||||
|
||||
type cmsghdr struct {
|
||||
Len uint64
|
||||
Level int32
|
||||
Type int32
|
||||
}
|
||||
|
||||
const (
|
||||
sizeofCmsghdr = 0x10
|
||||
)
|
||||
|
||||
func (h *cmsghdr) set(l, lvl, typ int) {
|
||||
h.Len = uint64(l)
|
||||
h.Level = int32(lvl)
|
||||
h.Type = int32(typ)
|
||||
}
|
||||
13
vendor/github.com/miekg/dns/internal/socket/cmsghdr_other.go
generated
vendored
Normal file
13
vendor/github.com/miekg/dns/internal/socket/cmsghdr_other.go
generated
vendored
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
// +build !linux
|
||||
|
||||
package socket
|
||||
|
||||
type cmsghdr struct{}
|
||||
|
||||
const sizeofCmsghdr = 0
|
||||
|
||||
func (h *cmsghdr) len() int { return 0 }
|
||||
func (h *cmsghdr) lvl() int { return 0 }
|
||||
func (h *cmsghdr) typ() int { return 0 }
|
||||
|
||||
func (h *cmsghdr) set(l, lvl, typ int) {}
|
||||
118
vendor/github.com/miekg/dns/internal/socket/controlmessage.go
generated
vendored
Normal file
118
vendor/github.com/miekg/dns/internal/socket/controlmessage.go
generated
vendored
Normal file
|
|
@ -0,0 +1,118 @@
|
|||
package socket
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
func controlHeaderLen() int {
|
||||
return roundup(sizeofCmsghdr)
|
||||
}
|
||||
|
||||
func controlMessageLen(dataLen int) int {
|
||||
return roundup(sizeofCmsghdr) + dataLen
|
||||
}
|
||||
|
||||
// returns the whole length of control message.
|
||||
func ControlMessageSpace(dataLen int) int {
|
||||
return roundup(sizeofCmsghdr) + roundup(dataLen)
|
||||
}
|
||||
|
||||
// A ControlMessage represents the head message in a stream of control
|
||||
// messages.
|
||||
//
|
||||
// A control message comprises of a header, data and a few padding
|
||||
// fields to conform to the interface to the kernel.
|
||||
//
|
||||
// See RFC 3542 for further information.
|
||||
type ControlMessage []byte
|
||||
|
||||
// Data returns the data field of the control message at the head.
|
||||
func (m ControlMessage) Data(dataLen int) []byte {
|
||||
l := controlHeaderLen()
|
||||
if len(m) < l || len(m) < l+dataLen {
|
||||
return nil
|
||||
}
|
||||
return m[l : l+dataLen]
|
||||
}
|
||||
|
||||
// ParseHeader parses and returns the header fields of the control
|
||||
// message at the head.
|
||||
func (m ControlMessage) ParseHeader() (lvl, typ, dataLen int, err error) {
|
||||
l := controlHeaderLen()
|
||||
if len(m) < l {
|
||||
return 0, 0, 0, errors.New("short message")
|
||||
}
|
||||
h := (*cmsghdr)(unsafe.Pointer(&m[0]))
|
||||
return h.lvl(), h.typ(), int(uint64(h.len()) - uint64(l)), nil
|
||||
}
|
||||
|
||||
// Next returns the control message at the next.
|
||||
func (m ControlMessage) Next(dataLen int) ControlMessage {
|
||||
l := ControlMessageSpace(dataLen)
|
||||
if len(m) < l {
|
||||
return nil
|
||||
}
|
||||
return m[l:]
|
||||
}
|
||||
|
||||
// MarshalHeader marshals the header fields of the control message at
|
||||
// the head.
|
||||
func (m ControlMessage) MarshalHeader(lvl, typ, dataLen int) error {
|
||||
if len(m) < controlHeaderLen() {
|
||||
return errors.New("short message")
|
||||
}
|
||||
h := (*cmsghdr)(unsafe.Pointer(&m[0]))
|
||||
h.set(controlMessageLen(dataLen), lvl, typ)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Marshal marshals the control message at the head, and returns the next
|
||||
// control message.
|
||||
func (m ControlMessage) Marshal(lvl, typ int, data []byte) (ControlMessage, error) {
|
||||
l := len(data)
|
||||
if len(m) < ControlMessageSpace(l) {
|
||||
return nil, errors.New("short message")
|
||||
}
|
||||
h := (*cmsghdr)(unsafe.Pointer(&m[0]))
|
||||
h.set(controlMessageLen(l), lvl, typ)
|
||||
if l > 0 {
|
||||
copy(m.Data(l), data)
|
||||
}
|
||||
return m.Next(l), nil
|
||||
}
|
||||
|
||||
// Parse parses as a single or multiple control messages.
|
||||
func (m ControlMessage) Parse() ([]ControlMessage, error) {
|
||||
var ms []ControlMessage
|
||||
for len(m) >= controlHeaderLen() {
|
||||
h := (*cmsghdr)(unsafe.Pointer(&m[0]))
|
||||
l := h.len()
|
||||
if l <= 0 {
|
||||
return nil, errors.New("invalid header length")
|
||||
}
|
||||
if uint64(l) < uint64(controlHeaderLen()) {
|
||||
return nil, errors.New("invalid message length")
|
||||
}
|
||||
if uint64(l) > uint64(len(m)) {
|
||||
return nil, errors.New("short buffer")
|
||||
}
|
||||
ms = append(ms, ControlMessage(m[:l]))
|
||||
ll := l - controlHeaderLen()
|
||||
if len(m) >= ControlMessageSpace(ll) {
|
||||
m = m[ControlMessageSpace(ll):]
|
||||
} else {
|
||||
m = m[controlMessageLen(ll):]
|
||||
}
|
||||
}
|
||||
return ms, nil
|
||||
}
|
||||
|
||||
// NewControlMessage returns a new stream of control messages.
|
||||
func NewControlMessage(dataLen []int) ControlMessage {
|
||||
var l int
|
||||
for i := range dataLen {
|
||||
l += ControlMessageSpace(dataLen[i])
|
||||
}
|
||||
return make([]byte, l)
|
||||
}
|
||||
103
vendor/github.com/miekg/dns/internal/socket/controlmessage_test.go
generated
vendored
Normal file
103
vendor/github.com/miekg/dns/internal/socket/controlmessage_test.go
generated
vendored
Normal file
|
|
@ -0,0 +1,103 @@
|
|||
// +build linux
|
||||
|
||||
package socket
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"testing"
|
||||
)
|
||||
|
||||
type mockControl struct {
|
||||
Level int
|
||||
Type int
|
||||
Data []byte
|
||||
}
|
||||
|
||||
func TestControlMessage(t *testing.T) {
|
||||
for _, tt := range []struct {
|
||||
cs []mockControl
|
||||
}{
|
||||
{
|
||||
[]mockControl{
|
||||
{Level: 1, Type: 1},
|
||||
},
|
||||
},
|
||||
{
|
||||
[]mockControl{
|
||||
{Level: 2, Type: 2, Data: []byte{0xfe}},
|
||||
},
|
||||
},
|
||||
{
|
||||
[]mockControl{
|
||||
{Level: 3, Type: 3, Data: []byte{0xfe, 0xff, 0xff, 0xfe}},
|
||||
},
|
||||
},
|
||||
{
|
||||
[]mockControl{
|
||||
{Level: 4, Type: 4, Data: []byte{0xfe, 0xff, 0xff, 0xfe, 0xfe, 0xff, 0xff, 0xfe}},
|
||||
},
|
||||
},
|
||||
{
|
||||
[]mockControl{
|
||||
{Level: 4, Type: 4, Data: []byte{0xfe, 0xff, 0xff, 0xfe, 0xfe, 0xff, 0xff, 0xfe}},
|
||||
{Level: 2, Type: 2, Data: []byte{0xfe}},
|
||||
},
|
||||
},
|
||||
} {
|
||||
var w []byte
|
||||
var tailPadLen int
|
||||
mm := NewControlMessage([]int{0})
|
||||
for i, c := range tt.cs {
|
||||
m := NewControlMessage([]int{len(c.Data)})
|
||||
l := len(m) - len(mm)
|
||||
if i == len(tt.cs)-1 && l > len(c.Data) {
|
||||
tailPadLen = l - len(c.Data)
|
||||
}
|
||||
w = append(w, m...)
|
||||
}
|
||||
|
||||
var err error
|
||||
ww := make([]byte, len(w))
|
||||
copy(ww, w)
|
||||
m := ControlMessage(ww)
|
||||
for _, c := range tt.cs {
|
||||
if err = m.MarshalHeader(c.Level, c.Type, len(c.Data)); err != nil {
|
||||
t.Fatalf("(%v).MarshalHeader() = %v", tt.cs, err)
|
||||
}
|
||||
copy(m.Data(len(c.Data)), c.Data)
|
||||
m = m.Next(len(c.Data))
|
||||
}
|
||||
m = ControlMessage(w)
|
||||
for _, c := range tt.cs {
|
||||
m, err = m.Marshal(c.Level, c.Type, c.Data)
|
||||
if err != nil {
|
||||
t.Fatalf("(%v).Marshal() = %v", tt.cs, err)
|
||||
}
|
||||
}
|
||||
if !bytes.Equal(ww, w) {
|
||||
t.Fatalf("got %#v; want %#v", ww, w)
|
||||
}
|
||||
|
||||
ws := [][]byte{w}
|
||||
if tailPadLen > 0 {
|
||||
// Test a message with no tail padding.
|
||||
nopad := w[:len(w)-tailPadLen]
|
||||
ws = append(ws, [][]byte{nopad}...)
|
||||
}
|
||||
for _, w := range ws {
|
||||
ms, err := ControlMessage(w).Parse()
|
||||
if err != nil {
|
||||
t.Fatalf("(%v).Parse() = %v", tt.cs, err)
|
||||
}
|
||||
for i, m := range ms {
|
||||
lvl, typ, dataLen, err := m.ParseHeader()
|
||||
if err != nil {
|
||||
t.Fatalf("(%v).ParseHeader() = %v", tt.cs, err)
|
||||
}
|
||||
if lvl != tt.cs[i].Level || typ != tt.cs[i].Type || dataLen != len(tt.cs[i].Data) {
|
||||
t.Fatalf("%v: got %d, %d, %d; want %d, %d, %d", tt.cs[i], lvl, typ, dataLen, tt.cs[i].Level, tt.cs[i].Type, len(tt.cs[i].Data))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
4
vendor/github.com/miekg/dns/internal/socket/socket.go
generated
vendored
Normal file
4
vendor/github.com/miekg/dns/internal/socket/socket.go
generated
vendored
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
// Package socket contains ControlMessage parsing code from
|
||||
// golang.org/x/net/internal/socket. Instead of supporting all possible
|
||||
// architectures, we're only supporting linux 32/64 bit.
|
||||
package socket
|
||||
14
vendor/github.com/miekg/dns/internal/socket/sys.go
generated
vendored
Normal file
14
vendor/github.com/miekg/dns/internal/socket/sys.go
generated
vendored
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
package socket
|
||||
|
||||
import "unsafe"
|
||||
|
||||
var (
|
||||
kernelAlign = func() int {
|
||||
var p uintptr
|
||||
return int(unsafe.Sizeof(p))
|
||||
}()
|
||||
)
|
||||
|
||||
func roundup(l int) int {
|
||||
return (l + kernelAlign - 1) & ^(kernelAlign - 1)
|
||||
}
|
||||
7
vendor/github.com/miekg/dns/msg_helpers.go
generated
vendored
7
vendor/github.com/miekg/dns/msg_helpers.go
generated
vendored
|
|
@ -458,6 +458,13 @@ Option:
|
|||
}
|
||||
edns = append(edns, e)
|
||||
off += int(optlen)
|
||||
case EDNS0PADDING:
|
||||
e := new(EDNS0_PADDING)
|
||||
if err := e.unpack(msg[off : off+int(optlen)]); err != nil {
|
||||
return nil, len(msg), err
|
||||
}
|
||||
edns = append(edns, e)
|
||||
off += int(optlen)
|
||||
default:
|
||||
e := new(EDNS0_LOCAL)
|
||||
e.Code = code
|
||||
|
|
|
|||
188
vendor/github.com/miekg/dns/parse_test.go
generated
vendored
188
vendor/github.com/miekg/dns/parse_test.go
generated
vendored
|
|
@ -8,6 +8,7 @@ import (
|
|||
"math/rand"
|
||||
"net"
|
||||
"reflect"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
"testing"
|
||||
|
|
@ -571,81 +572,88 @@ test IN CNAME test.a.example.com.
|
|||
t.Logf("%d RRs parsed in %.2f s (%.2f RR/s)", i, float32(delta)/1e9, float32(i)/(float32(delta)/1e9))
|
||||
}
|
||||
|
||||
func ExampleParseZone() {
|
||||
zone := `$ORIGIN .
|
||||
$TTL 3600 ; 1 hour
|
||||
name IN SOA a6.nstld.com. hostmaster.nic.name. (
|
||||
203362132 ; serial
|
||||
300 ; refresh (5 minutes)
|
||||
300 ; retry (5 minutes)
|
||||
1209600 ; expire (2 weeks)
|
||||
300 ; minimum (5 minutes)
|
||||
)
|
||||
$TTL 10800 ; 3 hours
|
||||
name. 10800 IN NS name.
|
||||
IN NS g6.nstld.com.
|
||||
7200 NS h6.nstld.com.
|
||||
3600 IN NS j6.nstld.com.
|
||||
IN 3600 NS k6.nstld.com.
|
||||
NS l6.nstld.com.
|
||||
NS a6.nstld.com.
|
||||
NS c6.nstld.com.
|
||||
NS d6.nstld.com.
|
||||
NS f6.nstld.com.
|
||||
NS m6.nstld.com.
|
||||
(
|
||||
NS m7.nstld.com.
|
||||
)
|
||||
$ORIGIN name.
|
||||
0-0onlus NS ns7.ehiweb.it.
|
||||
NS ns8.ehiweb.it.
|
||||
0-g MX 10 mx01.nic
|
||||
MX 10 mx02.nic
|
||||
MX 10 mx03.nic
|
||||
MX 10 mx04.nic
|
||||
$ORIGIN 0-g.name
|
||||
moutamassey NS ns01.yahoodomains.jp.
|
||||
NS ns02.yahoodomains.jp.
|
||||
func TestOmittedTTL(t *testing.T) {
|
||||
zone := `
|
||||
$ORIGIN example.com.
|
||||
example.com. 42 IN SOA ns1.example.com. hostmaster.example.com. 1 86400 60 86400 3600 ; TTL=42 SOA
|
||||
example.com. NS 2 ; TTL=42 absolute owner name
|
||||
@ MD 3 ; TTL=42 current-origin owner name
|
||||
MF 4 ; TTL=42 leading-space implied owner name
|
||||
43 TYPE65280 \# 1 05 ; TTL=43 implied owner name explicit TTL
|
||||
MB 6 ; TTL=43 leading-tab implied owner name
|
||||
$TTL 1337
|
||||
example.com. 88 MG 7 ; TTL=88 explicit TTL
|
||||
example.com. MR 8 ; TTL=1337 after first $TTL
|
||||
$TTL 314
|
||||
1 TXT 9 ; TTL=1 implied owner name explicit TTL
|
||||
example.com. DNAME 10 ; TTL=314 after second $TTL
|
||||
`
|
||||
to := ParseZone(strings.NewReader(zone), "", "testzone")
|
||||
for x := range to {
|
||||
fmt.Println(x.RR)
|
||||
reCaseFromComment := regexp.MustCompile(`TTL=(\d+)\s+(.*)`)
|
||||
records := ParseZone(strings.NewReader(zone), "", "")
|
||||
var i int
|
||||
for record := range records {
|
||||
i++
|
||||
if record.Error != nil {
|
||||
t.Error(record.Error)
|
||||
continue
|
||||
}
|
||||
expected := reCaseFromComment.FindStringSubmatch(record.Comment)
|
||||
expectedTTL, _ := strconv.ParseUint(expected[1], 10, 32)
|
||||
ttl := record.RR.Header().Ttl
|
||||
if ttl != uint32(expectedTTL) {
|
||||
t.Errorf("%s: expected TTL %d, got %d", expected[2], expectedTTL, ttl)
|
||||
}
|
||||
}
|
||||
if i != 10 {
|
||||
t.Errorf("expected %d records, got %d", 5, i)
|
||||
}
|
||||
// Output:
|
||||
// name. 3600 IN SOA a6.nstld.com. hostmaster.nic.name. 203362132 300 300 1209600 300
|
||||
// name. 10800 IN NS name.
|
||||
// name. 10800 IN NS g6.nstld.com.
|
||||
// name. 7200 IN NS h6.nstld.com.
|
||||
// name. 3600 IN NS j6.nstld.com.
|
||||
// name. 3600 IN NS k6.nstld.com.
|
||||
// name. 10800 IN NS l6.nstld.com.
|
||||
// name. 10800 IN NS a6.nstld.com.
|
||||
// name. 10800 IN NS c6.nstld.com.
|
||||
// name. 10800 IN NS d6.nstld.com.
|
||||
// name. 10800 IN NS f6.nstld.com.
|
||||
// name. 10800 IN NS m6.nstld.com.
|
||||
// name. 10800 IN NS m7.nstld.com.
|
||||
// 0-0onlus.name. 10800 IN NS ns7.ehiweb.it.
|
||||
// 0-0onlus.name. 10800 IN NS ns8.ehiweb.it.
|
||||
// 0-g.name. 10800 IN MX 10 mx01.nic.name.
|
||||
// 0-g.name. 10800 IN MX 10 mx02.nic.name.
|
||||
// 0-g.name. 10800 IN MX 10 mx03.nic.name.
|
||||
// 0-g.name. 10800 IN MX 10 mx04.nic.name.
|
||||
// moutamassey.0-g.name.name. 10800 IN NS ns01.yahoodomains.jp.
|
||||
// moutamassey.0-g.name.name. 10800 IN NS ns02.yahoodomains.jp.
|
||||
}
|
||||
|
||||
func ExampleHIP() {
|
||||
h := `www.example.com IN HIP ( 2 200100107B1A74DF365639CC39F1D578
|
||||
AwEAAbdxyhNuSutc5EMzxTs9LBPCIkOFH8cIvM4p
|
||||
9+LrV4e19WzK00+CI6zBCQTdtWsuxKbWIy87UOoJTwkUs7lBu+Upr1gsNrut79ryra+bSRGQ
|
||||
b1slImA8YVJyuIDsj7kwzG7jnERNqnWxZ48AWkskmdHaVDP4BcelrTI3rMXdXF5D
|
||||
rvs.example.com. )`
|
||||
if hip, err := NewRR(h); err == nil {
|
||||
fmt.Println(hip.String())
|
||||
func TestRelativeNameErrors(t *testing.T) {
|
||||
var badZones = []struct {
|
||||
label string
|
||||
zoneContents string
|
||||
expectedErr string
|
||||
}{
|
||||
{
|
||||
"relative owner name without origin",
|
||||
"example.com 3600 IN SOA ns.example.com. hostmaster.example.com. 1 86400 60 86400 3600",
|
||||
"bad owner name",
|
||||
},
|
||||
{
|
||||
"relative owner name in RDATA",
|
||||
"example.com. 3600 IN SOA ns hostmaster 1 86400 60 86400 3600",
|
||||
"bad SOA Ns",
|
||||
},
|
||||
{
|
||||
"origin reference without origin",
|
||||
"@ 3600 IN SOA ns.example.com. hostmaster.example.com. 1 86400 60 86400 3600",
|
||||
"bad owner name",
|
||||
},
|
||||
{
|
||||
"relative owner name in $INCLUDE",
|
||||
"$INCLUDE file.db example.com",
|
||||
"bad origin name",
|
||||
},
|
||||
{
|
||||
"relative owner name in $ORIGIN",
|
||||
"$ORIGIN example.com",
|
||||
"bad origin name",
|
||||
},
|
||||
}
|
||||
for _, errorCase := range badZones {
|
||||
entries := ParseZone(strings.NewReader(errorCase.zoneContents), "", "")
|
||||
for entry := range entries {
|
||||
if entry.Error == nil {
|
||||
t.Errorf("%s: expected error, got nil", errorCase.label)
|
||||
continue
|
||||
}
|
||||
err := entry.Error.err
|
||||
if err != errorCase.expectedErr {
|
||||
t.Errorf("%s: expected error `%s`, got `%s`", errorCase.label, errorCase.expectedErr, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
// Output:
|
||||
// www.example.com. 3600 IN HIP 2 200100107B1A74DF365639CC39F1D578 AwEAAbdxyhNuSutc5EMzxTs9LBPCIkOFH8cIvM4p9+LrV4e19WzK00+CI6zBCQTdtWsuxKbWIy87UOoJTwkUs7lBu+Upr1gsNrut79ryra+bSRGQb1slImA8YVJyuIDsj7kwzG7jnERNqnWxZ48AWkskmdHaVDP4BcelrTI3rMXdXF5D rvs.example.com.
|
||||
}
|
||||
|
||||
func TestHIP(t *testing.T) {
|
||||
|
|
@ -686,24 +694,6 @@ b1slImA8YVJyuIDsj7kwzG7jnERNqnWxZ48AWkskmdHaVDP4BcelrTI3rMXdXF5D
|
|||
}
|
||||
}
|
||||
|
||||
func ExampleSOA() {
|
||||
s := "example.com. 1000 SOA master.example.com. admin.example.com. 1 4294967294 4294967293 4294967295 100"
|
||||
if soa, err := NewRR(s); err == nil {
|
||||
fmt.Println(soa.String())
|
||||
}
|
||||
// Output:
|
||||
// example.com. 1000 IN SOA master.example.com. admin.example.com. 1 4294967294 4294967293 4294967295 100
|
||||
}
|
||||
|
||||
func TestLineNumberError(t *testing.T) {
|
||||
s := "example.com. 1000 SOA master.example.com. admin.example.com. monkey 4294967294 4294967293 4294967295 100"
|
||||
if _, err := NewRR(s); err != nil {
|
||||
if err.Error() != "dns: bad SOA zone parameter: \"monkey\" at line: 1:68" {
|
||||
t.Error("not expecting this error: ", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Test with no known RR on the line
|
||||
func TestLineNumberError2(t *testing.T) {
|
||||
tests := map[string]string{
|
||||
|
|
@ -801,28 +791,6 @@ func TestLowercaseTokens(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func ExampleParseZone_generate() {
|
||||
// From the manual: http://www.bind9.net/manual/bind/9.3.2/Bv9ARM.ch06.html#id2566761
|
||||
zone := "$GENERATE 1-2 0 NS SERVER$.EXAMPLE.\n$GENERATE 1-8 $ CNAME $.0"
|
||||
to := ParseZone(strings.NewReader(zone), "0.0.192.IN-ADDR.ARPA.", "")
|
||||
for x := range to {
|
||||
if x.Error == nil {
|
||||
fmt.Println(x.RR.String())
|
||||
}
|
||||
}
|
||||
// Output:
|
||||
// 0.0.0.192.IN-ADDR.ARPA. 3600 IN NS SERVER1.EXAMPLE.
|
||||
// 0.0.0.192.IN-ADDR.ARPA. 3600 IN NS SERVER2.EXAMPLE.
|
||||
// 1.0.0.192.IN-ADDR.ARPA. 3600 IN CNAME 1.0.0.0.192.IN-ADDR.ARPA.
|
||||
// 2.0.0.192.IN-ADDR.ARPA. 3600 IN CNAME 2.0.0.0.192.IN-ADDR.ARPA.
|
||||
// 3.0.0.192.IN-ADDR.ARPA. 3600 IN CNAME 3.0.0.0.192.IN-ADDR.ARPA.
|
||||
// 4.0.0.192.IN-ADDR.ARPA. 3600 IN CNAME 4.0.0.0.192.IN-ADDR.ARPA.
|
||||
// 5.0.0.192.IN-ADDR.ARPA. 3600 IN CNAME 5.0.0.0.192.IN-ADDR.ARPA.
|
||||
// 6.0.0.192.IN-ADDR.ARPA. 3600 IN CNAME 6.0.0.0.192.IN-ADDR.ARPA.
|
||||
// 7.0.0.192.IN-ADDR.ARPA. 3600 IN CNAME 7.0.0.0.192.IN-ADDR.ARPA.
|
||||
// 8.0.0.192.IN-ADDR.ARPA. 3600 IN CNAME 8.0.0.0.192.IN-ADDR.ARPA.
|
||||
}
|
||||
|
||||
func TestSRVPacking(t *testing.T) {
|
||||
msg := Msg{}
|
||||
|
||||
|
|
|
|||
2
vendor/github.com/miekg/dns/privaterr_test.go
generated
vendored
2
vendor/github.com/miekg/dns/privaterr_test.go
generated
vendored
|
|
@ -143,7 +143,7 @@ func (rd *VERSION) Len() int {
|
|||
}
|
||||
|
||||
var smallzone = `$ORIGIN example.org.
|
||||
@ SOA sns.dns.icann.org. noc.dns.icann.org. (
|
||||
@ 3600 IN SOA sns.dns.icann.org. noc.dns.icann.org. (
|
||||
2014091518 7200 3600 1209600 3600
|
||||
)
|
||||
A 1.2.3.4
|
||||
|
|
|
|||
129
vendor/github.com/miekg/dns/scan.go
generated
vendored
129
vendor/github.com/miekg/dns/scan.go
generated
vendored
|
|
@ -105,6 +105,12 @@ type Token struct {
|
|||
Comment string
|
||||
}
|
||||
|
||||
// ttlState describes the state necessary to fill in an omitted RR TTL
|
||||
type ttlState struct {
|
||||
ttl uint32 // ttl is the current default TTL
|
||||
isByDirective bool // isByDirective indicates whether ttl was set by a $TTL directive
|
||||
}
|
||||
|
||||
// NewRR reads the RR contained in the string s. Only the first RR is
|
||||
// returned. If s contains no RR, return nil with no error. The class
|
||||
// defaults to IN and TTL defaults to 3600. The full zone file syntax
|
||||
|
|
@ -120,7 +126,8 @@ func NewRR(s string) (RR, error) {
|
|||
// ReadRR reads the RR contained in q.
|
||||
// See NewRR for more documentation.
|
||||
func ReadRR(q io.Reader, filename string) (RR, error) {
|
||||
r := <-parseZoneHelper(q, ".", filename, 1)
|
||||
defttl := &ttlState{defaultTtl, false}
|
||||
r := <-parseZoneHelper(q, ".", defttl, filename, 1)
|
||||
if r == nil {
|
||||
return nil, nil
|
||||
}
|
||||
|
|
@ -132,10 +139,10 @@ func ReadRR(q io.Reader, filename string) (RR, error) {
|
|||
}
|
||||
|
||||
// ParseZone reads a RFC 1035 style zonefile from r. It returns *Tokens on the
|
||||
// returned channel, which consist out the parsed RR, a potential comment or an error.
|
||||
// If there is an error the RR is nil. The string file is only used
|
||||
// returned channel, each consisting of either a parsed RR and optional comment
|
||||
// or a nil RR and an error. The string file is only used
|
||||
// in error reporting. The string origin is used as the initial origin, as
|
||||
// if the file would start with: $ORIGIN origin .
|
||||
// if the file would start with an $ORIGIN directive.
|
||||
// The directives $INCLUDE, $ORIGIN, $TTL and $GENERATE are supported.
|
||||
// The channel t is closed by ParseZone when the end of r is reached.
|
||||
//
|
||||
|
|
@ -157,16 +164,16 @@ func ReadRR(q io.Reader, filename string) (RR, error) {
|
|||
// The text "; this is comment" is returned in Token.Comment. Comments inside the
|
||||
// RR are discarded. Comments on a line by themselves are discarded too.
|
||||
func ParseZone(r io.Reader, origin, file string) chan *Token {
|
||||
return parseZoneHelper(r, origin, file, 10000)
|
||||
return parseZoneHelper(r, origin, nil, file, 10000)
|
||||
}
|
||||
|
||||
func parseZoneHelper(r io.Reader, origin, file string, chansize int) chan *Token {
|
||||
func parseZoneHelper(r io.Reader, origin string, defttl *ttlState, file string, chansize int) chan *Token {
|
||||
t := make(chan *Token, chansize)
|
||||
go parseZone(r, origin, file, t, 0)
|
||||
go parseZone(r, origin, defttl, file, t, 0)
|
||||
return t
|
||||
}
|
||||
|
||||
func parseZone(r io.Reader, origin, f string, t chan *Token, include int) {
|
||||
func parseZone(r io.Reader, origin string, defttl *ttlState, f string, t chan *Token, include int) {
|
||||
defer func() {
|
||||
if include == 0 {
|
||||
close(t)
|
||||
|
|
@ -186,18 +193,16 @@ func parseZone(r io.Reader, origin, f string, t chan *Token, include int) {
|
|||
// After detecting these, we know the zRrtype so we can jump to functions
|
||||
// handling the rdata for each of these types.
|
||||
|
||||
if origin == "" {
|
||||
origin = "."
|
||||
}
|
||||
origin = Fqdn(origin)
|
||||
if _, ok := IsDomainName(origin); !ok {
|
||||
t <- &Token{Error: &ParseError{f, "bad initial origin name", lex{}}}
|
||||
return
|
||||
if origin != "" {
|
||||
origin = Fqdn(origin)
|
||||
if _, ok := IsDomainName(origin); !ok {
|
||||
t <- &Token{Error: &ParseError{f, "bad initial origin name", lex{}}}
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
st := zExpectOwnerDir // initial state
|
||||
var h RR_Header
|
||||
var defttl uint32 = defaultTtl
|
||||
var prevName string
|
||||
for l := range c {
|
||||
// Lexer spotted an error already
|
||||
|
|
@ -209,27 +214,21 @@ func parseZone(r io.Reader, origin, f string, t chan *Token, include int) {
|
|||
switch st {
|
||||
case zExpectOwnerDir:
|
||||
// We can also expect a directive, like $TTL or $ORIGIN
|
||||
h.Ttl = defttl
|
||||
if defttl != nil {
|
||||
h.Ttl = defttl.ttl
|
||||
}
|
||||
h.Class = ClassINET
|
||||
switch l.value {
|
||||
case zNewline:
|
||||
st = zExpectOwnerDir
|
||||
case zOwner:
|
||||
h.Name = l.token
|
||||
if l.token[0] == '@' {
|
||||
h.Name = origin
|
||||
prevName = h.Name
|
||||
st = zExpectOwnerBl
|
||||
break
|
||||
}
|
||||
if h.Name[l.length-1] != '.' {
|
||||
h.Name = appendOrigin(h.Name, origin)
|
||||
}
|
||||
_, ok := IsDomainName(l.token)
|
||||
name, ok := toAbsoluteName(l.token, origin)
|
||||
if !ok {
|
||||
t <- &Token{Error: &ParseError{f, "bad owner name", l}}
|
||||
return
|
||||
}
|
||||
h.Name = name
|
||||
prevName = h.Name
|
||||
st = zExpectOwnerBl
|
||||
case zDirTtl:
|
||||
|
|
@ -258,8 +257,9 @@ func parseZone(r io.Reader, origin, f string, t chan *Token, include int) {
|
|||
return
|
||||
}
|
||||
h.Ttl = ttl
|
||||
// Don't about the defttl, we should take the $TTL value
|
||||
// defttl = ttl
|
||||
if defttl == nil || !defttl.isByDirective {
|
||||
defttl = &ttlState{ttl, false}
|
||||
}
|
||||
st = zExpectAnyNoTtlBl
|
||||
|
||||
default:
|
||||
|
|
@ -282,20 +282,12 @@ func parseZone(r io.Reader, origin, f string, t chan *Token, include int) {
|
|||
case zBlank:
|
||||
l := <-c
|
||||
if l.value == zString {
|
||||
if _, ok := IsDomainName(l.token); !ok || l.length == 0 || l.err {
|
||||
name, ok := toAbsoluteName(l.token, origin)
|
||||
if !ok {
|
||||
t <- &Token{Error: &ParseError{f, "bad origin name", l}}
|
||||
return
|
||||
}
|
||||
// a new origin is specified.
|
||||
if l.token[l.length-1] != '.' {
|
||||
if origin != "." { // Prevent .. endings
|
||||
neworigin = l.token + "." + origin
|
||||
} else {
|
||||
neworigin = l.token + origin
|
||||
}
|
||||
} else {
|
||||
neworigin = l.token
|
||||
}
|
||||
neworigin = name
|
||||
}
|
||||
case zNewline, zEOF:
|
||||
// Ok
|
||||
|
|
@ -313,7 +305,7 @@ func parseZone(r io.Reader, origin, f string, t chan *Token, include int) {
|
|||
t <- &Token{Error: &ParseError{f, "too deeply nested $INCLUDE", l}}
|
||||
return
|
||||
}
|
||||
parseZone(r1, l.token, neworigin, t, include+1)
|
||||
parseZone(r1, neworigin, defttl, l.token, t, include+1)
|
||||
st = zExpectOwnerDir
|
||||
case zExpectDirTtlBl:
|
||||
if l.value != zBlank {
|
||||
|
|
@ -335,7 +327,7 @@ func parseZone(r io.Reader, origin, f string, t chan *Token, include int) {
|
|||
t <- &Token{Error: &ParseError{f, "expecting $TTL value, not this...", l}}
|
||||
return
|
||||
}
|
||||
defttl = ttl
|
||||
defttl = &ttlState{ttl, true}
|
||||
st = zExpectOwnerDir
|
||||
case zExpectDirOriginBl:
|
||||
if l.value != zBlank {
|
||||
|
|
@ -351,19 +343,12 @@ func parseZone(r io.Reader, origin, f string, t chan *Token, include int) {
|
|||
if e, _ := slurpRemainder(c, f); e != nil {
|
||||
t <- &Token{Error: e}
|
||||
}
|
||||
if _, ok := IsDomainName(l.token); !ok {
|
||||
name, ok := toAbsoluteName(l.token, origin)
|
||||
if !ok {
|
||||
t <- &Token{Error: &ParseError{f, "bad origin name", l}}
|
||||
return
|
||||
}
|
||||
if l.token[l.length-1] != '.' {
|
||||
if origin != "." { // Prevent .. endings
|
||||
origin = l.token + "." + origin
|
||||
} else {
|
||||
origin = l.token + origin
|
||||
}
|
||||
} else {
|
||||
origin = l.token
|
||||
}
|
||||
origin = name
|
||||
st = zExpectOwnerDir
|
||||
case zExpectDirGenerateBl:
|
||||
if l.value != zBlank {
|
||||
|
|
@ -390,6 +375,10 @@ func parseZone(r io.Reader, origin, f string, t chan *Token, include int) {
|
|||
case zExpectAny:
|
||||
switch l.value {
|
||||
case zRrtpe:
|
||||
if defttl == nil {
|
||||
t <- &Token{Error: &ParseError{f, "missing TTL with no previous value", l}}
|
||||
return
|
||||
}
|
||||
h.Rrtype = l.torc
|
||||
st = zExpectRdata
|
||||
case zClass:
|
||||
|
|
@ -402,7 +391,9 @@ func parseZone(r io.Reader, origin, f string, t chan *Token, include int) {
|
|||
return
|
||||
}
|
||||
h.Ttl = ttl
|
||||
// defttl = ttl // don't set the defttl here
|
||||
if defttl == nil || !defttl.isByDirective {
|
||||
defttl = &ttlState{ttl, false}
|
||||
}
|
||||
st = zExpectAnyNoTtlBl
|
||||
default:
|
||||
t <- &Token{Error: &ParseError{f, "expecting RR type, TTL or class, not this...", l}}
|
||||
|
|
@ -441,7 +432,9 @@ func parseZone(r io.Reader, origin, f string, t chan *Token, include int) {
|
|||
return
|
||||
}
|
||||
h.Ttl = ttl
|
||||
// defttl = ttl // don't set the def ttl anymore
|
||||
if defttl == nil || !defttl.isByDirective {
|
||||
defttl = &ttlState{ttl, false}
|
||||
}
|
||||
st = zExpectRrtypeBl
|
||||
case zRrtpe:
|
||||
h.Rrtype = l.torc
|
||||
|
|
@ -918,6 +911,34 @@ func stringToCm(token string) (e, m uint8, ok bool) {
|
|||
return
|
||||
}
|
||||
|
||||
func toAbsoluteName(name, origin string) (absolute string, ok bool) {
|
||||
// check for an explicit origin reference
|
||||
if name == "@" {
|
||||
// require a nonempty origin
|
||||
if origin == "" {
|
||||
return "", false
|
||||
}
|
||||
return origin, true
|
||||
}
|
||||
|
||||
// require a valid domain name
|
||||
_, ok = IsDomainName(name)
|
||||
if !ok || name == "" {
|
||||
return "", false
|
||||
}
|
||||
|
||||
// check if name is already absolute
|
||||
if name[len(name)-1] == '.' {
|
||||
return name, true
|
||||
}
|
||||
|
||||
// require a nonempty origin
|
||||
if origin == "" {
|
||||
return "", false
|
||||
}
|
||||
return appendOrigin(name, origin), true
|
||||
}
|
||||
|
||||
func appendOrigin(name, origin string) string {
|
||||
if origin == "." {
|
||||
return name + origin
|
||||
|
|
|
|||
592
vendor/github.com/miekg/dns/scan_rr.go
generated
vendored
592
vendor/github.com/miekg/dns/scan_rr.go
generated
vendored
File diff suppressed because it is too large
Load diff
5
vendor/github.com/miekg/dns/scan_test.go
generated
vendored
5
vendor/github.com/miekg/dns/scan_test.go
generated
vendored
|
|
@ -21,13 +21,16 @@ func TestParseZoneInclude(t *testing.T) {
|
|||
t.Fatalf("could not close tmpfile %q: %s", tmpfile.Name(), err)
|
||||
}
|
||||
|
||||
zone := "$INCLUDE " + tmpfile.Name()
|
||||
zone := "$ORIGIN example.org.\n$INCLUDE " + tmpfile.Name()
|
||||
|
||||
tok := ParseZone(strings.NewReader(zone), "", "")
|
||||
for x := range tok {
|
||||
if x.Error != nil {
|
||||
t.Fatalf("expected no error, but got %s", x.Error)
|
||||
}
|
||||
if x.RR.Header().Name != "foo.example.org." {
|
||||
t.Fatalf("expected %s, but got %s", "foo.example.org.", x.RR.Header().Name)
|
||||
}
|
||||
}
|
||||
|
||||
os.Remove(tmpfile.Name())
|
||||
|
|
|
|||
10
vendor/github.com/miekg/dns/server_test.go
generated
vendored
10
vendor/github.com/miekg/dns/server_test.go
generated
vendored
|
|
@ -30,6 +30,16 @@ func HelloServerBadID(w ResponseWriter, req *Msg) {
|
|||
w.WriteMsg(m)
|
||||
}
|
||||
|
||||
func HelloServerEchoAddrPort(w ResponseWriter, req *Msg) {
|
||||
m := new(Msg)
|
||||
m.SetReply(req)
|
||||
|
||||
remoteAddr := w.RemoteAddr().String()
|
||||
m.Extra = make([]RR, 1)
|
||||
m.Extra[0] = &TXT{Hdr: RR_Header{Name: m.Question[0].Name, Rrtype: TypeTXT, Class: ClassINET, Ttl: 0}, Txt: []string{remoteAddr}}
|
||||
w.WriteMsg(m)
|
||||
}
|
||||
|
||||
func AnotherHelloServer(w ResponseWriter, req *Msg) {
|
||||
m := new(Msg)
|
||||
m.SetReply(req)
|
||||
|
|
|
|||
15
vendor/github.com/miekg/dns/udp.go
generated
vendored
15
vendor/github.com/miekg/dns/udp.go
generated
vendored
|
|
@ -27,8 +27,19 @@ func ReadFromSessionUDP(conn *net.UDPConn, b []byte) (int, *SessionUDP, error) {
|
|||
return n, &SessionUDP{raddr, oob[:oobn]}, err
|
||||
}
|
||||
|
||||
// WriteToSessionUDP acts just like net.UDPConn.WritetTo(), but uses a *SessionUDP instead of a net.Addr.
|
||||
// WriteToSessionUDP acts just like net.UDPConn.WriteTo(), but uses a *SessionUDP instead of a net.Addr.
|
||||
func WriteToSessionUDP(conn *net.UDPConn, b []byte, session *SessionUDP) (int, error) {
|
||||
n, _, err := conn.WriteMsgUDP(b, session.context, session.raddr)
|
||||
oob := correctSource(session.context)
|
||||
n, _, err := conn.WriteMsgUDP(b, oob, session.raddr)
|
||||
return n, err
|
||||
}
|
||||
|
||||
// correctSource takes oob data and returns new oob data with the Src equal to the Dst
|
||||
func correctSource(oob []byte) []byte {
|
||||
dst, err := parseUDPSocketDst(oob)
|
||||
// If the destination could not be determined, ignore.
|
||||
if err != nil || dst == nil {
|
||||
return nil
|
||||
}
|
||||
return marshalUDPSocketSrc(dst)
|
||||
}
|
||||
|
|
|
|||
115
vendor/github.com/miekg/dns/udp_linux.go
generated
vendored
115
vendor/github.com/miekg/dns/udp_linux.go
generated
vendored
|
|
@ -13,8 +13,34 @@ package dns
|
|||
import (
|
||||
"net"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
|
||||
"github.com/miekg/dns/internal/socket"
|
||||
)
|
||||
|
||||
const (
|
||||
sizeofInet6Pktinfo = 0x14
|
||||
sizeofInetPktinfo = 0xc
|
||||
protocolIP = 0
|
||||
protocolIPv6 = 41
|
||||
)
|
||||
|
||||
type inetPktinfo struct {
|
||||
Ifindex int32
|
||||
Spec_dst [4]byte /* in_addr */
|
||||
Addr [4]byte /* in_addr */
|
||||
}
|
||||
|
||||
type inet6Pktinfo struct {
|
||||
Addr [16]byte /* in6_addr */
|
||||
Ifindex int32
|
||||
}
|
||||
|
||||
type inetControlMessage struct {
|
||||
Src net.IP // source address, specifying only
|
||||
Dst net.IP // destination address, receiving only
|
||||
}
|
||||
|
||||
// setUDPSocketOptions sets the UDP socket options.
|
||||
// This function is implemented on a per platform basis. See udp_*.go for more details
|
||||
func setUDPSocketOptions(conn *net.UDPConn) error {
|
||||
|
|
@ -103,3 +129,92 @@ func getUDPSocketName(conn *net.UDPConn) (syscall.Sockaddr, error) {
|
|||
defer file.Close()
|
||||
return syscall.Getsockname(int(file.Fd()))
|
||||
}
|
||||
|
||||
// marshalInetPacketInfo marshals a ipv4 control message, returning
|
||||
// the byte slice for the next marshal, if any
|
||||
func marshalInetPacketInfo(b []byte, cm *inetControlMessage) []byte {
|
||||
m := socket.ControlMessage(b)
|
||||
m.MarshalHeader(protocolIP, syscall.IP_PKTINFO, sizeofInetPktinfo)
|
||||
if cm != nil {
|
||||
pi := (*inetPktinfo)(unsafe.Pointer(&m.Data(sizeofInetPktinfo)[0]))
|
||||
if ip := cm.Src.To4(); ip != nil {
|
||||
copy(pi.Spec_dst[:], ip)
|
||||
}
|
||||
}
|
||||
return m.Next(sizeofInetPktinfo)
|
||||
}
|
||||
|
||||
// marshalInet6PacketInfo marshals a ipv6 control message, returning
|
||||
// the byte slice for the next marshal, if any
|
||||
func marshalInet6PacketInfo(b []byte, cm *inetControlMessage) []byte {
|
||||
m := socket.ControlMessage(b)
|
||||
m.MarshalHeader(protocolIPv6, syscall.IPV6_PKTINFO, sizeofInet6Pktinfo)
|
||||
if cm != nil {
|
||||
pi := (*inet6Pktinfo)(unsafe.Pointer(&m.Data(sizeofInet6Pktinfo)[0]))
|
||||
if ip := cm.Src.To16(); ip != nil && ip.To4() == nil {
|
||||
copy(pi.Addr[:], ip)
|
||||
}
|
||||
}
|
||||
return m.Next(sizeofInet6Pktinfo)
|
||||
}
|
||||
|
||||
func parseInetPacketInfo(cm *inetControlMessage, b []byte) {
|
||||
pi := (*inetPktinfo)(unsafe.Pointer(&b[0]))
|
||||
if len(cm.Dst) < net.IPv4len {
|
||||
cm.Dst = make(net.IP, net.IPv4len)
|
||||
}
|
||||
copy(cm.Dst, pi.Addr[:])
|
||||
}
|
||||
|
||||
func parseInet6PacketInfo(cm *inetControlMessage, b []byte) {
|
||||
pi := (*inet6Pktinfo)(unsafe.Pointer(&b[0]))
|
||||
if len(cm.Dst) < net.IPv6len {
|
||||
cm.Dst = make(net.IP, net.IPv6len)
|
||||
}
|
||||
copy(cm.Dst, pi.Addr[:])
|
||||
}
|
||||
|
||||
// parseUDPSocketDst takes out-of-band data from ReadMsgUDP and parses it for
|
||||
// the Dst address
|
||||
func parseUDPSocketDst(oob []byte) (net.IP, error) {
|
||||
cm := new(inetControlMessage)
|
||||
ms, err := socket.ControlMessage(oob).Parse()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, m := range ms {
|
||||
lvl, typ, l, err := m.ParseHeader()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if lvl == protocolIPv6 { // IPv6
|
||||
if typ == syscall.IPV6_PKTINFO && l >= sizeofInet6Pktinfo {
|
||||
parseInet6PacketInfo(cm, m.Data(l))
|
||||
}
|
||||
} else if lvl == protocolIP { // IPv4
|
||||
if typ == syscall.IP_PKTINFO && l >= sizeofInetPktinfo {
|
||||
parseInetPacketInfo(cm, m.Data(l))
|
||||
}
|
||||
}
|
||||
}
|
||||
return cm.Dst, nil
|
||||
}
|
||||
|
||||
// marshalUDPSocketSrc takes the given src address and returns out-of-band data
|
||||
// to give to WriteMsgUDP
|
||||
func marshalUDPSocketSrc(src net.IP) []byte {
|
||||
var oob []byte
|
||||
// If the dst is definitely an ipv6, then use ipv6 control to respond
|
||||
// otherwise use ipv4 because the ipv6 marshal ignores ipv4 messages.
|
||||
// See marshalInet6PacketInfo
|
||||
cm := new(inetControlMessage)
|
||||
cm.Src = src
|
||||
if src.To4() == nil {
|
||||
oob = make([]byte, socket.ControlMessageSpace(sizeofInet6Pktinfo))
|
||||
marshalInet6PacketInfo(oob, cm)
|
||||
} else {
|
||||
oob = make([]byte, socket.ControlMessageSpace(sizeofInetPktinfo))
|
||||
marshalInetPacketInfo(oob, cm)
|
||||
}
|
||||
return oob
|
||||
}
|
||||
|
|
|
|||
68
vendor/github.com/miekg/dns/udp_linux_test.go
generated
vendored
Normal file
68
vendor/github.com/miekg/dns/udp_linux_test.go
generated
vendored
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
// +build linux,!appengine
|
||||
|
||||
package dns
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"net"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestParseUDPSocketDst(t *testing.T) {
|
||||
// dst is :ffff:100.100.100.100
|
||||
oob := []byte{36, 0, 0, 0, 0, 0, 0, 0, 41, 0, 0, 0, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 100, 100, 100, 100, 2, 0, 0, 0}
|
||||
dst, err := parseUDPSocketDst(oob)
|
||||
if err != nil {
|
||||
t.Fatalf("error parsing ipv6 oob: %v", err)
|
||||
}
|
||||
dst4 := dst.To4()
|
||||
if dst4 == nil {
|
||||
t.Errorf("failed to parse ipv4: %v", dst)
|
||||
} else if dst4.String() != "100.100.100.100" {
|
||||
t.Errorf("unexpected ipv4: %v", dst4)
|
||||
}
|
||||
|
||||
// dst is 2001:db8::1
|
||||
oob = []byte{36, 0, 0, 0, 0, 0, 0, 0, 41, 0, 0, 0, 50, 0, 0, 0, 32, 1, 13, 184, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0}
|
||||
dst, err = parseUDPSocketDst(oob)
|
||||
if err != nil {
|
||||
t.Fatalf("error parsing ipv6 oob: %v", err)
|
||||
}
|
||||
dst6 := dst.To16()
|
||||
if dst6 == nil {
|
||||
t.Errorf("failed to parse ipv6: %v", dst)
|
||||
} else if dst6.String() != "2001:db8::1" {
|
||||
t.Errorf("unexpected ipv6: %v", dst4)
|
||||
}
|
||||
|
||||
// dst is 100.100.100.100 but was received on 10.10.10.10
|
||||
oob = []byte{28, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 2, 0, 0, 0, 10, 10, 10, 10, 100, 100, 100, 100, 0, 0, 0, 0}
|
||||
dst, err = parseUDPSocketDst(oob)
|
||||
if err != nil {
|
||||
t.Fatalf("error parsing ipv4 oob: %v", err)
|
||||
}
|
||||
dst4 = dst.To4()
|
||||
if dst4 == nil {
|
||||
t.Errorf("failed to parse ipv4: %v", dst)
|
||||
} else if dst4.String() != "100.100.100.100" {
|
||||
t.Errorf("unexpected ipv4: %v", dst4)
|
||||
}
|
||||
}
|
||||
|
||||
func TestMarshalUDPSocketSrc(t *testing.T) {
|
||||
// src is 100.100.100.100
|
||||
exoob := []byte{28, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 100, 100, 100, 100, 0, 0, 0, 0, 0, 0, 0, 0}
|
||||
oob := marshalUDPSocketSrc(net.ParseIP("100.100.100.100"))
|
||||
if !bytes.Equal(exoob, oob) {
|
||||
t.Errorf("expected ipv4 oob:\n%v", exoob)
|
||||
t.Errorf("actual ipv4 oob:\n%v", oob)
|
||||
}
|
||||
|
||||
// src is 2001:db8::1
|
||||
exoob = []byte{36, 0, 0, 0, 0, 0, 0, 0, 41, 0, 0, 0, 50, 0, 0, 0, 32, 1, 13, 184, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0}
|
||||
oob = marshalUDPSocketSrc(net.ParseIP("2001:db8::1"))
|
||||
if !bytes.Equal(exoob, oob) {
|
||||
t.Errorf("expected ipv6 oob:\n%v", exoob)
|
||||
t.Errorf("actual ipv6 oob:\n%v", oob)
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue