mirror of
https://github.com/bettercap/bettercap
synced 2025-07-14 00:53:46 -07:00
misc: replaced glide with go dep
This commit is contained in:
parent
a2e90769fe
commit
6b6078d30d
533 changed files with 298 additions and 128052 deletions
200
Gopkg.lock
generated
Normal file
200
Gopkg.lock
generated
Normal file
|
@ -0,0 +1,200 @@
|
|||
# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'.
|
||||
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/adrianmo/go-nmea"
|
||||
packages = ["."]
|
||||
revision = "22095aa1b48050243d3eb9a001ca80eb91a0c6fa"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/bettercap/gatt"
|
||||
packages = [
|
||||
".",
|
||||
"linux",
|
||||
"linux/cmd",
|
||||
"linux/evt",
|
||||
"linux/gioctl",
|
||||
"linux/socket",
|
||||
"linux/util",
|
||||
"xpc"
|
||||
]
|
||||
revision = "e65eb2df9116e5ec6e2409b6142a09a93e96b900"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/bettercap/readline"
|
||||
packages = ["."]
|
||||
revision = "62c6fe6193755f722b8b8788aa7357be55a50ff1"
|
||||
version = "v1.4"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/chifflier/nfqueue-go"
|
||||
packages = ["nfqueue"]
|
||||
revision = "61ca646babef3bd4dea1deb610bfb0005c0a1298"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/dustin/go-humanize"
|
||||
packages = ["."]
|
||||
revision = "bb3d318650d48840a39aa21a027c6630e198e626"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/elazarl/goproxy"
|
||||
packages = ["."]
|
||||
revision = "a96fa3a318260eab29abaf32f7128c9eb07fb073"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/gobwas/glob"
|
||||
packages = [
|
||||
".",
|
||||
"compiler",
|
||||
"match",
|
||||
"syntax",
|
||||
"syntax/ast",
|
||||
"syntax/lexer",
|
||||
"util/runes",
|
||||
"util/strings"
|
||||
]
|
||||
revision = "f00a7392b43971b2fdb562418faab1f18da2067a"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/google/go-github"
|
||||
packages = ["github"]
|
||||
revision = "e48060a28fac52d0f1cb758bc8b87c07bac4a87d"
|
||||
version = "v15.0.0"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/google/go-querystring"
|
||||
packages = ["query"]
|
||||
revision = "53e6ce116135b80d037921a7fdd5138cf32d7a8a"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/google/gopacket"
|
||||
packages = [
|
||||
".",
|
||||
"layers",
|
||||
"pcap",
|
||||
"pcapgo"
|
||||
]
|
||||
revision = "11c65f1ca9081dfea43b4f9643f5c155583b73ba"
|
||||
version = "v1.1.14"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/gorilla/context"
|
||||
packages = ["."]
|
||||
revision = "08b5f424b9271eedf6f9f0ce86cb9396ed337a42"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/gorilla/mux"
|
||||
packages = ["."]
|
||||
revision = "53c1911da2b537f792e7cafcb446b05ffe33b996"
|
||||
version = "v1.6.1"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/gorilla/websocket"
|
||||
packages = ["."]
|
||||
revision = "ea4d1f681babbce9545c9c5f3d5194a789c89f5b"
|
||||
version = "v1.2.0"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/inconshreveable/go-vhost"
|
||||
packages = ["."]
|
||||
revision = "06d84117953b22058c096b49a429ebd4f3d3d97b"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/jpillora/go-tld"
|
||||
packages = ["."]
|
||||
revision = "a31ae10e978ab5f352c5dad2cfbd60546dcea75f"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/malfunkt/iprange"
|
||||
packages = ["."]
|
||||
revision = "3a31f5ed42d2d8a1fc46f1be91fd693bdef2dd52"
|
||||
version = "v0.9.0"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/mattn/go-colorable"
|
||||
packages = ["."]
|
||||
revision = "5411d3eea5978e6cdc258b30de592b60df6aba96"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/mattn/go-isatty"
|
||||
packages = ["."]
|
||||
revision = "0360b2af4f38e8d38c7fce2a9f4e702702d73a39"
|
||||
version = "v0.0.3"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/mdlayher/dhcp6"
|
||||
packages = [
|
||||
".",
|
||||
"dhcp6opts",
|
||||
"internal/buffer"
|
||||
]
|
||||
revision = "e26af0688e455a82b14ebdbecf43f87ead3c4624"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/mgutz/ansi"
|
||||
packages = ["."]
|
||||
revision = "9520e82c474b0a04dd04f8a40959027271bab992"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/mgutz/logxi"
|
||||
packages = ["v1"]
|
||||
revision = "aebf8a7d67ab4625e0fd4a665766fef9a709161b"
|
||||
version = "v1"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/pkg/errors"
|
||||
packages = ["."]
|
||||
revision = "816c9085562cd7ee03e7f8188a1cfd942858cded"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/robertkrimen/otto"
|
||||
packages = [
|
||||
".",
|
||||
"ast",
|
||||
"dbg",
|
||||
"file",
|
||||
"parser",
|
||||
"registry",
|
||||
"token"
|
||||
]
|
||||
revision = "6c383dd335ef8dcccef05e651ce1eccfe4d0f011"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/tarm/serial"
|
||||
packages = ["."]
|
||||
revision = "eaafced92e9619f03c72527efeab21e326f3bc36"
|
||||
|
||||
[[projects]]
|
||||
name = "golang.org/x/sys"
|
||||
packages = ["unix"]
|
||||
revision = "abf9c25f54453410d0c6668e519582a9e1115027"
|
||||
|
||||
[[projects]]
|
||||
name = "gopkg.in/sourcemap.v1"
|
||||
packages = [
|
||||
".",
|
||||
"base64vlq"
|
||||
]
|
||||
revision = "6e83acea0053641eff084973fee085f0c193c61a"
|
||||
version = "v1.0.5"
|
||||
|
||||
[solve-meta]
|
||||
analyzer-name = "dep"
|
||||
analyzer-version = 1
|
||||
inputs-digest = "16887d6924226ea7174b18c0c2a92da30997904da44648f7df6927b3ec8e8de1"
|
||||
solver-name = "gps-cdcl"
|
||||
solver-version = 1
|
98
Gopkg.toml
Normal file
98
Gopkg.toml
Normal file
|
@ -0,0 +1,98 @@
|
|||
# Gopkg.toml example
|
||||
#
|
||||
# Refer to https://golang.github.io/dep/docs/Gopkg.toml.html
|
||||
# for detailed Gopkg.toml documentation.
|
||||
#
|
||||
# required = ["github.com/user/thing/cmd/thing"]
|
||||
# ignored = ["github.com/user/project/pkgX", "bitbucket.org/user/project/pkgA/pkgY"]
|
||||
#
|
||||
# [[constraint]]
|
||||
# name = "github.com/user/project"
|
||||
# version = "1.0.0"
|
||||
#
|
||||
# [[constraint]]
|
||||
# name = "github.com/user/project2"
|
||||
# branch = "dev"
|
||||
# source = "github.com/myfork/project2"
|
||||
#
|
||||
# [[override]]
|
||||
# name = "github.com/x/y"
|
||||
# version = "2.4.0"
|
||||
#
|
||||
# [prune]
|
||||
# non-go = false
|
||||
# go-tests = true
|
||||
# unused-packages = true
|
||||
|
||||
|
||||
[[constraint]]
|
||||
branch = "master"
|
||||
name = "github.com/bettercap/gatt"
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/bettercap/readline"
|
||||
version = "1.4.0"
|
||||
|
||||
[[constraint]]
|
||||
branch = "master"
|
||||
name = "github.com/chifflier/nfqueue-go"
|
||||
|
||||
[[constraint]]
|
||||
branch = "master"
|
||||
name = "github.com/dustin/go-humanize"
|
||||
|
||||
[[constraint]]
|
||||
branch = "master"
|
||||
name = "github.com/elazarl/goproxy"
|
||||
|
||||
[[constraint]]
|
||||
branch = "master"
|
||||
name = "github.com/gobwas/glob"
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/google/go-github"
|
||||
version = "15.0.0"
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/google/gopacket"
|
||||
version = "1.1.14"
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/gorilla/mux"
|
||||
version = "1.6.1"
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/gorilla/websocket"
|
||||
version = "1.2.0"
|
||||
|
||||
[[constraint]]
|
||||
branch = "master"
|
||||
name = "github.com/inconshreveable/go-vhost"
|
||||
|
||||
[[constraint]]
|
||||
branch = "master"
|
||||
name = "github.com/jpillora/go-tld"
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/malfunkt/iprange"
|
||||
version = "0.9.0"
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/mattn/go-isatty"
|
||||
version = "0.0.3"
|
||||
|
||||
[[constraint]]
|
||||
branch = "master"
|
||||
name = "github.com/mdlayher/dhcp6"
|
||||
|
||||
[[constraint]]
|
||||
branch = "master"
|
||||
name = "github.com/robertkrimen/otto"
|
||||
|
||||
[[constraint]]
|
||||
branch = "master"
|
||||
name = "github.com/tarm/serial"
|
||||
|
||||
[prune]
|
||||
go-tests = true
|
||||
unused-packages = true
|
101
glide.lock
generated
101
glide.lock
generated
|
@ -1,101 +0,0 @@
|
|||
hash: 8c75fb42328bdf49846d94b20ffdca1271647dac675a481d9e2c090c2fcadf95
|
||||
updated: 2018-04-17T18:24:27.044155505+02:00
|
||||
imports:
|
||||
- name: github.com/adrianmo/go-nmea
|
||||
version: 22095aa1b48050243d3eb9a001ca80eb91a0c6fa
|
||||
vcs: git
|
||||
- name: github.com/bettercap/gatt
|
||||
version: e65eb2df9116e5ec6e2409b6142a09a93e96b900
|
||||
vcs: git
|
||||
subpackages:
|
||||
- linux
|
||||
- linux/cmd
|
||||
- linux/evt
|
||||
- linux/gioctl
|
||||
- linux/socket
|
||||
- linux/util
|
||||
- xpc
|
||||
- name: github.com/bettercap/readline
|
||||
version: 62c6fe6193755f722b8b8788aa7357be55a50ff1
|
||||
- name: github.com/chifflier/nfqueue-go
|
||||
version: 61ca646babef3bd4dea1deb610bfb0005c0a1298
|
||||
subpackages:
|
||||
- nfqueue
|
||||
- name: github.com/dustin/go-humanize
|
||||
version: bb3d318650d48840a39aa21a027c6630e198e626
|
||||
- name: github.com/elazarl/goproxy
|
||||
version: a96fa3a318260eab29abaf32f7128c9eb07fb073
|
||||
vcs: git
|
||||
- name: github.com/gobwas/glob
|
||||
version: f00a7392b43971b2fdb562418faab1f18da2067a
|
||||
subpackages:
|
||||
- compiler
|
||||
- match
|
||||
- syntax
|
||||
- syntax/ast
|
||||
- syntax/lexer
|
||||
- util/runes
|
||||
- util/strings
|
||||
- name: github.com/google/go-github
|
||||
version: e48060a28fac52d0f1cb758bc8b87c07bac4a87d
|
||||
subpackages:
|
||||
- github
|
||||
- name: github.com/google/go-querystring
|
||||
version: 53e6ce116135b80d037921a7fdd5138cf32d7a8a
|
||||
subpackages:
|
||||
- query
|
||||
- name: github.com/google/gopacket
|
||||
version: 11c65f1ca9081dfea43b4f9643f5c155583b73ba
|
||||
subpackages:
|
||||
- layers
|
||||
- pcap
|
||||
- pcapgo
|
||||
- name: github.com/gorilla/context
|
||||
version: 08b5f424b9271eedf6f9f0ce86cb9396ed337a42
|
||||
- name: github.com/gorilla/mux
|
||||
version: 53c1911da2b537f792e7cafcb446b05ffe33b996
|
||||
- name: github.com/gorilla/websocket
|
||||
version: ea4d1f681babbce9545c9c5f3d5194a789c89f5b
|
||||
- name: github.com/inconshreveable/go-vhost
|
||||
version: 06d84117953b22058c096b49a429ebd4f3d3d97b
|
||||
- name: github.com/jpillora/go-tld
|
||||
version: a31ae10e978ab5f352c5dad2cfbd60546dcea75f
|
||||
- name: github.com/malfunkt/iprange
|
||||
version: 3a31f5ed42d2d8a1fc46f1be91fd693bdef2dd52
|
||||
- name: github.com/mattn/go-colorable
|
||||
version: 5411d3eea5978e6cdc258b30de592b60df6aba96
|
||||
- name: github.com/mattn/go-isatty
|
||||
version: 0360b2af4f38e8d38c7fce2a9f4e702702d73a39
|
||||
- name: github.com/mdlayher/dhcp6
|
||||
version: e26af0688e455a82b14ebdbecf43f87ead3c4624
|
||||
subpackages:
|
||||
- dhcp6opts
|
||||
- internal/buffer
|
||||
- name: github.com/mgutz/ansi
|
||||
version: 9520e82c474b0a04dd04f8a40959027271bab992
|
||||
- name: github.com/mgutz/logxi
|
||||
version: aebf8a7d67ab4625e0fd4a665766fef9a709161b
|
||||
subpackages:
|
||||
- v1
|
||||
- name: github.com/pkg/errors
|
||||
version: 816c9085562cd7ee03e7f8188a1cfd942858cded
|
||||
- name: github.com/robertkrimen/otto
|
||||
version: 6c383dd335ef8dcccef05e651ce1eccfe4d0f011
|
||||
subpackages:
|
||||
- ast
|
||||
- dbg
|
||||
- file
|
||||
- parser
|
||||
- registry
|
||||
- token
|
||||
- name: github.com/tarm/serial
|
||||
version: eaafced92e9619f03c72527efeab21e326f3bc36
|
||||
- name: golang.org/x/sys
|
||||
version: abf9c25f54453410d0c6668e519582a9e1115027
|
||||
subpackages:
|
||||
- unix
|
||||
- name: gopkg.in/sourcemap.v1
|
||||
version: 6e83acea0053641eff084973fee085f0c193c61a
|
||||
subpackages:
|
||||
- base64vlq
|
||||
testImports: []
|
41
glide.yaml
41
glide.yaml
|
@ -1,41 +0,0 @@
|
|||
package: github.com/bettercap/bettercap
|
||||
import:
|
||||
- package: github.com/adrianmo/go-nmea
|
||||
vcs: git
|
||||
version: 22095aa1b48050243d3eb9a001ca80eb91a0c6fa
|
||||
- package: github.com/bettercap/gatt
|
||||
vcs: git
|
||||
version: e65eb2df9116e5ec6e2409b6142a09a93e96b900
|
||||
subpackages:
|
||||
- linux/cmd
|
||||
- package: github.com/bettercap/readline
|
||||
version: ^1.4.0
|
||||
- package: github.com/dustin/go-humanize
|
||||
- package: github.com/elazarl/goproxy
|
||||
vcs: git
|
||||
version: a96fa3a318260eab29abaf32f7128c9eb07fb073
|
||||
- package: github.com/google/go-github
|
||||
version: ^15.0.0
|
||||
subpackages:
|
||||
- github
|
||||
- package: github.com/google/gopacket
|
||||
version: ^1.1.14
|
||||
subpackages:
|
||||
- layers
|
||||
- pcap
|
||||
- pcapgo
|
||||
- package: github.com/gorilla/mux
|
||||
version: ^1.6.1
|
||||
- package: github.com/gorilla/websocket
|
||||
version: ^1.2.0
|
||||
- package: github.com/inconshreveable/go-vhost
|
||||
- package: github.com/jpillora/go-tld
|
||||
- package: github.com/malfunkt/iprange
|
||||
version: ^0.9.0
|
||||
- package: github.com/mattn/go-isatty
|
||||
version: ^0.0.3
|
||||
- package: github.com/mdlayher/dhcp6
|
||||
subpackages:
|
||||
- dhcp6opts
|
||||
- package: github.com/robertkrimen/otto
|
||||
- package: github.com/tarm/serial
|
96
vendor/github.com/adrianmo/go-nmea/glgsv_test.go
generated
vendored
96
vendor/github.com/adrianmo/go-nmea/glgsv_test.go
generated
vendored
|
@ -1,96 +0,0 @@
|
|||
package nmea
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestGLGSVGoodSentence(t *testing.T) {
|
||||
goodMsg := "$GLGSV,3,1,11,03,03,111,00,04,15,270,00,06,01,010,12,13,06,292,00*6B"
|
||||
s, err := Parse(goodMsg)
|
||||
|
||||
assert.NoError(t, err, "Unexpected error parsing good sentence")
|
||||
assert.Equal(t, PrefixGLGSV, s.Prefix(), "Prefix does not match")
|
||||
|
||||
sentence := s.(GLGSV)
|
||||
assert.Equal(t, int64(3), sentence.TotalMessages, "Total messages does not match")
|
||||
assert.Equal(t, int64(1), sentence.MessageNumber, "Message number does not match")
|
||||
assert.Equal(t, int64(11), sentence.NumberSVsInView, "Number of SVs in view does not match")
|
||||
|
||||
assert.Equal(t, int64(3), sentence.Info[0].SVPRNNumber, "Number of Info[0] SV PRN does not match")
|
||||
assert.Equal(t, int64(3), sentence.Info[0].Elevation, "Number of Info[0] Elevation does not match")
|
||||
assert.Equal(t, int64(111), sentence.Info[0].Azimuth, "Number of Info[0] Azimuth does not match")
|
||||
assert.Equal(t, int64(0), sentence.Info[0].SNR, "Number of Info[0] SNR does not match")
|
||||
|
||||
assert.Equal(t, int64(4), sentence.Info[1].SVPRNNumber, "Number of Info[1] SV PRN does not match")
|
||||
assert.Equal(t, int64(15), sentence.Info[1].Elevation, "Number of Info[1] Elevation does not match")
|
||||
assert.Equal(t, int64(270), sentence.Info[1].Azimuth, "Number of Info[1] Azimuth does not match")
|
||||
assert.Equal(t, int64(0), sentence.Info[1].SNR, "Number of Info[1] SNR does not match")
|
||||
|
||||
assert.Equal(t, int64(6), sentence.Info[2].SVPRNNumber, "Number of Info[2] SV PRN does not match")
|
||||
assert.Equal(t, int64(1), sentence.Info[2].Elevation, "Number of Info[2] Elevation does not match")
|
||||
assert.Equal(t, int64(10), sentence.Info[2].Azimuth, "Number of Info[2] Azimuth does not match")
|
||||
assert.Equal(t, int64(12), sentence.Info[2].SNR, "Number of Info[2] SNR does not match")
|
||||
|
||||
assert.Equal(t, int64(13), sentence.Info[3].SVPRNNumber, "Number of Info[3] SV PRN does not match")
|
||||
assert.Equal(t, int64(6), sentence.Info[3].Elevation, "Number of Info[3] Elevation does not match")
|
||||
assert.Equal(t, int64(292), sentence.Info[3].Azimuth, "Number of Info[3] Azimuth does not match")
|
||||
assert.Equal(t, int64(0), sentence.Info[3].SNR, "Number of Info[3] SNR does not match")
|
||||
}
|
||||
|
||||
func TestGLGSVShort(t *testing.T) {
|
||||
goodMsg := "$GLGSV,3,1,11,03,03,111,00,04,15,270,00,06,01,010,12*56"
|
||||
s, err := Parse(goodMsg)
|
||||
|
||||
assert.NoError(t, err, "Unexpected error parsing good sentence")
|
||||
assert.Equal(t, PrefixGLGSV, s.Prefix(), "Prefix does not match")
|
||||
|
||||
sentence := s.(GLGSV)
|
||||
assert.Equal(t, int64(3), sentence.TotalMessages, "Total messages does not match")
|
||||
assert.Equal(t, int64(1), sentence.MessageNumber, "Message number does not match")
|
||||
assert.Equal(t, int64(11), sentence.NumberSVsInView, "Number of SVs in view does not match")
|
||||
|
||||
assert.Equal(t, int64(3), sentence.Info[0].SVPRNNumber, "Number of Info[0] SV PRN does not match")
|
||||
assert.Equal(t, int64(3), sentence.Info[0].Elevation, "Number of Info[0] Elevation does not match")
|
||||
assert.Equal(t, int64(111), sentence.Info[0].Azimuth, "Number of Info[0] Azimuth does not match")
|
||||
assert.Equal(t, int64(0), sentence.Info[0].SNR, "Number of Info[0] SNR does not match")
|
||||
|
||||
assert.Equal(t, int64(4), sentence.Info[1].SVPRNNumber, "Number of Info[1] SV PRN does not match")
|
||||
assert.Equal(t, int64(15), sentence.Info[1].Elevation, "Number of Info[1] Elevation does not match")
|
||||
assert.Equal(t, int64(270), sentence.Info[1].Azimuth, "Number of Info[1] Azimuth does not match")
|
||||
assert.Equal(t, int64(0), sentence.Info[1].SNR, "Number of Info[1] SNR does not match")
|
||||
|
||||
assert.Equal(t, int64(6), sentence.Info[2].SVPRNNumber, "Number of Info[2] SV PRN does not match")
|
||||
assert.Equal(t, int64(1), sentence.Info[2].Elevation, "Number of Info[2] Elevation does not match")
|
||||
assert.Equal(t, int64(10), sentence.Info[2].Azimuth, "Number of Info[2] Azimuth does not match")
|
||||
assert.Equal(t, int64(12), sentence.Info[2].SNR, "Number of Info[2] SNR does not match")
|
||||
}
|
||||
func TestGLGSVBadSentence(t *testing.T) {
|
||||
tests := []struct {
|
||||
Input string
|
||||
Error string
|
||||
}{
|
||||
{"$GLGSV,3,1,11.2,03,03,111,00,04,15,270,00,06,01,010,12,13,06,292,00*77", "nmea: GLGSV invalid number of SVs in view: 11.2"},
|
||||
{"$GLGSV,A3,1,11,03,03,111,00,04,15,270,00,06,01,010,12,13,06,292,00*2A", "nmea: GLGSV invalid total number of messages: A3"},
|
||||
{"$GLGSV,3,A1,11,03,03,111,00,04,15,270,00,06,01,010,12,13,06,292,00*2A", "nmea: GLGSV invalid message number: A1"},
|
||||
{"$GLGSV,3,1,11,A03,03,111,00,04,15,270,00,06,01,010,12,13,06,292,00*2A", "nmea: GLGSV invalid SV prn number: A03"},
|
||||
{"$GLGSV,3,1,11,03,A03,111,00,04,15,270,00,06,01,010,12,13,06,292,00*2A", "nmea: GLGSV invalid elevation: A03"},
|
||||
{"$GLGSV,3,1,11,03,03,A111,00,04,15,270,00,06,01,010,12,13,06,292,00*2A", "nmea: GLGSV invalid azimuth: A111"},
|
||||
{"$GLGSV,3,1,11,03,03,111,A00,04,15,270,00,06,01,010,12,13,06,292,00*2A", "nmea: GLGSV invalid SNR: A00"},
|
||||
}
|
||||
for _, tc := range tests {
|
||||
_, err := Parse(tc.Input)
|
||||
assert.Error(t, err, "Parse error not returned")
|
||||
assert.Equal(t, tc.Error, err.Error(), "Incorrect error message")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestGLGSVWrongSentence(t *testing.T) {
|
||||
wrongMsg := "$GPXTE,A,A,4.07,L,N*6D"
|
||||
sent, _ := ParseSentence(wrongMsg)
|
||||
_, err := NewGLGSV(sent)
|
||||
assert.Error(t, err, "Parse error not returned")
|
||||
assert.Equal(t, "nmea: GLGSV invalid prefix: GPXTE", err.Error(), "Incorrect error message")
|
||||
}
|
71
vendor/github.com/adrianmo/go-nmea/gngga_test.go
generated
vendored
71
vendor/github.com/adrianmo/go-nmea/gngga_test.go
generated
vendored
|
@ -1,71 +0,0 @@
|
|||
package nmea
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestGNGGAGoodSentence(t *testing.T) {
|
||||
goodMsg := "$GNGGA,203415.000,6325.6138,N,01021.4290,E,1,8,2.42,72.5,M,41.5,M,,*7C"
|
||||
sentence, err := Parse(goodMsg)
|
||||
|
||||
assert.NoError(t, err, "Unexpected error parsing good sentence")
|
||||
|
||||
lat, _ := ParseLatLong("6325.6138 N")
|
||||
lon, _ := ParseLatLong("01021.4290 E")
|
||||
// Attributes of the parsed sentence, and their expected values.
|
||||
expected := GNGGA{
|
||||
Sent: Sent{
|
||||
Type: "GNGGA",
|
||||
Fields: []string{"203415.000", "6325.6138", "N", "01021.4290", "E", "1", "8", "2.42", "72.5", "M", "41.5", "M", "", ""},
|
||||
Checksum: "7C",
|
||||
Raw: "$GNGGA,203415.000,6325.6138,N,01021.4290,E,1,8,2.42,72.5,M,41.5,M,,*7C",
|
||||
},
|
||||
Time: Time{true, 20, 34, 15, 0},
|
||||
Latitude: lat,
|
||||
Longitude: lon,
|
||||
FixQuality: GPS,
|
||||
NumSatellites: 8,
|
||||
HDOP: 2.42,
|
||||
Altitude: 72.5,
|
||||
Separation: 41.5,
|
||||
DGPSAge: "",
|
||||
DGPSId: "",
|
||||
}
|
||||
|
||||
assert.EqualValues(t, expected, sentence, "Sentence values do not match")
|
||||
}
|
||||
|
||||
func TestGNGGABadType(t *testing.T) {
|
||||
badType := "$GPRMC,220516,A,5133.82,N,00042.24,W,173.8,231.8,130694,004.2,W*70"
|
||||
s, err := Parse(badType)
|
||||
|
||||
assert.NoError(t, err, "Unexpected error parsing sentence")
|
||||
assert.NotEqual(t, "GNGGA", s.Prefix(), "Unexpected sentence type")
|
||||
}
|
||||
|
||||
func TestGNGGABadLatitude(t *testing.T) {
|
||||
badLat := "$GNGGA,034225.077,A,S,15124.5567,E,1,03,9.7,-25.0,M,21.0,M,,0000*24"
|
||||
_, err := Parse(badLat)
|
||||
|
||||
assert.Error(t, err, "Parse error not returned")
|
||||
assert.Equal(t, "nmea: GNGGA invalid latitude: cannot parse [A S], unknown format", err.Error(), "Error message does not match")
|
||||
}
|
||||
|
||||
func TestGNGGABadLongitude(t *testing.T) {
|
||||
badLon := "$GNGGA,034225.077,3356.4650,S,A,E,1,03,9.7,-25.0,M,21.0,M,,0000*12"
|
||||
_, err := Parse(badLon)
|
||||
|
||||
assert.Error(t, err, "Parse error not returned")
|
||||
assert.Equal(t, "nmea: GNGGA invalid longitude: cannot parse [A E], unknown format", err.Error(), "Error message does not match")
|
||||
}
|
||||
|
||||
func TestGNGGABadFixQuality(t *testing.T) {
|
||||
// Make sure bad fix mode is detected.
|
||||
badMode := "$GNGGA,034225.077,3356.4650,S,15124.5567,E,5,03,9.7,-25.0,M,21.0,M,,0000*4B"
|
||||
_, err := Parse(badMode)
|
||||
|
||||
assert.Error(t, err, "Parse error not returned")
|
||||
assert.Equal(t, err.Error(), "nmea: GNGGA invalid fix quality: 5", "Error message not as expected")
|
||||
}
|
78
vendor/github.com/adrianmo/go-nmea/gnrmc_test.go
generated
vendored
78
vendor/github.com/adrianmo/go-nmea/gnrmc_test.go
generated
vendored
|
@ -1,78 +0,0 @@
|
|||
package nmea
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
var gnrmctests = []struct {
|
||||
Input string
|
||||
Output GNRMC
|
||||
}{
|
||||
{
|
||||
"$GNRMC,220516,A,5133.82,N,00042.24,W,173.8,231.8,130694,004.2,W*6E",
|
||||
GNRMC{
|
||||
Time: Time{true, 22, 05, 16, 0},
|
||||
Validity: "A",
|
||||
Speed: 173.8,
|
||||
Course: 231.8,
|
||||
Date: Date{true, 13, 06, 94},
|
||||
Variation: -4.2,
|
||||
Latitude: MustParseGPS("5133.82 N"),
|
||||
Longitude: MustParseGPS("00042.24 W"),
|
||||
},
|
||||
},
|
||||
{
|
||||
"$GNRMC,142754.0,A,4302.539570,N,07920.379823,W,0.0,,070617,0.0,E,A*21",
|
||||
GNRMC{
|
||||
Time: Time{true, 14, 27, 54, 0},
|
||||
Validity: "A",
|
||||
Speed: 0,
|
||||
Course: 0,
|
||||
Date: Date{true, 7, 6, 17},
|
||||
Variation: 0,
|
||||
Latitude: MustParseGPS("4302.539570 N"),
|
||||
Longitude: MustParseGPS("07920.379823 W"),
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
func TestGNRMCGoodSentence(t *testing.T) {
|
||||
|
||||
for _, tt := range gnrmctests {
|
||||
|
||||
s, err := Parse(tt.Input)
|
||||
|
||||
assert.NoError(t, err, "Unexpected error parsing good sentence")
|
||||
assert.Equal(t, PrefixGNRMC, s.Prefix(), "Prefix does not match")
|
||||
|
||||
sentence := s.(GNRMC)
|
||||
|
||||
assert.Equal(t, tt.Output.Time, sentence.Time, "Time does not match")
|
||||
assert.Equal(t, tt.Output.Validity, sentence.Validity, "Status does not match")
|
||||
assert.Equal(t, tt.Output.Speed, sentence.Speed, "Speed does not match")
|
||||
assert.Equal(t, tt.Output.Course, sentence.Course, "Course does not match")
|
||||
assert.Equal(t, tt.Output.Date, sentence.Date, "Date does not match")
|
||||
assert.Equal(t, tt.Output.Variation, sentence.Variation, "Variation does not match")
|
||||
assert.Equal(t, tt.Output.Latitude, sentence.Latitude, "Latitude does not match")
|
||||
assert.Equal(t, tt.Output.Longitude, sentence.Longitude, "Longitude does not match")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestGNRMCBadSentence(t *testing.T) {
|
||||
badMsg := "$GNRMC,220516,D,5133.82,N,00042.24,W,173.8,231.8,130694,004.2,W*6B"
|
||||
_, err := Parse(badMsg)
|
||||
|
||||
assert.Error(t, err, "Parse error not returned")
|
||||
assert.Equal(t, "nmea: GNRMC invalid validity: D", err.Error(), "Incorrect error message")
|
||||
}
|
||||
|
||||
func TestGNRMCWrongSentence(t *testing.T) {
|
||||
wrongMsg := "$GPXTE,A,A,4.07,L,N*6D"
|
||||
_, err := Parse(wrongMsg)
|
||||
|
||||
assert.Error(t, err, "Parse error not returned")
|
||||
assert.Equal(t, "nmea: sentence type 'GPXTE' not implemented", err.Error(), "Incorrect error message")
|
||||
}
|
71
vendor/github.com/adrianmo/go-nmea/gpgga_test.go
generated
vendored
71
vendor/github.com/adrianmo/go-nmea/gpgga_test.go
generated
vendored
|
@ -1,71 +0,0 @@
|
|||
package nmea
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestGPGGAGoodSentence(t *testing.T) {
|
||||
goodMsg := "$GPGGA,034225.077,3356.4650,S,15124.5567,E,1,03,9.7,-25.0,M,21.0,M,,0000*51"
|
||||
sentence, err := Parse(goodMsg)
|
||||
|
||||
assert.NoError(t, err, "Unexpected error parsing good sentence")
|
||||
|
||||
lat, _ := ParseLatLong("3356.4650 S")
|
||||
lon, _ := ParseLatLong("15124.5567 E")
|
||||
// Attributes of the parsed sentence, and their expected values.
|
||||
expected := GPGGA{
|
||||
Sent: Sent{
|
||||
Type: "GPGGA",
|
||||
Fields: []string{"034225.077", "3356.4650", "S", "15124.5567", "E", "1", "03", "9.7", "-25.0", "M", "21.0", "M", "", "0000"},
|
||||
Checksum: "51",
|
||||
Raw: "$GPGGA,034225.077,3356.4650,S,15124.5567,E,1,03,9.7,-25.0,M,21.0,M,,0000*51",
|
||||
},
|
||||
Time: Time{true, 3, 42, 25, 77},
|
||||
Latitude: lat,
|
||||
Longitude: lon,
|
||||
FixQuality: GPS,
|
||||
NumSatellites: 03,
|
||||
HDOP: 9.7,
|
||||
Altitude: -25.0,
|
||||
Separation: 21.0,
|
||||
DGPSAge: "",
|
||||
DGPSId: "0000",
|
||||
}
|
||||
|
||||
assert.EqualValues(t, expected, sentence, "Sentence values do not match")
|
||||
}
|
||||
|
||||
func TestGPGGABadType(t *testing.T) {
|
||||
badType := "$GPRMC,220516,A,5133.82,N,00042.24,W,173.8,231.8,130694,004.2,W*70"
|
||||
s, err := Parse(badType)
|
||||
|
||||
assert.NoError(t, err, "Unexpected error parsing sentence")
|
||||
assert.NotEqual(t, "GPGGA", s.Prefix(), "Unexpected sentence type")
|
||||
}
|
||||
|
||||
func TestGPGGABadLatitude(t *testing.T) {
|
||||
badLat := "$GPGGA,034225.077,A,S,15124.5567,E,1,03,9.7,-25.0,M,21.0,M,,0000*3A"
|
||||
_, err := Parse(badLat)
|
||||
|
||||
assert.Error(t, err, "Parse error not returned")
|
||||
assert.Equal(t, "nmea: GPGGA invalid latitude: cannot parse [A S], unknown format", err.Error(), "Error message does not match")
|
||||
}
|
||||
|
||||
func TestGPGGABadLongitude(t *testing.T) {
|
||||
badLon := "$GPGGA,034225.077,3356.4650,S,A,E,1,03,9.7,-25.0,M,21.0,M,,0000*0C"
|
||||
_, err := Parse(badLon)
|
||||
|
||||
assert.Error(t, err, "Parse error not returned")
|
||||
assert.Equal(t, "nmea: GPGGA invalid longitude: cannot parse [A E], unknown format", err.Error(), "Error message does not match")
|
||||
}
|
||||
|
||||
func TestGPGGABadFixQuality(t *testing.T) {
|
||||
// Make sure bad fix mode is detected.
|
||||
badMode := "$GPGGA,034225.077,3356.4650,S,15124.5567,E,5,03,9.7,-25.0,M,21.0,M,,0000*55"
|
||||
_, err := Parse(badMode)
|
||||
|
||||
assert.Error(t, err, "Parse error not returned")
|
||||
assert.Equal(t, err.Error(), "nmea: GPGGA invalid fix quality: 5", "Error message not as expected")
|
||||
}
|
38
vendor/github.com/adrianmo/go-nmea/gpgll_test.go
generated
vendored
38
vendor/github.com/adrianmo/go-nmea/gpgll_test.go
generated
vendored
|
@ -1,38 +0,0 @@
|
|||
package nmea
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestGPGLLGoodSentence(t *testing.T) {
|
||||
goodMsg := "$GPGLL,3926.7952,N,12000.5947,W,022732,A,A*58"
|
||||
s, err := Parse(goodMsg)
|
||||
|
||||
assert.NoError(t, err, "Unexpected error parsing good sentence")
|
||||
assert.Equal(t, PrefixGPGLL, s.Prefix(), "Prefix does not match")
|
||||
|
||||
sentence := s.(GPGLL)
|
||||
|
||||
assert.Equal(t, "3926.7952", sentence.Latitude.PrintGPS(), "Latitude does not match")
|
||||
assert.Equal(t, "12000.5947", sentence.Longitude.PrintGPS(), "Longitude does not match")
|
||||
assert.Equal(t, Time{true, 2, 27, 32, 0}, sentence.Time, "Time does not match")
|
||||
assert.Equal(t, "A", sentence.Validity, "Status does not match")
|
||||
}
|
||||
|
||||
func TestGPGLLBadSentence(t *testing.T) {
|
||||
badMsg := "$GPGLL,3926.7952,N,12000.5947,W,022732,D,A*5D"
|
||||
_, err := Parse(badMsg)
|
||||
|
||||
assert.Error(t, err, "Parse error not returned")
|
||||
assert.Equal(t, "nmea: GPGLL invalid validity: D", err.Error(), "Incorrect error message")
|
||||
}
|
||||
|
||||
func TestGPGLLWrongSentence(t *testing.T) {
|
||||
wrongMsg := "$GPXTE,A,A,4.07,L,N*6D"
|
||||
_, err := Parse(wrongMsg)
|
||||
|
||||
assert.Error(t, err, "Parse error not returned")
|
||||
assert.Equal(t, "nmea: sentence type 'GPXTE' not implemented", err.Error(), "Incorrect error message")
|
||||
}
|
50
vendor/github.com/adrianmo/go-nmea/gpgsa_test.go
generated
vendored
50
vendor/github.com/adrianmo/go-nmea/gpgsa_test.go
generated
vendored
|
@ -1,50 +0,0 @@
|
|||
package nmea
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestGPGSAGoodSentence(t *testing.T) {
|
||||
goodMsg := "$GPGSA,A,3,22,19,18,27,14,03,,,,,,,3.1,2.0,2.4*36"
|
||||
sentence, err := Parse(goodMsg)
|
||||
|
||||
assert.NoError(t, err, "Unexpected error parsing good sentence")
|
||||
|
||||
// Attributes of the parsed sentence, and their expected values.
|
||||
expected := GPGSA{
|
||||
Sent: Sent{
|
||||
Type: "GPGSA",
|
||||
Fields: []string{"A", "3", "22", "19", "18", "27", "14", "03", "", "", "", "", "", "", "3.1", "2.0", "2.4"},
|
||||
Checksum: "36",
|
||||
Raw: "$GPGSA,A,3,22,19,18,27,14,03,,,,,,,3.1,2.0,2.4*36",
|
||||
},
|
||||
Mode: Auto,
|
||||
FixType: Fix3D,
|
||||
PDOP: 3.1,
|
||||
HDOP: 2.0,
|
||||
VDOP: 2.4,
|
||||
SV: []string{"22", "19", "18", "27", "14", "03"},
|
||||
}
|
||||
|
||||
assert.EqualValues(t, expected, sentence, "Sentence values do not match")
|
||||
}
|
||||
|
||||
func TestGPGSABadMode(t *testing.T) {
|
||||
// Make sure bad fix mode is detected.
|
||||
badMode := "$GPGSA,F,3,22,19,18,27,14,03,,,,,,,3.1,2.0,2.4*31"
|
||||
_, err := Parse(badMode)
|
||||
|
||||
assert.Error(t, err, "Parse error not returned")
|
||||
assert.Equal(t, "nmea: GPGSA invalid selection mode: F", err.Error(), "Error message does not match")
|
||||
}
|
||||
|
||||
func TestGPGSABadFix(t *testing.T) {
|
||||
// Make sure bad fix type is detected.
|
||||
badFixType := "$GPGSA,A,6,22,19,18,27,14,03,,,,,,,3.1,2.0,2.4*33"
|
||||
_, err := Parse(badFixType)
|
||||
|
||||
assert.Error(t, err, "Parse error not returned")
|
||||
assert.Equal(t, "nmea: GPGSA invalid fix type: 6", err.Error(), "Error message does not match")
|
||||
}
|
96
vendor/github.com/adrianmo/go-nmea/gpgsv_test.go
generated
vendored
96
vendor/github.com/adrianmo/go-nmea/gpgsv_test.go
generated
vendored
|
@ -1,96 +0,0 @@
|
|||
package nmea
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestGPGSVGoodSentence(t *testing.T) {
|
||||
goodMsg := "$GPGSV,3,1,11,03,03,111,00,04,15,270,00,06,01,010,12,13,06,292,00*77"
|
||||
s, err := Parse(goodMsg)
|
||||
|
||||
assert.NoError(t, err, "Unexpected error parsing good sentence")
|
||||
assert.Equal(t, PrefixGPGSV, s.Prefix(), "Prefix does not match")
|
||||
|
||||
sentence := s.(GPGSV)
|
||||
assert.Equal(t, int64(3), sentence.TotalMessages, "Total messages does not match")
|
||||
assert.Equal(t, int64(1), sentence.MessageNumber, "Message number does not match")
|
||||
assert.Equal(t, int64(11), sentence.NumberSVsInView, "Number of SVs in view does not match")
|
||||
|
||||
assert.Equal(t, int64(3), sentence.Info[0].SVPRNNumber, "Number of Info[0] SV PRN does not match")
|
||||
assert.Equal(t, int64(3), sentence.Info[0].Elevation, "Number of Info[0] Elevation does not match")
|
||||
assert.Equal(t, int64(111), sentence.Info[0].Azimuth, "Number of Info[0] Azimuth does not match")
|
||||
assert.Equal(t, int64(0), sentence.Info[0].SNR, "Number of Info[0] SNR does not match")
|
||||
|
||||
assert.Equal(t, int64(4), sentence.Info[1].SVPRNNumber, "Number of Info[1] SV PRN does not match")
|
||||
assert.Equal(t, int64(15), sentence.Info[1].Elevation, "Number of Info[1] Elevation does not match")
|
||||
assert.Equal(t, int64(270), sentence.Info[1].Azimuth, "Number of Info[1] Azimuth does not match")
|
||||
assert.Equal(t, int64(0), sentence.Info[1].SNR, "Number of Info[1] SNR does not match")
|
||||
|
||||
assert.Equal(t, int64(6), sentence.Info[2].SVPRNNumber, "Number of Info[2] SV PRN does not match")
|
||||
assert.Equal(t, int64(1), sentence.Info[2].Elevation, "Number of Info[2] Elevation does not match")
|
||||
assert.Equal(t, int64(10), sentence.Info[2].Azimuth, "Number of Info[2] Azimuth does not match")
|
||||
assert.Equal(t, int64(12), sentence.Info[2].SNR, "Number of Info[2] SNR does not match")
|
||||
|
||||
assert.Equal(t, int64(13), sentence.Info[3].SVPRNNumber, "Number of Info[3] SV PRN does not match")
|
||||
assert.Equal(t, int64(6), sentence.Info[3].Elevation, "Number of Info[3] Elevation does not match")
|
||||
assert.Equal(t, int64(292), sentence.Info[3].Azimuth, "Number of Info[3] Azimuth does not match")
|
||||
assert.Equal(t, int64(0), sentence.Info[3].SNR, "Number of Info[3] SNR does not match")
|
||||
}
|
||||
|
||||
func TestGPGSVShort(t *testing.T) {
|
||||
goodMsg := "$GPGSV,3,1,11,03,03,111,00,04,15,270,00,06,01,010,12*4A"
|
||||
s, err := Parse(goodMsg)
|
||||
|
||||
assert.NoError(t, err, "Unexpected error parsing good sentence")
|
||||
assert.Equal(t, PrefixGPGSV, s.Prefix(), "Prefix does not match")
|
||||
|
||||
sentence := s.(GPGSV)
|
||||
assert.Equal(t, int64(3), sentence.TotalMessages, "Total messages does not match")
|
||||
assert.Equal(t, int64(1), sentence.MessageNumber, "Message number does not match")
|
||||
assert.Equal(t, int64(11), sentence.NumberSVsInView, "Number of SVs in view does not match")
|
||||
|
||||
assert.Equal(t, int64(3), sentence.Info[0].SVPRNNumber, "Number of Info[0] SV PRN does not match")
|
||||
assert.Equal(t, int64(3), sentence.Info[0].Elevation, "Number of Info[0] Elevation does not match")
|
||||
assert.Equal(t, int64(111), sentence.Info[0].Azimuth, "Number of Info[0] Azimuth does not match")
|
||||
assert.Equal(t, int64(0), sentence.Info[0].SNR, "Number of Info[0] SNR does not match")
|
||||
|
||||
assert.Equal(t, int64(4), sentence.Info[1].SVPRNNumber, "Number of Info[1] SV PRN does not match")
|
||||
assert.Equal(t, int64(15), sentence.Info[1].Elevation, "Number of Info[1] Elevation does not match")
|
||||
assert.Equal(t, int64(270), sentence.Info[1].Azimuth, "Number of Info[1] Azimuth does not match")
|
||||
assert.Equal(t, int64(0), sentence.Info[1].SNR, "Number of Info[1] SNR does not match")
|
||||
|
||||
assert.Equal(t, int64(6), sentence.Info[2].SVPRNNumber, "Number of Info[2] SV PRN does not match")
|
||||
assert.Equal(t, int64(1), sentence.Info[2].Elevation, "Number of Info[2] Elevation does not match")
|
||||
assert.Equal(t, int64(10), sentence.Info[2].Azimuth, "Number of Info[2] Azimuth does not match")
|
||||
assert.Equal(t, int64(12), sentence.Info[2].SNR, "Number of Info[2] SNR does not match")
|
||||
}
|
||||
func TestGPGSVBadSentence(t *testing.T) {
|
||||
tests := []struct {
|
||||
Input string
|
||||
Error string
|
||||
}{
|
||||
{"$GPGSV,3,1,11.2,03,03,111,00,04,15,270,00,06,01,010,12,13,06,292,00*6b", "nmea: GPGSV invalid number of SVs in view: 11.2"},
|
||||
{"$GPGSV,A3,1,11,03,03,111,00,04,15,270,00,06,01,010,12,13,06,292,00*36", "nmea: GPGSV invalid total number of messages: A3"},
|
||||
{"$GPGSV,3,A1,11,03,03,111,00,04,15,270,00,06,01,010,12,13,06,292,00*36", "nmea: GPGSV invalid message number: A1"},
|
||||
{"$GPGSV,3,1,11,A03,03,111,00,04,15,270,00,06,01,010,12,13,06,292,00*36", "nmea: GPGSV invalid SV prn number: A03"},
|
||||
{"$GPGSV,3,1,11,03,A03,111,00,04,15,270,00,06,01,010,12,13,06,292,00*36", "nmea: GPGSV invalid elevation: A03"},
|
||||
{"$GPGSV,3,1,11,03,03,A111,00,04,15,270,00,06,01,010,12,13,06,292,00*36", "nmea: GPGSV invalid azimuth: A111"},
|
||||
{"$GPGSV,3,1,11,03,03,111,A00,04,15,270,00,06,01,010,12,13,06,292,00*36", "nmea: GPGSV invalid SNR: A00"},
|
||||
}
|
||||
for _, tc := range tests {
|
||||
_, err := Parse(tc.Input)
|
||||
assert.Error(t, err, "Parse error not returned")
|
||||
assert.Equal(t, tc.Error, err.Error(), "Incorrect error message")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestGPGSVWrongSentence(t *testing.T) {
|
||||
wrongMsg := "$GPXTE,A,A,4.07,L,N*6D"
|
||||
sent, _ := ParseSentence(wrongMsg)
|
||||
_, err := NewGPGSV(sent)
|
||||
assert.Error(t, err, "Parse error not returned")
|
||||
assert.Equal(t, "nmea: GPGSV invalid prefix: GPXTE", err.Error(), "Incorrect error message")
|
||||
}
|
86
vendor/github.com/adrianmo/go-nmea/gprmc_test.go
generated
vendored
86
vendor/github.com/adrianmo/go-nmea/gprmc_test.go
generated
vendored
|
@ -1,86 +0,0 @@
|
|||
package nmea
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func MustParseGPS(s string) LatLong {
|
||||
ll, err := ParseGPS(s)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return ll
|
||||
}
|
||||
|
||||
var gprmctests = []struct {
|
||||
Input string
|
||||
Output GPRMC
|
||||
}{
|
||||
{
|
||||
"$GPRMC,220516,A,5133.82,N,00042.24,W,173.8,231.8,130694,004.2,W*70",
|
||||
GPRMC{
|
||||
Time: Time{true, 22, 05, 16, 0},
|
||||
Validity: "A",
|
||||
Speed: 173.8,
|
||||
Course: 231.8,
|
||||
Date: Date{true, 13, 6, 94},
|
||||
Variation: -4.2,
|
||||
Latitude: MustParseGPS("5133.82 N"),
|
||||
Longitude: MustParseGPS("00042.24 W"),
|
||||
},
|
||||
},
|
||||
{
|
||||
"$GPRMC,142754.0,A,4302.539570,N,07920.379823,W,0.0,,070617,0.0,E,A*3F",
|
||||
GPRMC{
|
||||
Time: Time{true, 14, 27, 54, 0},
|
||||
Validity: "A",
|
||||
Speed: 0,
|
||||
Course: 0,
|
||||
Date: Date{true, 7, 6, 17},
|
||||
Variation: 0,
|
||||
Latitude: MustParseGPS("4302.539570 N"),
|
||||
Longitude: MustParseGPS("07920.379823 W"),
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
func TestGPRMCGoodSentence(t *testing.T) {
|
||||
|
||||
for _, tt := range gprmctests {
|
||||
|
||||
s, err := Parse(tt.Input)
|
||||
|
||||
assert.NoError(t, err, "Unexpected error parsing good sentence")
|
||||
assert.Equal(t, PrefixGPRMC, s.Prefix(), "Prefix does not match")
|
||||
|
||||
sentence := s.(GPRMC)
|
||||
|
||||
assert.Equal(t, tt.Output.Time, sentence.Time, "Time does not match")
|
||||
assert.Equal(t, tt.Output.Validity, sentence.Validity, "Status does not match")
|
||||
assert.Equal(t, tt.Output.Speed, sentence.Speed, "Speed does not match")
|
||||
assert.Equal(t, tt.Output.Course, sentence.Course, "Course does not match")
|
||||
assert.Equal(t, tt.Output.Date, sentence.Date, "Date does not match")
|
||||
assert.Equal(t, tt.Output.Variation, sentence.Variation, "Variation does not match")
|
||||
assert.Equal(t, tt.Output.Latitude, sentence.Latitude, "Latitude does not match")
|
||||
assert.Equal(t, tt.Output.Longitude, sentence.Longitude, "Longitude does not match")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestGPRMCBadSentence(t *testing.T) {
|
||||
badMsg := "$GPRMC,220516,D,5133.82,N,00042.24,W,173.8,231.8,130694,004.2,W*75"
|
||||
_, err := Parse(badMsg)
|
||||
|
||||
assert.Error(t, err, "Parse error not returned")
|
||||
assert.Equal(t, "nmea: GPRMC invalid validity: D", err.Error(), "Incorrect error message")
|
||||
}
|
||||
|
||||
func TestGPRMCWrongSentence(t *testing.T) {
|
||||
wrongMsg := "$GPXTE,A,A,4.07,L,N*6D"
|
||||
_, err := Parse(wrongMsg)
|
||||
|
||||
assert.Error(t, err, "Parse error not returned")
|
||||
assert.Equal(t, "nmea: sentence type 'GPXTE' not implemented", err.Error(), "Incorrect error message")
|
||||
}
|
38
vendor/github.com/adrianmo/go-nmea/gpvtg_test.go
generated
vendored
38
vendor/github.com/adrianmo/go-nmea/gpvtg_test.go
generated
vendored
|
@ -1,38 +0,0 @@
|
|||
package nmea
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestGPVTGGoodSentence(t *testing.T) {
|
||||
goodMsg := "$GPVTG,45.5,T,67.5,M,30.45,N,56.40,K*4B"
|
||||
s, err := Parse(goodMsg)
|
||||
|
||||
assert.NoError(t, err, "Unexpected error parsing good sentence")
|
||||
assert.Equal(t, PrefixGPVTG, s.Prefix(), "Prefix does not match")
|
||||
|
||||
sentence := s.(GPVTG)
|
||||
|
||||
assert.Equal(t, 45.5, sentence.TrueTrack, "True track does not match")
|
||||
assert.Equal(t, 67.5, sentence.MagneticTrack, "Magnetic track does not match")
|
||||
assert.Equal(t, 30.45, sentence.GroundSpeedKnots, "Ground speed (knots) does not match")
|
||||
assert.Equal(t, 56.40, sentence.GroundSpeedKPH, "Ground speed (km/h) does not match")
|
||||
}
|
||||
|
||||
func TestGPVTGBadSentence(t *testing.T) {
|
||||
badMsg := "$GPVTG,T,45.5,67.5,M,30.45,N,56.40,K*4B"
|
||||
_, err := Parse(badMsg)
|
||||
|
||||
assert.Error(t, err, "Parse error not returned")
|
||||
assert.Equal(t, "nmea: GPVTG invalid true track: T", err.Error(), "Incorrect error message")
|
||||
}
|
||||
|
||||
func TestGPVTGWrongSentence(t *testing.T) {
|
||||
wrongMsg := "$GPXTE,A,A,4.07,L,N*6D"
|
||||
_, err := Parse(wrongMsg)
|
||||
|
||||
assert.Error(t, err, "Parse error not returned")
|
||||
assert.Equal(t, "nmea: sentence type 'GPXTE' not implemented", err.Error(), "Incorrect error message")
|
||||
}
|
40
vendor/github.com/adrianmo/go-nmea/gpzda_test.go
generated
vendored
40
vendor/github.com/adrianmo/go-nmea/gpzda_test.go
generated
vendored
|
@ -1,40 +0,0 @@
|
|||
package nmea
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestGPZDAGoodSentence(t *testing.T) {
|
||||
goodMsg := "$GPZDA,172809.456,12,07,1996,00,00*57"
|
||||
s, err := Parse(goodMsg)
|
||||
|
||||
assert.NoError(t, err, "Unexpected error parsing good sentence")
|
||||
assert.Equal(t, PrefixGPZDA, s.Prefix(), "Prefix does not match")
|
||||
|
||||
sentence := s.(GPZDA)
|
||||
|
||||
assert.Equal(t, Time{true, 17, 28, 9, 456}, sentence.Time, "Time does not match")
|
||||
assert.Equal(t, int64(12), sentence.Day, "Day does not match")
|
||||
assert.Equal(t, int64(7), sentence.Month, "Month does not match")
|
||||
assert.Equal(t, int64(1996), sentence.Year, "Yeah does not match")
|
||||
assert.Equal(t, int64(0), sentence.OffsetHours, "Offset (hours) does not match")
|
||||
assert.Equal(t, int64(0), sentence.OffsetMinutes, "Offset (minutes) does not match")
|
||||
}
|
||||
|
||||
func TestGPZDABadSentence(t *testing.T) {
|
||||
badMsg := "$GPZDA,220516,D,5133.82,N,00042.24,W,173.8,231.8,130694,004.2,W*76"
|
||||
_, err := Parse(badMsg)
|
||||
|
||||
assert.Error(t, err, "Parse error not returned")
|
||||
assert.Equal(t, "nmea: GPZDA invalid day: D", err.Error(), "Incorrect error message")
|
||||
}
|
||||
|
||||
func TestGPZDAWrongSentence(t *testing.T) {
|
||||
wrongMsg := "$GPXTE,A,A,4.07,L,N*6D"
|
||||
_, err := Parse(wrongMsg)
|
||||
|
||||
assert.Error(t, err, "Parse error not returned")
|
||||
assert.Equal(t, "nmea: sentence type 'GPXTE' not implemented", err.Error(), "Incorrect error message")
|
||||
}
|
226
vendor/github.com/adrianmo/go-nmea/parser_test.go
generated
vendored
226
vendor/github.com/adrianmo/go-nmea/parser_test.go
generated
vendored
|
@ -1,226 +0,0 @@
|
|||
package nmea
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
var parsertests = []struct {
|
||||
name string
|
||||
fields []string
|
||||
expected interface{}
|
||||
hasErr bool
|
||||
parse func(p *parser) interface{}
|
||||
}{
|
||||
{
|
||||
name: "String",
|
||||
fields: []string{"foo", "bar"},
|
||||
expected: "bar",
|
||||
parse: func(p *parser) interface{} {
|
||||
return p.String(1, "")
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "String out of range",
|
||||
fields: []string{"wot"},
|
||||
expected: "",
|
||||
hasErr: true,
|
||||
parse: func(p *parser) interface{} {
|
||||
return p.String(5, "thing")
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "String with existing error",
|
||||
expected: "",
|
||||
hasErr: true,
|
||||
parse: func(p *parser) interface{} {
|
||||
p.SetErr("context", "value")
|
||||
return p.String(123, "blah")
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "EnumString",
|
||||
fields: []string{"a", "b", "c"},
|
||||
expected: "b",
|
||||
parse: func(p *parser) interface{} {
|
||||
return p.EnumString(1, "context", "b", "d")
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "EnumString invalid",
|
||||
fields: []string{"a", "b", "c"},
|
||||
expected: "",
|
||||
hasErr: true,
|
||||
parse: func(p *parser) interface{} {
|
||||
return p.EnumString(1, "context", "x", "y")
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "EnumString with existing error",
|
||||
fields: []string{"a", "b", "c"},
|
||||
expected: "",
|
||||
hasErr: true,
|
||||
parse: func(p *parser) interface{} {
|
||||
p.SetErr("context", "value")
|
||||
return p.EnumString(1, "context", "a", "b")
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Int64",
|
||||
fields: []string{"123"},
|
||||
expected: int64(123),
|
||||
parse: func(p *parser) interface{} {
|
||||
return p.Int64(0, "context")
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Int64 empty field is zero",
|
||||
fields: []string{""},
|
||||
expected: int64(0),
|
||||
parse: func(p *parser) interface{} {
|
||||
return p.Int64(0, "context")
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Int64 invalid",
|
||||
fields: []string{"abc"},
|
||||
expected: int64(0),
|
||||
hasErr: true,
|
||||
parse: func(p *parser) interface{} {
|
||||
return p.Int64(0, "context")
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Int64 with existing error",
|
||||
fields: []string{"123"},
|
||||
expected: int64(0),
|
||||
hasErr: true,
|
||||
parse: func(p *parser) interface{} {
|
||||
p.SetErr("context", "value")
|
||||
return p.Int64(0, "context")
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Float64",
|
||||
fields: []string{"123.123"},
|
||||
expected: float64(123.123),
|
||||
parse: func(p *parser) interface{} {
|
||||
return p.Float64(0, "context")
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Float64 empty field is zero",
|
||||
fields: []string{""},
|
||||
expected: float64(0),
|
||||
parse: func(p *parser) interface{} {
|
||||
return p.Float64(0, "context")
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Float64 invalid",
|
||||
fields: []string{"abc"},
|
||||
expected: float64(0),
|
||||
hasErr: true,
|
||||
parse: func(p *parser) interface{} {
|
||||
return p.Float64(0, "context")
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Float64 with existing error",
|
||||
fields: []string{"123.123"},
|
||||
expected: float64(0),
|
||||
hasErr: true,
|
||||
parse: func(p *parser) interface{} {
|
||||
p.SetErr("context", "value")
|
||||
return p.Float64(0, "context")
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Time",
|
||||
fields: []string{"123456"},
|
||||
expected: Time{true, 12, 34, 56, 0},
|
||||
parse: func(p *parser) interface{} {
|
||||
return p.Time(0, "context")
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Time empty field is zero",
|
||||
fields: []string{""},
|
||||
expected: Time{},
|
||||
parse: func(p *parser) interface{} {
|
||||
return p.Time(0, "context")
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Time with existing error",
|
||||
fields: []string{"123456"},
|
||||
expected: Time{},
|
||||
hasErr: true,
|
||||
parse: func(p *parser) interface{} {
|
||||
p.SetErr("context", "value")
|
||||
return p.Time(0, "context")
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Time invalid",
|
||||
fields: []string{"wrong"},
|
||||
expected: Time{},
|
||||
hasErr: true,
|
||||
parse: func(p *parser) interface{} {
|
||||
return p.Time(0, "context")
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Date",
|
||||
fields: []string{"010203"},
|
||||
expected: Date{true, 1, 2, 3},
|
||||
parse: func(p *parser) interface{} {
|
||||
return p.Date(0, "context")
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Date empty field is zero",
|
||||
fields: []string{""},
|
||||
expected: Date{},
|
||||
parse: func(p *parser) interface{} {
|
||||
return p.Date(0, "context")
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Date invalid",
|
||||
fields: []string{"Hello"},
|
||||
expected: Date{},
|
||||
hasErr: true,
|
||||
parse: func(p *parser) interface{} {
|
||||
return p.Date(0, "context")
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Date with existing error",
|
||||
fields: []string{"010203"},
|
||||
expected: Date{},
|
||||
hasErr: true,
|
||||
parse: func(p *parser) interface{} {
|
||||
p.SetErr("context", "value")
|
||||
return p.Date(0, "context")
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
func TestParser(t *testing.T) {
|
||||
for _, tt := range parsertests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
p := newParser(Sent{
|
||||
Type: "type",
|
||||
Fields: tt.fields,
|
||||
}, "type")
|
||||
assert.Equal(t, tt.expected, tt.parse(p))
|
||||
if tt.hasErr {
|
||||
assert.Error(t, p.Err())
|
||||
} else {
|
||||
assert.NoError(t, p.Err())
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
70
vendor/github.com/adrianmo/go-nmea/pgrme_test.go
generated
vendored
70
vendor/github.com/adrianmo/go-nmea/pgrme_test.go
generated
vendored
|
@ -1,70 +0,0 @@
|
|||
package nmea
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestPGRMEGoodSentence(t *testing.T) {
|
||||
goodMsg := "$PGRME,3.3,M,4.9,M,6.0,M*25"
|
||||
s, err := Parse(goodMsg)
|
||||
|
||||
assert.NoError(t, err, "Unexpected error parsing good sentence")
|
||||
assert.Equal(t, PrefixPGRME, s.Prefix(), "Prefix does not match")
|
||||
|
||||
sentence := s.(PGRME)
|
||||
|
||||
assert.Equal(t, 3.3, sentence.Horizontal, "Horizontal error does not match")
|
||||
assert.Equal(t, 4.9, sentence.Vertical, "Vertical error does not match")
|
||||
assert.Equal(t, 6.0, sentence.Spherical, "Spherical error does not match")
|
||||
|
||||
}
|
||||
|
||||
func TestPGRMEInvalidHorizontalError(t *testing.T) {
|
||||
badMsg := "$PGRME,A,M,4.9,M,6.0,M*4A"
|
||||
_, err := Parse(badMsg)
|
||||
|
||||
assert.Error(t, err, "Parse error not returned")
|
||||
assert.Equal(t, "nmea: PGRME invalid horizontal error: A", err.Error(), "Incorrect error message")
|
||||
}
|
||||
|
||||
func TestPGRMEInvalidHorizontalErrorUnit(t *testing.T) {
|
||||
badMsg := "$PGRME,3.3,A,4.9,M,6.0,M*29"
|
||||
_, err := Parse(badMsg)
|
||||
|
||||
assert.Error(t, err, "Parse error not returned")
|
||||
assert.Equal(t, "nmea: PGRME invalid horizontal error unit: A", err.Error(), "Incorrect error message")
|
||||
}
|
||||
|
||||
func TestPGRMEInvalidVerticalError(t *testing.T) {
|
||||
badMsg := "$PGRME,3.3,M,A,M,6.0,M*47"
|
||||
_, err := Parse(badMsg)
|
||||
|
||||
assert.Error(t, err, "Parse error not returned")
|
||||
assert.Equal(t, "nmea: PGRME invalid vertical error: A", err.Error(), "Incorrect error message")
|
||||
}
|
||||
|
||||
func TestPGRMEInvalidVerticalErrorUnit(t *testing.T) {
|
||||
badMsg := "$PGRME,3.3,M,4.9,A,6.0,M*29"
|
||||
_, err := Parse(badMsg)
|
||||
|
||||
assert.Error(t, err, "Parse error not returned")
|
||||
assert.Equal(t, "nmea: PGRME invalid vertical error unit: A", err.Error(), "Incorrect error message")
|
||||
}
|
||||
|
||||
func TestPGRMEInvalidSphericalError(t *testing.T) {
|
||||
badMsg := "$PGRME,3.3,M,4.9,M,A,M*4C"
|
||||
_, err := Parse(badMsg)
|
||||
|
||||
assert.Error(t, err, "Parse error not returned")
|
||||
assert.Equal(t, "nmea: PGRME invalid spherical error: A", err.Error(), "Incorrect error message")
|
||||
}
|
||||
|
||||
func TestPGRMEInvalidSphericalErrorUnit(t *testing.T) {
|
||||
badMsg := "$PGRME,3.3,M,4.9,M,6.0,A*29"
|
||||
_, err := Parse(badMsg)
|
||||
|
||||
assert.Error(t, err, "Parse error not returned")
|
||||
assert.Equal(t, "nmea: PGRME invalid spherical error unit: A", err.Error(), "Incorrect error message")
|
||||
}
|
96
vendor/github.com/adrianmo/go-nmea/sentence_test.go
generated
vendored
96
vendor/github.com/adrianmo/go-nmea/sentence_test.go
generated
vendored
|
@ -1,96 +0,0 @@
|
|||
package nmea
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestChecksumOK(t *testing.T) {
|
||||
_, err := ParseSentence("$GPFOO,1,2,3.3,x,y,zz,*51")
|
||||
assert.NoError(t, err, "Checksum check failed")
|
||||
}
|
||||
|
||||
func TestChecksumBad(t *testing.T) {
|
||||
_, err := ParseSentence("$GPFOO,1,2,3.4,x,y,zz,*51")
|
||||
assert.Error(t, err, "Checksum check failed")
|
||||
}
|
||||
|
||||
func TestChecksumBadRaw(t *testing.T) {
|
||||
badRaw := "$GPFOO,1,2,3.3,x,y,zz,*33"
|
||||
_, err := Parse(badRaw)
|
||||
assert.Error(t, err, "Expected 'Sentence checksum mismatch [51 != 33]'")
|
||||
}
|
||||
|
||||
func TestBadStartCharacter(t *testing.T) {
|
||||
// Check that a bad start character is flagged.
|
||||
rawBadStart := "%GPFOO,1,2,3,x,y,z*1A"
|
||||
_, err := Parse(rawBadStart)
|
||||
assert.Error(t, err, "Expected 'Sentence does not start with a '$''")
|
||||
}
|
||||
|
||||
func TestBadChecksumDelimiter(t *testing.T) {
|
||||
// Check that a bad checksum delimiter is flagged.
|
||||
rawBadSumSep := "$GPFOO,1,2,3,x,y,z"
|
||||
_, err := Parse(rawBadSumSep)
|
||||
assert.Error(t, err, "Expected 'Sentence does not contain single checksum separator'")
|
||||
}
|
||||
|
||||
func TestGoodParsing(t *testing.T) {
|
||||
// Check for good parsing.
|
||||
raw := "$GPRMC,235236,A,3925.9479,N,11945.9211,W,44.7,153.6,250905,15.2,E,A*0C"
|
||||
_, err := Parse(raw)
|
||||
assert.NoError(t, err, "Parse error")
|
||||
}
|
||||
|
||||
func TestGoodFields(t *testing.T) {
|
||||
raw := "$GPRMC,235236,A,3925.9479,N,11945.9211,W,44.7,153.6,250905,15.2,E,A*0C"
|
||||
expectedFields := []string{"235236", "A", "3925.9479", "N", "11945.9211", "W", "44.7", "153.6", "250905", "15.2", "E", "A"}
|
||||
m, _ := Parse(raw)
|
||||
assert.EqualValues(t, expectedFields, m.Sentence().Fields, "Got '%q', expected '%q'", m.Sentence().Fields, expectedFields)
|
||||
}
|
||||
|
||||
func TestGoodSentenceType(t *testing.T) {
|
||||
raw := "$GPRMC,235236,A,3925.9479,N,11945.9211,W,44.7,153.6,250905,15.2,E,A*0C"
|
||||
expected := "GPRMC"
|
||||
m, _ := Parse(raw)
|
||||
assert.Equal(t, expected, m.Prefix(), "Got '%s', expected '%s'", m.Prefix(), expected)
|
||||
}
|
||||
|
||||
func TestGoodRawSentence(t *testing.T) {
|
||||
raw := "$GPRMC,235236,A,3925.9479,N,11945.9211,W,44.7,153.6,250905,15.2,E,A*0C"
|
||||
m, _ := Parse(raw)
|
||||
assert.Equal(t, raw, m.String(), "Bad raw sentence")
|
||||
}
|
||||
|
||||
func TestMultipleStartDelimiterSentence(t *testing.T) {
|
||||
raw := "$$$$GPRMC,235236,A,3925.9479,N,11945.9211,W,44.7,153.6,250905,15.2,E,A*0C"
|
||||
result, err := Parse(raw)
|
||||
assert.Nil(t, result, "Result should be nil")
|
||||
assert.NotNil(t, err, "Err should be an error")
|
||||
assert.Equal(t, "nmea: sentence checksum mismatch [28 != 0C]", err.Error(), "Error sentence mismatch")
|
||||
}
|
||||
|
||||
func TestNoStartDelimiterSentence(t *testing.T) {
|
||||
raw := "abc$GPRMC,235236,A,3925.9479,N,11945.9211,W,44.7,153.6,250905,15.2,E,A*0C"
|
||||
result, err := Parse(raw)
|
||||
assert.Nil(t, result, "Result should be nil")
|
||||
assert.NotNil(t, err, "Err should be an error")
|
||||
assert.Equal(t, "nmea: sentence does not start with a '$'", err.Error(), "Error sentence mismatch")
|
||||
}
|
||||
|
||||
func TestNoContainDelimiterSentence(t *testing.T) {
|
||||
raw := "GPRMC,235236,A,3925.9479,N,11945.9211,W,44.7,153.6,250905,15.2,E,A*0C"
|
||||
result, err := Parse(raw)
|
||||
assert.Nil(t, result, "Result should be nil")
|
||||
assert.NotNil(t, err, "Err should be an error")
|
||||
assert.Equal(t, "nmea: sentence does not start with a '$'", err.Error(), "Error sentence mismatch")
|
||||
}
|
||||
|
||||
func TestReturnValues(t *testing.T) {
|
||||
// Ensure Parse returns errors when appropriate.
|
||||
result, err := Parse("$GPRMC,235236,A,3925.9479,N,11945.9211,W,44.7,153.6,250905,15.2,E,A*0A")
|
||||
assert.Nil(t, result, "Result should be nil")
|
||||
assert.NotNil(t, err, "Err should be an error")
|
||||
assert.Equal(t, "nmea: sentence checksum mismatch [0C != 0A]", err.Error(), "Error sentence mismatch")
|
||||
}
|
152
vendor/github.com/adrianmo/go-nmea/types_test.go
generated
vendored
152
vendor/github.com/adrianmo/go-nmea/types_test.go
generated
vendored
|
@ -1,152 +0,0 @@
|
|||
package nmea
|
||||
|
||||
import "testing"
|
||||
|
||||
var nearDistance = 0.001
|
||||
|
||||
func TestLatLongParse(t *testing.T) {
|
||||
var l LatLong
|
||||
var err error
|
||||
value, expected := "3345.1232 N", LatLong(33.752054)
|
||||
if l, err = ParseGPS(value); err != nil {
|
||||
t.Errorf("ParseGPS error: %s", err)
|
||||
} else if !l.IsNear(expected, nearDistance) {
|
||||
t.Errorf("ParseGPS got %f, expected %f", l, expected)
|
||||
}
|
||||
|
||||
value, expected = "15145.9877 S", LatLong(-151.76646)
|
||||
if l, err = ParseGPS(value); err != nil {
|
||||
t.Errorf("ParseGPS error: %s", err)
|
||||
} else if !l.IsNear(expected, nearDistance) {
|
||||
t.Errorf("ParseGPS got %f, expected %f", l, expected)
|
||||
}
|
||||
|
||||
value, expected = "33\u00B0 12' 34.3423\"", LatLong(33.209540)
|
||||
if l, err = ParseDMS(value); err != nil {
|
||||
t.Errorf("ParseDMS error: %s", err)
|
||||
} else if !l.IsNear(expected, nearDistance) {
|
||||
t.Errorf("ParseDMS got %f, expected %f", l, expected)
|
||||
}
|
||||
|
||||
value, expected = "151.234532", LatLong(151.234532)
|
||||
if l, err = ParseDecimal(value); err != nil {
|
||||
t.Errorf("ParseDecimal error: %s", err)
|
||||
} else if !l.IsNear(expected, nearDistance) {
|
||||
t.Errorf("ParseDecimal got %f, expected %f", l, expected)
|
||||
}
|
||||
|
||||
value, expected = "-151.234532", LatLong(-151.234532)
|
||||
if l, err = ParseDecimal(value); err != nil {
|
||||
t.Errorf("ParseDecimal error: %s", err)
|
||||
} else if !l.IsNear(expected, nearDistance) {
|
||||
t.Errorf("ParseDecimal got %f, expected %f", l, expected)
|
||||
}
|
||||
}
|
||||
|
||||
func TestLatLongPrint(t *testing.T) {
|
||||
l, _ := ParseDecimal("151.434367")
|
||||
exp := "15126.0620"
|
||||
if s := l.PrintGPS(); s != exp {
|
||||
t.Errorf("PrintGPS() got %s expected %s", s, exp)
|
||||
}
|
||||
|
||||
l, _ = ParseGPS("3356.4343 N")
|
||||
exp = "3356.4343"
|
||||
if s := l.PrintGPS(); s != exp {
|
||||
t.Errorf("PrintGPS() got %s expected %s", s, exp)
|
||||
}
|
||||
|
||||
exp = "33° 56' 26.058000\""
|
||||
if s := l.PrintDMS(); s != exp {
|
||||
t.Errorf("PrintDMS() got %s expected %s", s, exp)
|
||||
}
|
||||
}
|
||||
|
||||
func TestTimeParse(t *testing.T) {
|
||||
timetests := []struct {
|
||||
value string
|
||||
expected Time
|
||||
ok bool
|
||||
}{
|
||||
{"123456", Time{true, 12, 34, 56, 0}, true},
|
||||
{"", Time{}, true},
|
||||
{"112233.123", Time{true, 11, 22, 33, 123}, true},
|
||||
{"010203.04", Time{true, 1, 2, 3, 4}, true},
|
||||
{"10203.04", Time{}, false},
|
||||
{"x0u2xd", Time{}, false},
|
||||
{"xx2233.123", Time{}, false},
|
||||
{"11xx33.123", Time{}, false},
|
||||
{"1122xx.123", Time{}, false},
|
||||
{"112233.xxx", Time{}, false},
|
||||
}
|
||||
for _, tt := range timetests {
|
||||
actual, err := ParseTime(tt.value)
|
||||
if !tt.ok {
|
||||
if err == nil {
|
||||
t.Errorf("ParseTime(%s) expected error", tt.value)
|
||||
}
|
||||
} else {
|
||||
if err != nil {
|
||||
t.Errorf("ParseTime(%s) %s", tt.value, err)
|
||||
}
|
||||
if actual != tt.expected {
|
||||
t.Errorf("ParseTime(%s) got %s expected %s", tt.value, actual, tt.expected)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestTimeString(t *testing.T) {
|
||||
d := Time{
|
||||
Hour: 1,
|
||||
Minute: 2,
|
||||
Second: 3,
|
||||
Millisecond: 4,
|
||||
}
|
||||
expected := "01:02:03.0004"
|
||||
if s := d.String(); s != expected {
|
||||
t.Fatalf("got %s, expected %s", s, expected)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDateParse(t *testing.T) {
|
||||
datetests := []struct {
|
||||
value string
|
||||
expected Date
|
||||
ok bool
|
||||
}{
|
||||
{"010203", Date{true, 1, 2, 3}, true},
|
||||
{"01003", Date{}, false},
|
||||
{"", Date{}, true},
|
||||
{"xx0203", Date{}, false},
|
||||
{"01xx03", Date{}, false},
|
||||
{"0102xx", Date{}, false},
|
||||
}
|
||||
for _, tt := range datetests {
|
||||
actual, err := ParseDate(tt.value)
|
||||
if !tt.ok {
|
||||
if err == nil {
|
||||
t.Errorf("ParseDate(%s) expected error", tt.value)
|
||||
}
|
||||
} else {
|
||||
if err != nil {
|
||||
t.Errorf("ParseDate(%s) %s", tt.value, err)
|
||||
}
|
||||
if actual != tt.expected {
|
||||
t.Errorf("ParseDate(%s) got %s expected %s", tt.value, actual, tt.expected)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestDateString(t *testing.T) {
|
||||
d := Date{
|
||||
DD: 1,
|
||||
MM: 2,
|
||||
YY: 3,
|
||||
}
|
||||
expected := "01/02/03"
|
||||
if s := d.String(); s != expected {
|
||||
t.Fatalf("got %s expected %s", s, expected)
|
||||
}
|
||||
}
|
12
vendor/github.com/chifflier/nfqueue-go/.travis.yml
generated
vendored
12
vendor/github.com/chifflier/nfqueue-go/.travis.yml
generated
vendored
|
@ -1,12 +0,0 @@
|
|||
language: go
|
||||
|
||||
go:
|
||||
- 1.6
|
||||
- tip
|
||||
install:
|
||||
- go get github.com/google/gopacket
|
||||
- go get github.com/google/gopacket/layers
|
||||
- go get github.com/chifflier/nfqueue-go/nfqueue
|
||||
before_install:
|
||||
- sudo apt-get -qq update
|
||||
- sudo apt-get install -y pkg-config libnfnetlink-dev libnetfilter-queue-dev
|
54
vendor/github.com/chifflier/nfqueue-go/README.md
generated
vendored
54
vendor/github.com/chifflier/nfqueue-go/README.md
generated
vendored
|
@ -1,54 +0,0 @@
|
|||
# nfqueue-go
|
||||
|
||||
|
||||
[](https://travis-ci.org/chifflier/nfqueue-go)
|
||||
[](https://godoc.org/github.com/chifflier/nfqueue-go/nfqueue)
|
||||
|
||||
nfqueue-go is a wrapper library for
|
||||
[libnetfilter-queue](http://www.netfilter.org/projects/libnetfilter_queue/). The goal is to provide a library to gain access to packets queued by the kernel packet filter.
|
||||
|
||||
It is important to note that these bindings will not follow blindly libnetfilter_queue API. For ex., some higher-level wrappers will be provided for the open/bind/create mechanism (using one function call instead of three).
|
||||
|
||||
**The API is not yet stable.**
|
||||
|
||||
To use the library, a program must
|
||||
- open a queue
|
||||
- bind to a network family (`AF_PACKET` for IPv4)
|
||||
- provide a callback function, which will be automatically called when a packet is received. The callback must return a verdict
|
||||
- create the queue, providing the queue number (which must match the `--queue-num` from the iptables rules, see below
|
||||
- run a loop, waiting for events. The program should also provide a clean way to exit the loop (for ex on `SIGINT`)
|
||||
|
||||
## Using library
|
||||
|
||||
```
|
||||
import "github.com/chifflier/nfqueue-go/nfqueue"
|
||||
```
|
||||
|
||||
## Example
|
||||
|
||||
See [test_nfqueue](nfqueue/test_nfqueue/test_nfqueue.go) for a minimal example, and [test_nfqueue_gopacket](nfqueue/test_nfqueue_gopacket/test_nfqueue.go) for an example using the [gopacket](https://github.com/google/gopacket) library to decode the packets.
|
||||
|
||||
## IPtables
|
||||
|
||||
You must add rules in netfilter to send packets to the userspace queue.
|
||||
The number of the queue (--queue-num option in netfilter) must match the
|
||||
number provided to create_queue().
|
||||
|
||||
Example of iptables rules:
|
||||
|
||||
iptables -A OUTPUT --destination 1.2.3.4 -j NFQUEUE --queue-num 0
|
||||
|
||||
Of course, you should be more restrictive, depending on your needs.
|
||||
|
||||
## Privileges
|
||||
|
||||
nfqueue-go does not require root privileges, but needs to open a netlink socket and send/receive packets to the kernel.
|
||||
|
||||
You have several options:
|
||||
- Use the CAP_NET_ADMIN capability in order to allow your application to receive from and to send packets to kernel-space:
|
||||
```setcap 'cap_net_admin=+ep' /path/to/program```
|
||||
- Run your program as `root` and drop privileges
|
||||
|
||||
## License
|
||||
|
||||
This library is licensed under the GNU General Public License version 2, or (at your option) any later version.
|
54
vendor/github.com/chifflier/nfqueue-go/nfqueue/test_nfqueue/test_nfqueue.go
generated
vendored
54
vendor/github.com/chifflier/nfqueue-go/nfqueue/test_nfqueue/test_nfqueue.go
generated
vendored
|
@ -1,54 +0,0 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"github.com/chifflier/nfqueue-go/nfqueue"
|
||||
"os"
|
||||
"os/signal"
|
||||
"syscall"
|
||||
)
|
||||
|
||||
func real_callback(payload *nfqueue.Payload) int {
|
||||
fmt.Println("Real callback")
|
||||
fmt.Printf(" id: %d\n", payload.Id)
|
||||
fmt.Printf(" mark: %d\n", payload.GetNFMark())
|
||||
fmt.Printf(" in %d out %d\n", payload.GetInDev(), payload.GetOutDev())
|
||||
fmt.Printf(" Φin %d Φout %d\n", payload.GetPhysInDev(), payload.GetPhysOutDev())
|
||||
fmt.Println(hex.Dump(payload.Data))
|
||||
fmt.Println("-- ")
|
||||
payload.SetVerdict(nfqueue.NF_ACCEPT)
|
||||
return 0
|
||||
}
|
||||
|
||||
func main() {
|
||||
q := new(nfqueue.Queue)
|
||||
|
||||
q.SetCallback(real_callback)
|
||||
|
||||
q.Init()
|
||||
defer q.Close()
|
||||
|
||||
q.Unbind(syscall.AF_INET)
|
||||
q.Bind(syscall.AF_INET)
|
||||
|
||||
q.CreateQueue(0)
|
||||
q.SetMode(nfqueue.NFQNL_COPY_PACKET)
|
||||
|
||||
c := make(chan os.Signal, 1)
|
||||
signal.Notify(c, os.Interrupt)
|
||||
go func(){
|
||||
for sig := range c {
|
||||
// sig is a ^C, handle it
|
||||
_ = sig
|
||||
q.StopLoop()
|
||||
}
|
||||
}()
|
||||
|
||||
// XXX Drop privileges here
|
||||
|
||||
q.Loop()
|
||||
q.DestroyQueue()
|
||||
q.Close()
|
||||
os.Exit(0)
|
||||
}
|
66
vendor/github.com/chifflier/nfqueue-go/nfqueue/test_nfqueue_gopacket/test_nfqueue.go
generated
vendored
66
vendor/github.com/chifflier/nfqueue-go/nfqueue/test_nfqueue_gopacket/test_nfqueue.go
generated
vendored
|
@ -1,66 +0,0 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"github.com/chifflier/nfqueue-go/nfqueue"
|
||||
"os"
|
||||
"os/signal"
|
||||
"syscall"
|
||||
|
||||
"github.com/google/gopacket"
|
||||
"github.com/google/gopacket/layers"
|
||||
)
|
||||
|
||||
func real_callback(payload *nfqueue.Payload) int {
|
||||
fmt.Println("Real callback")
|
||||
fmt.Printf(" id: %d\n", payload.Id)
|
||||
fmt.Println(hex.Dump(payload.Data))
|
||||
// Decode a packet
|
||||
packet := gopacket.NewPacket(payload.Data, layers.LayerTypeIPv4, gopacket.Default)
|
||||
// Get the TCP layer from this packet
|
||||
if tcpLayer := packet.Layer(layers.LayerTypeTCP); tcpLayer != nil {
|
||||
fmt.Println("This is a TCP packet!")
|
||||
// Get actual TCP data from this layer
|
||||
tcp, _ := tcpLayer.(*layers.TCP)
|
||||
fmt.Printf("From src port %d to dst port %d\n", tcp.SrcPort, tcp.DstPort)
|
||||
}
|
||||
// Iterate over all layers, printing out each layer type
|
||||
for _, layer := range packet.Layers() {
|
||||
fmt.Println("PACKET LAYER:", layer.LayerType())
|
||||
fmt.Println(gopacket.LayerDump(layer))
|
||||
}
|
||||
fmt.Println("-- ")
|
||||
payload.SetVerdict(nfqueue.NF_ACCEPT)
|
||||
return 0
|
||||
}
|
||||
|
||||
func main() {
|
||||
q := new(nfqueue.Queue)
|
||||
|
||||
q.SetCallback(real_callback)
|
||||
|
||||
q.Init()
|
||||
|
||||
q.Unbind(syscall.AF_INET)
|
||||
q.Bind(syscall.AF_INET)
|
||||
|
||||
q.CreateQueue(0)
|
||||
|
||||
c := make(chan os.Signal, 1)
|
||||
signal.Notify(c, os.Interrupt)
|
||||
go func(){
|
||||
for sig := range c {
|
||||
// sig is a ^C, handle it
|
||||
_ = sig
|
||||
q.StopLoop()
|
||||
}
|
||||
}()
|
||||
|
||||
// XXX Drop privileges here
|
||||
|
||||
q.Loop()
|
||||
q.DestroyQueue()
|
||||
q.Close()
|
||||
os.Exit(0)
|
||||
}
|
220
vendor/github.com/dustin/go-humanize/bigbytes_test.go
generated
vendored
220
vendor/github.com/dustin/go-humanize/bigbytes_test.go
generated
vendored
|
@ -1,220 +0,0 @@
|
|||
package humanize
|
||||
|
||||
import (
|
||||
"math/big"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestBigByteParsing(t *testing.T) {
|
||||
tests := []struct {
|
||||
in string
|
||||
exp uint64
|
||||
}{
|
||||
{"42", 42},
|
||||
{"42MB", 42000000},
|
||||
{"42MiB", 44040192},
|
||||
{"42mb", 42000000},
|
||||
{"42mib", 44040192},
|
||||
{"42MIB", 44040192},
|
||||
{"42 MB", 42000000},
|
||||
{"42 MiB", 44040192},
|
||||
{"42 mb", 42000000},
|
||||
{"42 mib", 44040192},
|
||||
{"42 MIB", 44040192},
|
||||
{"42.5MB", 42500000},
|
||||
{"42.5MiB", 44564480},
|
||||
{"42.5 MB", 42500000},
|
||||
{"42.5 MiB", 44564480},
|
||||
// No need to say B
|
||||
{"42M", 42000000},
|
||||
{"42Mi", 44040192},
|
||||
{"42m", 42000000},
|
||||
{"42mi", 44040192},
|
||||
{"42MI", 44040192},
|
||||
{"42 M", 42000000},
|
||||
{"42 Mi", 44040192},
|
||||
{"42 m", 42000000},
|
||||
{"42 mi", 44040192},
|
||||
{"42 MI", 44040192},
|
||||
{"42.5M", 42500000},
|
||||
{"42.5Mi", 44564480},
|
||||
{"42.5 M", 42500000},
|
||||
{"42.5 Mi", 44564480},
|
||||
{"1,005.03 MB", 1005030000},
|
||||
// Large testing, breaks when too much larger than
|
||||
// this.
|
||||
{"12.5 EB", uint64(12.5 * float64(EByte))},
|
||||
{"12.5 E", uint64(12.5 * float64(EByte))},
|
||||
{"12.5 EiB", uint64(12.5 * float64(EiByte))},
|
||||
}
|
||||
|
||||
for _, p := range tests {
|
||||
got, err := ParseBigBytes(p.in)
|
||||
if err != nil {
|
||||
t.Errorf("Couldn't parse %v: %v", p.in, err)
|
||||
} else {
|
||||
if got.Uint64() != p.exp {
|
||||
t.Errorf("Expected %v for %v, got %v",
|
||||
p.exp, p.in, got)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestBigByteErrors(t *testing.T) {
|
||||
got, err := ParseBigBytes("84 JB")
|
||||
if err == nil {
|
||||
t.Errorf("Expected error, got %v", got)
|
||||
}
|
||||
got, err = ParseBigBytes("")
|
||||
if err == nil {
|
||||
t.Errorf("Expected error parsing nothing")
|
||||
}
|
||||
}
|
||||
|
||||
func bbyte(in uint64) string {
|
||||
return BigBytes((&big.Int{}).SetUint64(in))
|
||||
}
|
||||
|
||||
func bibyte(in uint64) string {
|
||||
return BigIBytes((&big.Int{}).SetUint64(in))
|
||||
}
|
||||
|
||||
func TestBigBytes(t *testing.T) {
|
||||
testList{
|
||||
{"bytes(0)", bbyte(0), "0 B"},
|
||||
{"bytes(1)", bbyte(1), "1 B"},
|
||||
{"bytes(803)", bbyte(803), "803 B"},
|
||||
{"bytes(999)", bbyte(999), "999 B"},
|
||||
|
||||
{"bytes(1024)", bbyte(1024), "1.0 kB"},
|
||||
{"bytes(1MB - 1)", bbyte(MByte - Byte), "1000 kB"},
|
||||
|
||||
{"bytes(1MB)", bbyte(1024 * 1024), "1.0 MB"},
|
||||
{"bytes(1GB - 1K)", bbyte(GByte - KByte), "1000 MB"},
|
||||
|
||||
{"bytes(1GB)", bbyte(GByte), "1.0 GB"},
|
||||
{"bytes(1TB - 1M)", bbyte(TByte - MByte), "1000 GB"},
|
||||
|
||||
{"bytes(1TB)", bbyte(TByte), "1.0 TB"},
|
||||
{"bytes(1PB - 1T)", bbyte(PByte - TByte), "999 TB"},
|
||||
|
||||
{"bytes(1PB)", bbyte(PByte), "1.0 PB"},
|
||||
{"bytes(1PB - 1T)", bbyte(EByte - PByte), "999 PB"},
|
||||
|
||||
{"bytes(1EB)", bbyte(EByte), "1.0 EB"},
|
||||
// Overflows.
|
||||
// {"bytes(1EB - 1P)", Bytes((KByte*EByte)-PByte), "1023EB"},
|
||||
|
||||
{"bytes(0)", bibyte(0), "0 B"},
|
||||
{"bytes(1)", bibyte(1), "1 B"},
|
||||
{"bytes(803)", bibyte(803), "803 B"},
|
||||
{"bytes(1023)", bibyte(1023), "1023 B"},
|
||||
|
||||
{"bytes(1024)", bibyte(1024), "1.0 KiB"},
|
||||
{"bytes(1MB - 1)", bibyte(MiByte - IByte), "1024 KiB"},
|
||||
|
||||
{"bytes(1MB)", bibyte(1024 * 1024), "1.0 MiB"},
|
||||
{"bytes(1GB - 1K)", bibyte(GiByte - KiByte), "1024 MiB"},
|
||||
|
||||
{"bytes(1GB)", bibyte(GiByte), "1.0 GiB"},
|
||||
{"bytes(1TB - 1M)", bibyte(TiByte - MiByte), "1024 GiB"},
|
||||
|
||||
{"bytes(1TB)", bibyte(TiByte), "1.0 TiB"},
|
||||
{"bytes(1PB - 1T)", bibyte(PiByte - TiByte), "1023 TiB"},
|
||||
|
||||
{"bytes(1PB)", bibyte(PiByte), "1.0 PiB"},
|
||||
{"bytes(1PB - 1T)", bibyte(EiByte - PiByte), "1023 PiB"},
|
||||
|
||||
{"bytes(1EiB)", bibyte(EiByte), "1.0 EiB"},
|
||||
// Overflows.
|
||||
// {"bytes(1EB - 1P)", bibyte((KIByte*EIByte)-PiByte), "1023EB"},
|
||||
|
||||
{"bytes(5.5GiB)", bibyte(5.5 * GiByte), "5.5 GiB"},
|
||||
|
||||
{"bytes(5.5GB)", bbyte(5.5 * GByte), "5.5 GB"},
|
||||
}.validate(t)
|
||||
}
|
||||
|
||||
func TestVeryBigBytes(t *testing.T) {
|
||||
b, _ := (&big.Int{}).SetString("15347691069326346944512", 10)
|
||||
s := BigBytes(b)
|
||||
if s != "15 ZB" {
|
||||
t.Errorf("Expected 15 ZB, got %v", s)
|
||||
}
|
||||
s = BigIBytes(b)
|
||||
if s != "13 ZiB" {
|
||||
t.Errorf("Expected 13 ZiB, got %v", s)
|
||||
}
|
||||
|
||||
b, _ = (&big.Int{}).SetString("15716035654990179271180288", 10)
|
||||
s = BigBytes(b)
|
||||
if s != "16 YB" {
|
||||
t.Errorf("Expected 16 YB, got %v", s)
|
||||
}
|
||||
s = BigIBytes(b)
|
||||
if s != "13 YiB" {
|
||||
t.Errorf("Expected 13 YiB, got %v", s)
|
||||
}
|
||||
}
|
||||
|
||||
func TestVeryVeryBigBytes(t *testing.T) {
|
||||
b, _ := (&big.Int{}).SetString("16093220510709943573688614912", 10)
|
||||
s := BigBytes(b)
|
||||
if s != "16093 YB" {
|
||||
t.Errorf("Expected 16093 YB, got %v", s)
|
||||
}
|
||||
s = BigIBytes(b)
|
||||
if s != "13312 YiB" {
|
||||
t.Errorf("Expected 13312 YiB, got %v", s)
|
||||
}
|
||||
}
|
||||
|
||||
func TestParseVeryBig(t *testing.T) {
|
||||
tests := []struct {
|
||||
in string
|
||||
out string
|
||||
}{
|
||||
{"16 ZB", "16000000000000000000000"},
|
||||
{"16 ZiB", "18889465931478580854784"},
|
||||
{"16.5 ZB", "16500000000000000000000"},
|
||||
{"16.5 ZiB", "19479761741837286506496"},
|
||||
{"16 Z", "16000000000000000000000"},
|
||||
{"16 Zi", "18889465931478580854784"},
|
||||
{"16.5 Z", "16500000000000000000000"},
|
||||
{"16.5 Zi", "19479761741837286506496"},
|
||||
|
||||
{"16 YB", "16000000000000000000000000"},
|
||||
{"16 YiB", "19342813113834066795298816"},
|
||||
{"16.5 YB", "16500000000000000000000000"},
|
||||
{"16.5 YiB", "19947276023641381382651904"},
|
||||
{"16 Y", "16000000000000000000000000"},
|
||||
{"16 Yi", "19342813113834066795298816"},
|
||||
{"16.5 Y", "16500000000000000000000000"},
|
||||
{"16.5 Yi", "19947276023641381382651904"},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
x, err := ParseBigBytes(test.in)
|
||||
if err != nil {
|
||||
t.Errorf("Error parsing %q: %v", test.in, err)
|
||||
continue
|
||||
}
|
||||
|
||||
if x.String() != test.out {
|
||||
t.Errorf("Expected %q for %q, got %v", test.out, test.in, x)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkParseBigBytes(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
ParseBigBytes("16.5 Z")
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkBigBytes(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
bibyte(16.5 * GByte)
|
||||
}
|
||||
}
|
146
vendor/github.com/dustin/go-humanize/bytes_test.go
generated
vendored
146
vendor/github.com/dustin/go-humanize/bytes_test.go
generated
vendored
|
@ -1,146 +0,0 @@
|
|||
package humanize
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestByteParsing(t *testing.T) {
|
||||
tests := []struct {
|
||||
in string
|
||||
exp uint64
|
||||
}{
|
||||
{"42", 42},
|
||||
{"42MB", 42000000},
|
||||
{"42MiB", 44040192},
|
||||
{"42mb", 42000000},
|
||||
{"42mib", 44040192},
|
||||
{"42MIB", 44040192},
|
||||
{"42 MB", 42000000},
|
||||
{"42 MiB", 44040192},
|
||||
{"42 mb", 42000000},
|
||||
{"42 mib", 44040192},
|
||||
{"42 MIB", 44040192},
|
||||
{"42.5MB", 42500000},
|
||||
{"42.5MiB", 44564480},
|
||||
{"42.5 MB", 42500000},
|
||||
{"42.5 MiB", 44564480},
|
||||
// No need to say B
|
||||
{"42M", 42000000},
|
||||
{"42Mi", 44040192},
|
||||
{"42m", 42000000},
|
||||
{"42mi", 44040192},
|
||||
{"42MI", 44040192},
|
||||
{"42 M", 42000000},
|
||||
{"42 Mi", 44040192},
|
||||
{"42 m", 42000000},
|
||||
{"42 mi", 44040192},
|
||||
{"42 MI", 44040192},
|
||||
{"42.5M", 42500000},
|
||||
{"42.5Mi", 44564480},
|
||||
{"42.5 M", 42500000},
|
||||
{"42.5 Mi", 44564480},
|
||||
// Bug #42
|
||||
{"1,005.03 MB", 1005030000},
|
||||
// Large testing, breaks when too much larger than
|
||||
// this.
|
||||
{"12.5 EB", uint64(12.5 * float64(EByte))},
|
||||
{"12.5 E", uint64(12.5 * float64(EByte))},
|
||||
{"12.5 EiB", uint64(12.5 * float64(EiByte))},
|
||||
}
|
||||
|
||||
for _, p := range tests {
|
||||
got, err := ParseBytes(p.in)
|
||||
if err != nil {
|
||||
t.Errorf("Couldn't parse %v: %v", p.in, err)
|
||||
}
|
||||
if got != p.exp {
|
||||
t.Errorf("Expected %v for %v, got %v",
|
||||
p.exp, p.in, got)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestByteErrors(t *testing.T) {
|
||||
got, err := ParseBytes("84 JB")
|
||||
if err == nil {
|
||||
t.Errorf("Expected error, got %v", got)
|
||||
}
|
||||
got, err = ParseBytes("")
|
||||
if err == nil {
|
||||
t.Errorf("Expected error parsing nothing")
|
||||
}
|
||||
got, err = ParseBytes("16 EiB")
|
||||
if err == nil {
|
||||
t.Errorf("Expected error, got %v", got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestBytes(t *testing.T) {
|
||||
testList{
|
||||
{"bytes(0)", Bytes(0), "0 B"},
|
||||
{"bytes(1)", Bytes(1), "1 B"},
|
||||
{"bytes(803)", Bytes(803), "803 B"},
|
||||
{"bytes(999)", Bytes(999), "999 B"},
|
||||
|
||||
{"bytes(1024)", Bytes(1024), "1.0 kB"},
|
||||
{"bytes(9999)", Bytes(9999), "10 kB"},
|
||||
{"bytes(1MB - 1)", Bytes(MByte - Byte), "1000 kB"},
|
||||
|
||||
{"bytes(1MB)", Bytes(1024 * 1024), "1.0 MB"},
|
||||
{"bytes(1GB - 1K)", Bytes(GByte - KByte), "1000 MB"},
|
||||
|
||||
{"bytes(1GB)", Bytes(GByte), "1.0 GB"},
|
||||
{"bytes(1TB - 1M)", Bytes(TByte - MByte), "1000 GB"},
|
||||
{"bytes(10MB)", Bytes(9999 * 1000), "10 MB"},
|
||||
|
||||
{"bytes(1TB)", Bytes(TByte), "1.0 TB"},
|
||||
{"bytes(1PB - 1T)", Bytes(PByte - TByte), "999 TB"},
|
||||
|
||||
{"bytes(1PB)", Bytes(PByte), "1.0 PB"},
|
||||
{"bytes(1PB - 1T)", Bytes(EByte - PByte), "999 PB"},
|
||||
|
||||
{"bytes(1EB)", Bytes(EByte), "1.0 EB"},
|
||||
// Overflows.
|
||||
// {"bytes(1EB - 1P)", Bytes((KByte*EByte)-PByte), "1023EB"},
|
||||
|
||||
{"bytes(0)", IBytes(0), "0 B"},
|
||||
{"bytes(1)", IBytes(1), "1 B"},
|
||||
{"bytes(803)", IBytes(803), "803 B"},
|
||||
{"bytes(1023)", IBytes(1023), "1023 B"},
|
||||
|
||||
{"bytes(1024)", IBytes(1024), "1.0 KiB"},
|
||||
{"bytes(1MB - 1)", IBytes(MiByte - IByte), "1024 KiB"},
|
||||
|
||||
{"bytes(1MB)", IBytes(1024 * 1024), "1.0 MiB"},
|
||||
{"bytes(1GB - 1K)", IBytes(GiByte - KiByte), "1024 MiB"},
|
||||
|
||||
{"bytes(1GB)", IBytes(GiByte), "1.0 GiB"},
|
||||
{"bytes(1TB - 1M)", IBytes(TiByte - MiByte), "1024 GiB"},
|
||||
|
||||
{"bytes(1TB)", IBytes(TiByte), "1.0 TiB"},
|
||||
{"bytes(1PB - 1T)", IBytes(PiByte - TiByte), "1023 TiB"},
|
||||
|
||||
{"bytes(1PB)", IBytes(PiByte), "1.0 PiB"},
|
||||
{"bytes(1PB - 1T)", IBytes(EiByte - PiByte), "1023 PiB"},
|
||||
|
||||
{"bytes(1EiB)", IBytes(EiByte), "1.0 EiB"},
|
||||
// Overflows.
|
||||
// {"bytes(1EB - 1P)", IBytes((KIByte*EIByte)-PiByte), "1023EB"},
|
||||
|
||||
{"bytes(5.5GiB)", IBytes(5.5 * GiByte), "5.5 GiB"},
|
||||
|
||||
{"bytes(5.5GB)", Bytes(5.5 * GByte), "5.5 GB"},
|
||||
}.validate(t)
|
||||
}
|
||||
|
||||
func BenchmarkParseBytes(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
ParseBytes("16.5 GB")
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkBytes(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
Bytes(16.5 * GByte)
|
||||
}
|
||||
}
|
136
vendor/github.com/dustin/go-humanize/comma_test.go
generated
vendored
136
vendor/github.com/dustin/go-humanize/comma_test.go
generated
vendored
|
@ -1,136 +0,0 @@
|
|||
package humanize
|
||||
|
||||
import (
|
||||
"math"
|
||||
"math/big"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestCommas(t *testing.T) {
|
||||
testList{
|
||||
{"0", Comma(0), "0"},
|
||||
{"10", Comma(10), "10"},
|
||||
{"100", Comma(100), "100"},
|
||||
{"1,000", Comma(1000), "1,000"},
|
||||
{"10,000", Comma(10000), "10,000"},
|
||||
{"100,000", Comma(100000), "100,000"},
|
||||
{"10,000,000", Comma(10000000), "10,000,000"},
|
||||
{"10,100,000", Comma(10100000), "10,100,000"},
|
||||
{"10,010,000", Comma(10010000), "10,010,000"},
|
||||
{"10,001,000", Comma(10001000), "10,001,000"},
|
||||
{"123,456,789", Comma(123456789), "123,456,789"},
|
||||
{"maxint", Comma(9.223372e+18), "9,223,372,000,000,000,000"},
|
||||
{"math.maxint", Comma(math.MaxInt64), "9,223,372,036,854,775,807"},
|
||||
{"math.minint", Comma(math.MinInt64), "-9,223,372,036,854,775,808"},
|
||||
{"minint", Comma(-9.223372e+18), "-9,223,372,000,000,000,000"},
|
||||
{"-123,456,789", Comma(-123456789), "-123,456,789"},
|
||||
{"-10,100,000", Comma(-10100000), "-10,100,000"},
|
||||
{"-10,010,000", Comma(-10010000), "-10,010,000"},
|
||||
{"-10,001,000", Comma(-10001000), "-10,001,000"},
|
||||
{"-10,000,000", Comma(-10000000), "-10,000,000"},
|
||||
{"-100,000", Comma(-100000), "-100,000"},
|
||||
{"-10,000", Comma(-10000), "-10,000"},
|
||||
{"-1,000", Comma(-1000), "-1,000"},
|
||||
{"-100", Comma(-100), "-100"},
|
||||
{"-10", Comma(-10), "-10"},
|
||||
}.validate(t)
|
||||
}
|
||||
|
||||
func TestCommafs(t *testing.T) {
|
||||
testList{
|
||||
{"0", Commaf(0), "0"},
|
||||
{"10.11", Commaf(10.11), "10.11"},
|
||||
{"100", Commaf(100), "100"},
|
||||
{"1,000", Commaf(1000), "1,000"},
|
||||
{"10,000", Commaf(10000), "10,000"},
|
||||
{"100,000", Commaf(100000), "100,000"},
|
||||
{"834,142.32", Commaf(834142.32), "834,142.32"},
|
||||
{"10,000,000", Commaf(10000000), "10,000,000"},
|
||||
{"10,100,000", Commaf(10100000), "10,100,000"},
|
||||
{"10,010,000", Commaf(10010000), "10,010,000"},
|
||||
{"10,001,000", Commaf(10001000), "10,001,000"},
|
||||
{"123,456,789", Commaf(123456789), "123,456,789"},
|
||||
{"maxf64", Commaf(math.MaxFloat64), "179,769,313,486,231,570,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000"},
|
||||
{"minf64", Commaf(math.SmallestNonzeroFloat64), "0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005"},
|
||||
{"-123,456,789", Commaf(-123456789), "-123,456,789"},
|
||||
{"-10,100,000", Commaf(-10100000), "-10,100,000"},
|
||||
{"-10,010,000", Commaf(-10010000), "-10,010,000"},
|
||||
{"-10,001,000", Commaf(-10001000), "-10,001,000"},
|
||||
{"-10,000,000", Commaf(-10000000), "-10,000,000"},
|
||||
{"-100,000", Commaf(-100000), "-100,000"},
|
||||
{"-10,000", Commaf(-10000), "-10,000"},
|
||||
{"-1,000", Commaf(-1000), "-1,000"},
|
||||
{"-100.11", Commaf(-100.11), "-100.11"},
|
||||
{"-10", Commaf(-10), "-10"},
|
||||
}.validate(t)
|
||||
}
|
||||
|
||||
func BenchmarkCommas(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
Comma(1234567890)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkCommaf(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
Commaf(1234567890.83584)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkBigCommas(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
BigComma(big.NewInt(1234567890))
|
||||
}
|
||||
}
|
||||
|
||||
func bigComma(i int64) string {
|
||||
return BigComma(big.NewInt(i))
|
||||
}
|
||||
|
||||
func TestBigCommas(t *testing.T) {
|
||||
testList{
|
||||
{"0", bigComma(0), "0"},
|
||||
{"10", bigComma(10), "10"},
|
||||
{"100", bigComma(100), "100"},
|
||||
{"1,000", bigComma(1000), "1,000"},
|
||||
{"10,000", bigComma(10000), "10,000"},
|
||||
{"100,000", bigComma(100000), "100,000"},
|
||||
{"10,000,000", bigComma(10000000), "10,000,000"},
|
||||
{"10,100,000", bigComma(10100000), "10,100,000"},
|
||||
{"10,010,000", bigComma(10010000), "10,010,000"},
|
||||
{"10,001,000", bigComma(10001000), "10,001,000"},
|
||||
{"123,456,789", bigComma(123456789), "123,456,789"},
|
||||
{"maxint", bigComma(9.223372e+18), "9,223,372,000,000,000,000"},
|
||||
{"minint", bigComma(-9.223372e+18), "-9,223,372,000,000,000,000"},
|
||||
{"-123,456,789", bigComma(-123456789), "-123,456,789"},
|
||||
{"-10,100,000", bigComma(-10100000), "-10,100,000"},
|
||||
{"-10,010,000", bigComma(-10010000), "-10,010,000"},
|
||||
{"-10,001,000", bigComma(-10001000), "-10,001,000"},
|
||||
{"-10,000,000", bigComma(-10000000), "-10,000,000"},
|
||||
{"-100,000", bigComma(-100000), "-100,000"},
|
||||
{"-10,000", bigComma(-10000), "-10,000"},
|
||||
{"-1,000", bigComma(-1000), "-1,000"},
|
||||
{"-100", bigComma(-100), "-100"},
|
||||
{"-10", bigComma(-10), "-10"},
|
||||
}.validate(t)
|
||||
}
|
||||
|
||||
func TestVeryBigCommas(t *testing.T) {
|
||||
tests := []struct{ in, exp string }{
|
||||
{
|
||||
"84889279597249724975972597249849757294578485",
|
||||
"84,889,279,597,249,724,975,972,597,249,849,757,294,578,485",
|
||||
},
|
||||
{
|
||||
"-84889279597249724975972597249849757294578485",
|
||||
"-84,889,279,597,249,724,975,972,597,249,849,757,294,578,485",
|
||||
},
|
||||
}
|
||||
for _, test := range tests {
|
||||
n, _ := (&big.Int{}).SetString(test.in, 10)
|
||||
got := BigComma(n)
|
||||
if test.exp != got {
|
||||
t.Errorf("Expected %q, got %q", test.exp, got)
|
||||
}
|
||||
}
|
||||
}
|
44
vendor/github.com/dustin/go-humanize/commaf_test.go
generated
vendored
44
vendor/github.com/dustin/go-humanize/commaf_test.go
generated
vendored
|
@ -1,44 +0,0 @@
|
|||
// +build go1.6
|
||||
|
||||
package humanize
|
||||
|
||||
import (
|
||||
"math"
|
||||
"math/big"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func BenchmarkBigCommaf(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
Commaf(1234567890.83584)
|
||||
}
|
||||
}
|
||||
|
||||
func TestBigCommafs(t *testing.T) {
|
||||
testList{
|
||||
{"0", BigCommaf(big.NewFloat(0)), "0"},
|
||||
{"10.11", BigCommaf(big.NewFloat(10.11)), "10.11"},
|
||||
{"100", BigCommaf(big.NewFloat(100)), "100"},
|
||||
{"1,000", BigCommaf(big.NewFloat(1000)), "1,000"},
|
||||
{"10,000", BigCommaf(big.NewFloat(10000)), "10,000"},
|
||||
{"100,000", BigCommaf(big.NewFloat(100000)), "100,000"},
|
||||
{"834,142.32", BigCommaf(big.NewFloat(834142.32)), "834,142.32"},
|
||||
{"10,000,000", BigCommaf(big.NewFloat(10000000)), "10,000,000"},
|
||||
{"10,100,000", BigCommaf(big.NewFloat(10100000)), "10,100,000"},
|
||||
{"10,010,000", BigCommaf(big.NewFloat(10010000)), "10,010,000"},
|
||||
{"10,001,000", BigCommaf(big.NewFloat(10001000)), "10,001,000"},
|
||||
{"123,456,789", BigCommaf(big.NewFloat(123456789)), "123,456,789"},
|
||||
{"maxf64", BigCommaf(big.NewFloat(math.MaxFloat64)), "179,769,313,486,231,570,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000"},
|
||||
{"minf64", BigCommaf(big.NewFloat(math.SmallestNonzeroFloat64)), "0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004940656458412465"},
|
||||
{"-123,456,789", BigCommaf(big.NewFloat(-123456789)), "-123,456,789"},
|
||||
{"-10,100,000", BigCommaf(big.NewFloat(-10100000)), "-10,100,000"},
|
||||
{"-10,010,000", BigCommaf(big.NewFloat(-10010000)), "-10,010,000"},
|
||||
{"-10,001,000", BigCommaf(big.NewFloat(-10001000)), "-10,001,000"},
|
||||
{"-10,000,000", BigCommaf(big.NewFloat(-10000000)), "-10,000,000"},
|
||||
{"-100,000", BigCommaf(big.NewFloat(-100000)), "-100,000"},
|
||||
{"-10,000", BigCommaf(big.NewFloat(-10000)), "-10,000"},
|
||||
{"-1,000", BigCommaf(big.NewFloat(-1000)), "-1,000"},
|
||||
{"-100.11", BigCommaf(big.NewFloat(-100.11)), "-100.11"},
|
||||
{"-10", BigCommaf(big.NewFloat(-10)), "-10"},
|
||||
}.validate(t)
|
||||
}
|
18
vendor/github.com/dustin/go-humanize/common_test.go
generated
vendored
18
vendor/github.com/dustin/go-humanize/common_test.go
generated
vendored
|
@ -1,18 +0,0 @@
|
|||
package humanize
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
type testList []struct {
|
||||
name, got, exp string
|
||||
}
|
||||
|
||||
func (tl testList) validate(t *testing.T) {
|
||||
for _, test := range tl {
|
||||
if test.got != test.exp {
|
||||
t.Errorf("On %v, expected '%v', but got '%v'",
|
||||
test.name, test.exp, test.got)
|
||||
}
|
||||
}
|
||||
}
|
96
vendor/github.com/dustin/go-humanize/english/words.go
generated
vendored
96
vendor/github.com/dustin/go-humanize/english/words.go
generated
vendored
|
@ -1,96 +0,0 @@
|
|||
// Package english provides utilities to generate more user-friendly English output.
|
||||
package english
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// These are included because they are common technical terms.
|
||||
var specialPlurals = map[string]string{
|
||||
"index": "indices",
|
||||
"matrix": "matrices",
|
||||
"vertex": "vertices",
|
||||
}
|
||||
|
||||
var sibilantEndings = []string{"s", "sh", "tch", "x"}
|
||||
|
||||
var isVowel = map[byte]bool{
|
||||
'A': true, 'E': true, 'I': true, 'O': true, 'U': true,
|
||||
'a': true, 'e': true, 'i': true, 'o': true, 'u': true,
|
||||
}
|
||||
|
||||
// PluralWord builds the plural form of an English word.
|
||||
// The simple English rules of regular pluralization will be used
|
||||
// if the plural form is an empty string (i.e. not explicitly given).
|
||||
// The special cases are not guaranteed to work for strings outside ASCII.
|
||||
func PluralWord(quantity int, singular, plural string) string {
|
||||
if quantity == 1 {
|
||||
return singular
|
||||
}
|
||||
if plural != "" {
|
||||
return plural
|
||||
}
|
||||
if plural = specialPlurals[singular]; plural != "" {
|
||||
return plural
|
||||
}
|
||||
|
||||
// We need to guess what the English plural might be. Keep this
|
||||
// function simple! It doesn't need to know about every possiblity;
|
||||
// only regular rules and the most common special cases.
|
||||
//
|
||||
// Reference: http://en.wikipedia.org/wiki/English_plural
|
||||
|
||||
for _, ending := range sibilantEndings {
|
||||
if strings.HasSuffix(singular, ending) {
|
||||
return singular + "es"
|
||||
}
|
||||
}
|
||||
l := len(singular)
|
||||
if l >= 2 && singular[l-1] == 'o' && !isVowel[singular[l-2]] {
|
||||
return singular + "es"
|
||||
}
|
||||
if l >= 2 && singular[l-1] == 'y' && !isVowel[singular[l-2]] {
|
||||
return singular[:l-1] + "ies"
|
||||
}
|
||||
|
||||
return singular + "s"
|
||||
}
|
||||
|
||||
// Plural formats an integer and a string into a single pluralized string.
|
||||
// The simple English rules of regular pluralization will be used
|
||||
// if the plural form is an empty string (i.e. not explicitly given).
|
||||
func Plural(quantity int, singular, plural string) string {
|
||||
return fmt.Sprintf("%d %s", quantity, PluralWord(quantity, singular, plural))
|
||||
}
|
||||
|
||||
// WordSeries converts a list of words into a word series in English.
|
||||
// It returns a string containing all the given words separated by commas,
|
||||
// the coordinating conjunction, and a serial comma, as appropriate.
|
||||
func WordSeries(words []string, conjunction string) string {
|
||||
switch len(words) {
|
||||
case 0:
|
||||
return ""
|
||||
case 1:
|
||||
return words[0]
|
||||
default:
|
||||
return fmt.Sprintf("%s %s %s", strings.Join(words[:len(words)-1], ", "), conjunction, words[len(words)-1])
|
||||
}
|
||||
}
|
||||
|
||||
// OxfordWordSeries converts a list of words into a word series in English,
|
||||
// using an Oxford comma (https://en.wikipedia.org/wiki/Serial_comma). It
|
||||
// returns a string containing all the given words separated by commas, the
|
||||
// coordinating conjunction, and a serial comma, as appropriate.
|
||||
func OxfordWordSeries(words []string, conjunction string) string {
|
||||
switch len(words) {
|
||||
case 0:
|
||||
return ""
|
||||
case 1:
|
||||
return words[0]
|
||||
case 2:
|
||||
return strings.Join(words, fmt.Sprintf(" %s ", conjunction))
|
||||
default:
|
||||
return fmt.Sprintf("%s, %s %s", strings.Join(words[:len(words)-1], ", "), conjunction, words[len(words)-1])
|
||||
}
|
||||
}
|
94
vendor/github.com/dustin/go-humanize/english/words_test.go
generated
vendored
94
vendor/github.com/dustin/go-humanize/english/words_test.go
generated
vendored
|
@ -1,94 +0,0 @@
|
|||
package english
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestPluralWord(t *testing.T) {
|
||||
tests := []struct {
|
||||
n int
|
||||
singular, plural string
|
||||
want string
|
||||
}{
|
||||
{0, "object", "", "objects"},
|
||||
{1, "object", "", "object"},
|
||||
{-1, "object", "", "objects"},
|
||||
{42, "object", "", "objects"},
|
||||
{2, "vax", "vaxen", "vaxen"},
|
||||
|
||||
// special cases
|
||||
{2, "index", "", "indices"},
|
||||
|
||||
// ending in a sibilant sound
|
||||
{2, "bus", "", "buses"},
|
||||
{2, "bush", "", "bushes"},
|
||||
{2, "watch", "", "watches"},
|
||||
{2, "box", "", "boxes"},
|
||||
|
||||
// ending with 'o' preceded by a consonant
|
||||
{2, "hero", "", "heroes"},
|
||||
|
||||
// ending with 'y' preceded by a consonant
|
||||
{2, "lady", "", "ladies"},
|
||||
{2, "day", "", "days"},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
if got := PluralWord(tt.n, tt.singular, tt.plural); got != tt.want {
|
||||
t.Errorf("PluralWord(%d, %q, %q)=%q; want: %q", tt.n, tt.singular, tt.plural, got, tt.want)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestPlural(t *testing.T) {
|
||||
tests := []struct {
|
||||
n int
|
||||
singular, plural string
|
||||
want string
|
||||
}{
|
||||
{1, "object", "", "1 object"},
|
||||
{42, "object", "", "42 objects"},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
if got := Plural(tt.n, tt.singular, tt.plural); got != tt.want {
|
||||
t.Errorf("Plural(%d, %q, %q)=%q; want: %q", tt.n, tt.singular, tt.plural, got, tt.want)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestWordSeries(t *testing.T) {
|
||||
tests := []struct {
|
||||
words []string
|
||||
conjunction string
|
||||
want string
|
||||
}{
|
||||
{[]string{}, "and", ""},
|
||||
{[]string{"foo"}, "and", "foo"},
|
||||
{[]string{"foo", "bar"}, "and", "foo and bar"},
|
||||
{[]string{"foo", "bar", "baz"}, "and", "foo, bar and baz"},
|
||||
{[]string{"foo", "bar", "baz"}, "or", "foo, bar or baz"},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
if got := WordSeries(tt.words, tt.conjunction); got != tt.want {
|
||||
t.Errorf("WordSeries(%q, %q)=%q; want: %q", tt.words, tt.conjunction, got, tt.want)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestOxfordWordSeries(t *testing.T) {
|
||||
tests := []struct {
|
||||
words []string
|
||||
conjunction string
|
||||
want string
|
||||
}{
|
||||
{[]string{}, "and", ""},
|
||||
{[]string{"foo"}, "and", "foo"},
|
||||
{[]string{"foo", "bar"}, "and", "foo and bar"},
|
||||
{[]string{"foo", "bar", "baz"}, "and", "foo, bar, and baz"},
|
||||
{[]string{"foo", "bar", "baz"}, "or", "foo, bar, or baz"},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
if got := OxfordWordSeries(tt.words, tt.conjunction); got != tt.want {
|
||||
t.Errorf("OxfordWordSeries(%q, %q)=%q; want: %q", tt.words, tt.conjunction, got, tt.want)
|
||||
}
|
||||
}
|
||||
}
|
55
vendor/github.com/dustin/go-humanize/ftoa_test.go
generated
vendored
55
vendor/github.com/dustin/go-humanize/ftoa_test.go
generated
vendored
|
@ -1,55 +0,0 @@
|
|||
package humanize
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestFtoa(t *testing.T) {
|
||||
testList{
|
||||
{"200", Ftoa(200), "200"},
|
||||
{"2", Ftoa(2), "2"},
|
||||
{"2.2", Ftoa(2.2), "2.2"},
|
||||
{"2.02", Ftoa(2.02), "2.02"},
|
||||
{"200.02", Ftoa(200.02), "200.02"},
|
||||
}.validate(t)
|
||||
}
|
||||
|
||||
func BenchmarkFtoaRegexTrailing(b *testing.B) {
|
||||
trailingZerosRegex := regexp.MustCompile(`\.?0+$`)
|
||||
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
trailingZerosRegex.ReplaceAllString("2.00000", "")
|
||||
trailingZerosRegex.ReplaceAllString("2.0000", "")
|
||||
trailingZerosRegex.ReplaceAllString("2.000", "")
|
||||
trailingZerosRegex.ReplaceAllString("2.00", "")
|
||||
trailingZerosRegex.ReplaceAllString("2.0", "")
|
||||
trailingZerosRegex.ReplaceAllString("2", "")
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkFtoaFunc(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
stripTrailingZeros("2.00000")
|
||||
stripTrailingZeros("2.0000")
|
||||
stripTrailingZeros("2.000")
|
||||
stripTrailingZeros("2.00")
|
||||
stripTrailingZeros("2.0")
|
||||
stripTrailingZeros("2")
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkFmtF(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
_ = fmt.Sprintf("%f", 2.03584)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkStrconvF(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
strconv.FormatFloat(2.03584, 'f', 6, 64)
|
||||
}
|
||||
}
|
79
vendor/github.com/dustin/go-humanize/number_test.go
generated
vendored
79
vendor/github.com/dustin/go-humanize/number_test.go
generated
vendored
|
@ -1,79 +0,0 @@
|
|||
package humanize
|
||||
|
||||
import (
|
||||
"math"
|
||||
"testing"
|
||||
)
|
||||
|
||||
type TestStruct struct {
|
||||
name string
|
||||
format string
|
||||
num float64
|
||||
formatted string
|
||||
}
|
||||
|
||||
func TestFormatFloat(t *testing.T) {
|
||||
tests := []TestStruct{
|
||||
{"default", "", 12345.6789, "12,345.68"},
|
||||
{"#", "#", 12345.6789, "12345.678900000"},
|
||||
{"#.", "#.", 12345.6789, "12346"},
|
||||
{"#,#", "#,#", 12345.6789, "12345,7"},
|
||||
{"#,##", "#,##", 12345.6789, "12345,68"},
|
||||
{"#,###", "#,###", 12345.6789, "12345,679"},
|
||||
{"#,###.", "#,###.", 12345.6789, "12,346"},
|
||||
{"#,###.##", "#,###.##", 12345.6789, "12,345.68"},
|
||||
{"#,###.###", "#,###.###", 12345.6789, "12,345.679"},
|
||||
{"#,###.####", "#,###.####", 12345.6789, "12,345.6789"},
|
||||
{"#.###,######", "#.###,######", 12345.6789, "12.345,678900"},
|
||||
{"bug46", "#,###.##", 52746220055.92342, "52,746,220,055.92"},
|
||||
{"#\u202f###,##", "#\u202f###,##", 12345.6789, "12 345,68"},
|
||||
|
||||
// special cases
|
||||
{"NaN", "#", math.NaN(), "NaN"},
|
||||
{"+Inf", "#", math.Inf(1), "Infinity"},
|
||||
{"-Inf", "#", math.Inf(-1), "-Infinity"},
|
||||
{"signStr <= -0.000000001", "", -0.000000002, "-0.00"},
|
||||
{"signStr = 0", "", 0, "0.00"},
|
||||
{"Format directive must start with +", "+000", 12345.6789, "+12345.678900000"},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
got := FormatFloat(test.format, test.num)
|
||||
if got != test.formatted {
|
||||
t.Errorf("On %v (%v, %v), got %v, wanted %v",
|
||||
test.name, test.format, test.num, got, test.formatted)
|
||||
}
|
||||
}
|
||||
// Test a single integer
|
||||
got := FormatInteger("#", 12345)
|
||||
if got != "12345.000000000" {
|
||||
t.Errorf("On %v (%v, %v), got %v, wanted %v",
|
||||
"integerTest", "#", 12345, got, "12345.000000000")
|
||||
}
|
||||
// Test the things that could panic
|
||||
panictests := []TestStruct{
|
||||
{"RenderFloat(): invalid positive sign directive", "-", 12345.6789, "12,345.68"},
|
||||
{"RenderFloat(): thousands separator directive must be followed by 3 digit-specifiers", "0.01", 12345.6789, "12,345.68"},
|
||||
}
|
||||
for _, test := range panictests {
|
||||
didPanic := false
|
||||
var message interface{}
|
||||
func() {
|
||||
|
||||
defer func() {
|
||||
if message = recover(); message != nil {
|
||||
didPanic = true
|
||||
}
|
||||
}()
|
||||
|
||||
// call the target function
|
||||
_ = FormatFloat(test.format, test.num)
|
||||
|
||||
}()
|
||||
if didPanic != true {
|
||||
t.Errorf("On %v, should have panic and did not.",
|
||||
test.name)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
22
vendor/github.com/dustin/go-humanize/ordinals_test.go
generated
vendored
22
vendor/github.com/dustin/go-humanize/ordinals_test.go
generated
vendored
|
@ -1,22 +0,0 @@
|
|||
package humanize
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestOrdinals(t *testing.T) {
|
||||
testList{
|
||||
{"0", Ordinal(0), "0th"},
|
||||
{"1", Ordinal(1), "1st"},
|
||||
{"2", Ordinal(2), "2nd"},
|
||||
{"3", Ordinal(3), "3rd"},
|
||||
{"4", Ordinal(4), "4th"},
|
||||
{"10", Ordinal(10), "10th"},
|
||||
{"11", Ordinal(11), "11th"},
|
||||
{"12", Ordinal(12), "12th"},
|
||||
{"13", Ordinal(13), "13th"},
|
||||
{"101", Ordinal(101), "101st"},
|
||||
{"102", Ordinal(102), "102nd"},
|
||||
{"103", Ordinal(103), "103rd"},
|
||||
}.validate(t)
|
||||
}
|
101
vendor/github.com/dustin/go-humanize/si_test.go
generated
vendored
101
vendor/github.com/dustin/go-humanize/si_test.go
generated
vendored
|
@ -1,101 +0,0 @@
|
|||
package humanize
|
||||
|
||||
import (
|
||||
"math"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestSI(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
num float64
|
||||
formatted string
|
||||
}{
|
||||
{"e-24", 1e-24, "1 yF"},
|
||||
{"e-21", 1e-21, "1 zF"},
|
||||
{"e-18", 1e-18, "1 aF"},
|
||||
{"e-15", 1e-15, "1 fF"},
|
||||
{"e-12", 1e-12, "1 pF"},
|
||||
{"e-12", 2.2345e-12, "2.2345 pF"},
|
||||
{"e-12", 2.23e-12, "2.23 pF"},
|
||||
{"e-11", 2.23e-11, "22.3 pF"},
|
||||
{"e-10", 2.2e-10, "220 pF"},
|
||||
{"e-9", 2.2e-9, "2.2 nF"},
|
||||
{"e-8", 2.2e-8, "22 nF"},
|
||||
{"e-7", 2.2e-7, "220 nF"},
|
||||
{"e-6", 2.2e-6, "2.2 µF"},
|
||||
{"e-6", 1e-6, "1 µF"},
|
||||
{"e-5", 2.2e-5, "22 µF"},
|
||||
{"e-4", 2.2e-4, "220 µF"},
|
||||
{"e-3", 2.2e-3, "2.2 mF"},
|
||||
{"e-2", 2.2e-2, "22 mF"},
|
||||
{"e-1", 2.2e-1, "220 mF"},
|
||||
{"e+0", 2.2e-0, "2.2 F"},
|
||||
{"e+0", 2.2, "2.2 F"},
|
||||
{"e+1", 2.2e+1, "22 F"},
|
||||
{"0", 0, "0 F"},
|
||||
{"e+1", 22, "22 F"},
|
||||
{"e+2", 2.2e+2, "220 F"},
|
||||
{"e+2", 220, "220 F"},
|
||||
{"e+3", 2.2e+3, "2.2 kF"},
|
||||
{"e+3", 2200, "2.2 kF"},
|
||||
{"e+4", 2.2e+4, "22 kF"},
|
||||
{"e+4", 22000, "22 kF"},
|
||||
{"e+5", 2.2e+5, "220 kF"},
|
||||
{"e+6", 2.2e+6, "2.2 MF"},
|
||||
{"e+6", 1e+6, "1 MF"},
|
||||
{"e+7", 2.2e+7, "22 MF"},
|
||||
{"e+8", 2.2e+8, "220 MF"},
|
||||
{"e+9", 2.2e+9, "2.2 GF"},
|
||||
{"e+10", 2.2e+10, "22 GF"},
|
||||
{"e+11", 2.2e+11, "220 GF"},
|
||||
{"e+12", 2.2e+12, "2.2 TF"},
|
||||
{"e+15", 2.2e+15, "2.2 PF"},
|
||||
{"e+18", 2.2e+18, "2.2 EF"},
|
||||
{"e+21", 2.2e+21, "2.2 ZF"},
|
||||
{"e+24", 2.2e+24, "2.2 YF"},
|
||||
|
||||
// special case
|
||||
{"1F", 1000 * 1000, "1 MF"},
|
||||
{"1F", 1e6, "1 MF"},
|
||||
|
||||
// negative number
|
||||
{"-100 F", -100, "-100 F"},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
got := SI(test.num, "F")
|
||||
if got != test.formatted {
|
||||
t.Errorf("On %v (%v), got %v, wanted %v",
|
||||
test.name, test.num, got, test.formatted)
|
||||
}
|
||||
|
||||
gotf, gotu, err := ParseSI(test.formatted)
|
||||
if err != nil {
|
||||
t.Errorf("Error parsing %v (%v): %v", test.name, test.formatted, err)
|
||||
continue
|
||||
}
|
||||
|
||||
if math.Abs(1-(gotf/test.num)) > 0.01 {
|
||||
t.Errorf("On %v (%v), got %v, wanted %v (±%v)",
|
||||
test.name, test.formatted, gotf, test.num,
|
||||
math.Abs(1-(gotf/test.num)))
|
||||
}
|
||||
if gotu != "F" {
|
||||
t.Errorf("On %v (%v), expected unit F, got %v",
|
||||
test.name, test.formatted, gotu)
|
||||
}
|
||||
}
|
||||
|
||||
// Parse error
|
||||
gotf, gotu, err := ParseSI("x1.21JW") // 1.21 jigga whats
|
||||
if err == nil {
|
||||
t.Errorf("Expected error on x1.21JW, got %v %v", gotf, gotu)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkParseSI(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
ParseSI("2.2346ZB")
|
||||
}
|
||||
}
|
124
vendor/github.com/dustin/go-humanize/times_test.go
generated
vendored
124
vendor/github.com/dustin/go-humanize/times_test.go
generated
vendored
|
@ -1,124 +0,0 @@
|
|||
package humanize
|
||||
|
||||
import (
|
||||
"math"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestPast(t *testing.T) {
|
||||
now := time.Now()
|
||||
testList{
|
||||
{"now", Time(now), "now"},
|
||||
{"1 second ago", Time(now.Add(-1 * time.Second)), "1 second ago"},
|
||||
{"12 seconds ago", Time(now.Add(-12 * time.Second)), "12 seconds ago"},
|
||||
{"30 seconds ago", Time(now.Add(-30 * time.Second)), "30 seconds ago"},
|
||||
{"45 seconds ago", Time(now.Add(-45 * time.Second)), "45 seconds ago"},
|
||||
{"1 minute ago", Time(now.Add(-63 * time.Second)), "1 minute ago"},
|
||||
{"15 minutes ago", Time(now.Add(-15 * time.Minute)), "15 minutes ago"},
|
||||
{"1 hour ago", Time(now.Add(-63 * time.Minute)), "1 hour ago"},
|
||||
{"2 hours ago", Time(now.Add(-2 * time.Hour)), "2 hours ago"},
|
||||
{"21 hours ago", Time(now.Add(-21 * time.Hour)), "21 hours ago"},
|
||||
{"1 day ago", Time(now.Add(-26 * time.Hour)), "1 day ago"},
|
||||
{"2 days ago", Time(now.Add(-49 * time.Hour)), "2 days ago"},
|
||||
{"3 days ago", Time(now.Add(-3 * Day)), "3 days ago"},
|
||||
{"1 week ago (1)", Time(now.Add(-7 * Day)), "1 week ago"},
|
||||
{"1 week ago (2)", Time(now.Add(-12 * Day)), "1 week ago"},
|
||||
{"2 weeks ago", Time(now.Add(-15 * Day)), "2 weeks ago"},
|
||||
{"1 month ago", Time(now.Add(-39 * Day)), "1 month ago"},
|
||||
{"3 months ago", Time(now.Add(-99 * Day)), "3 months ago"},
|
||||
{"1 year ago (1)", Time(now.Add(-365 * Day)), "1 year ago"},
|
||||
{"1 year ago (1)", Time(now.Add(-400 * Day)), "1 year ago"},
|
||||
{"2 years ago (1)", Time(now.Add(-548 * Day)), "2 years ago"},
|
||||
{"2 years ago (2)", Time(now.Add(-725 * Day)), "2 years ago"},
|
||||
{"2 years ago (3)", Time(now.Add(-800 * Day)), "2 years ago"},
|
||||
{"3 years ago", Time(now.Add(-3 * Year)), "3 years ago"},
|
||||
{"long ago", Time(now.Add(-LongTime)), "a long while ago"},
|
||||
}.validate(t)
|
||||
}
|
||||
|
||||
func TestReltimeOffbyone(t *testing.T) {
|
||||
testList{
|
||||
{"1w-1", RelTime(time.Unix(0, 0), time.Unix(7*24*60*60, -1), "ago", ""), "6 days ago"},
|
||||
{"1w±0", RelTime(time.Unix(0, 0), time.Unix(7*24*60*60, 0), "ago", ""), "1 week ago"},
|
||||
{"1w+1", RelTime(time.Unix(0, 0), time.Unix(7*24*60*60, 1), "ago", ""), "1 week ago"},
|
||||
{"2w-1", RelTime(time.Unix(0, 0), time.Unix(14*24*60*60, -1), "ago", ""), "1 week ago"},
|
||||
{"2w±0", RelTime(time.Unix(0, 0), time.Unix(14*24*60*60, 0), "ago", ""), "2 weeks ago"},
|
||||
{"2w+1", RelTime(time.Unix(0, 0), time.Unix(14*24*60*60, 1), "ago", ""), "2 weeks ago"},
|
||||
}.validate(t)
|
||||
}
|
||||
|
||||
func TestFuture(t *testing.T) {
|
||||
// Add a little time so that these things properly line up in
|
||||
// the future.
|
||||
now := time.Now().Add(time.Millisecond * 250)
|
||||
testList{
|
||||
{"now", Time(now), "now"},
|
||||
{"1 second from now", Time(now.Add(+1 * time.Second)), "1 second from now"},
|
||||
{"12 seconds from now", Time(now.Add(+12 * time.Second)), "12 seconds from now"},
|
||||
{"30 seconds from now", Time(now.Add(+30 * time.Second)), "30 seconds from now"},
|
||||
{"45 seconds from now", Time(now.Add(+45 * time.Second)), "45 seconds from now"},
|
||||
{"15 minutes from now", Time(now.Add(+15 * time.Minute)), "15 minutes from now"},
|
||||
{"2 hours from now", Time(now.Add(+2 * time.Hour)), "2 hours from now"},
|
||||
{"21 hours from now", Time(now.Add(+21 * time.Hour)), "21 hours from now"},
|
||||
{"1 day from now", Time(now.Add(+26 * time.Hour)), "1 day from now"},
|
||||
{"2 days from now", Time(now.Add(+49 * time.Hour)), "2 days from now"},
|
||||
{"3 days from now", Time(now.Add(+3 * Day)), "3 days from now"},
|
||||
{"1 week from now (1)", Time(now.Add(+7 * Day)), "1 week from now"},
|
||||
{"1 week from now (2)", Time(now.Add(+12 * Day)), "1 week from now"},
|
||||
{"2 weeks from now", Time(now.Add(+15 * Day)), "2 weeks from now"},
|
||||
{"1 month from now", Time(now.Add(+30 * Day)), "1 month from now"},
|
||||
{"1 year from now", Time(now.Add(+365 * Day)), "1 year from now"},
|
||||
{"2 years from now", Time(now.Add(+2 * Year)), "2 years from now"},
|
||||
{"a while from now", Time(now.Add(+LongTime)), "a long while from now"},
|
||||
}.validate(t)
|
||||
}
|
||||
|
||||
func TestRange(t *testing.T) {
|
||||
start := time.Time{}
|
||||
end := time.Unix(math.MaxInt64, math.MaxInt64)
|
||||
x := RelTime(start, end, "ago", "from now")
|
||||
if x != "a long while from now" {
|
||||
t.Errorf("Expected a long while from now, got %q", x)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCustomRelTime(t *testing.T) {
|
||||
now := time.Now().Add(time.Millisecond * 250)
|
||||
magnitudes := []RelTimeMagnitude{
|
||||
{time.Second, "now", time.Second},
|
||||
{2 * time.Second, "1 second %s", 1},
|
||||
{time.Minute, "%d seconds %s", time.Second},
|
||||
{Day - time.Second, "%d minutes %s", time.Minute},
|
||||
{Day, "%d hours %s", time.Hour},
|
||||
{2 * Day, "1 day %s", 1},
|
||||
{Week, "%d days %s", Day},
|
||||
{2 * Week, "1 week %s", 1},
|
||||
{6 * Month, "%d weeks %s", Week},
|
||||
{Year, "%d months %s", Month},
|
||||
}
|
||||
customRelTime := func(then time.Time) string {
|
||||
return CustomRelTime(then, time.Now(), "ago", "from now", magnitudes)
|
||||
}
|
||||
testList{
|
||||
{"now", customRelTime(now), "now"},
|
||||
{"1 second from now", customRelTime(now.Add(+1 * time.Second)), "1 second from now"},
|
||||
{"12 seconds from now", customRelTime(now.Add(+12 * time.Second)), "12 seconds from now"},
|
||||
{"30 seconds from now", customRelTime(now.Add(+30 * time.Second)), "30 seconds from now"},
|
||||
{"45 seconds from now", customRelTime(now.Add(+45 * time.Second)), "45 seconds from now"},
|
||||
{"15 minutes from now", customRelTime(now.Add(+15 * time.Minute)), "15 minutes from now"},
|
||||
{"2 hours from now", customRelTime(now.Add(+2 * time.Hour)), "120 minutes from now"},
|
||||
{"21 hours from now", customRelTime(now.Add(+21 * time.Hour)), "1260 minutes from now"},
|
||||
{"1 day from now", customRelTime(now.Add(+26 * time.Hour)), "1 day from now"},
|
||||
{"2 days from now", customRelTime(now.Add(+49 * time.Hour)), "2 days from now"},
|
||||
{"3 days from now", customRelTime(now.Add(+3 * Day)), "3 days from now"},
|
||||
{"1 week from now (1)", customRelTime(now.Add(+7 * Day)), "1 week from now"},
|
||||
{"1 week from now (2)", customRelTime(now.Add(+12 * Day)), "1 week from now"},
|
||||
{"2 weeks from now", customRelTime(now.Add(+15 * Day)), "2 weeks from now"},
|
||||
{"1 month from now", customRelTime(now.Add(+30 * Day)), "4 weeks from now"},
|
||||
{"6 months from now", customRelTime(now.Add(+6*Month - time.Second)), "25 weeks from now"},
|
||||
{"1 year from now", customRelTime(now.Add(+365 * Day)), "12 months from now"},
|
||||
{"2 years from now", customRelTime(now.Add(+2 * Year)), "24 months from now"},
|
||||
{"a while from now", customRelTime(now.Add(+LongTime)), "444 months from now"},
|
||||
}.validate(t)
|
||||
}
|
8
vendor/github.com/elazarl/goproxy/certs/openssl-gen.sh
generated
vendored
8
vendor/github.com/elazarl/goproxy/certs/openssl-gen.sh
generated
vendored
|
@ -1,8 +0,0 @@
|
|||
#!/bin/bash
|
||||
set -ex
|
||||
# generate CA's key
|
||||
openssl genrsa -aes256 -passout pass:1 -out ca.key.pem 4096
|
||||
openssl rsa -passin pass:1 -in ca.key.pem -out ca.key.pem.tmp
|
||||
mv ca.key.pem.tmp ca.key.pem
|
||||
|
||||
openssl req -config openssl.cnf -key ca.key.pem -new -x509 -days 7300 -sha256 -extensions v3_ca -out ca.pem
|
39
vendor/github.com/elazarl/goproxy/certs/openssl.cnf
generated
vendored
39
vendor/github.com/elazarl/goproxy/certs/openssl.cnf
generated
vendored
|
@ -1,39 +0,0 @@
|
|||
[ ca ]
|
||||
default_ca = CA_default
|
||||
[ CA_default ]
|
||||
default_md = sha256
|
||||
[ v3_ca ]
|
||||
subjectKeyIdentifier=hash
|
||||
authorityKeyIdentifier=keyid:always,issuer
|
||||
basicConstraints = critical,CA:true
|
||||
[ req ]
|
||||
distinguished_name = req_distinguished_name
|
||||
[ req_distinguished_name ]
|
||||
countryName = Country Name (2 letter code)
|
||||
countryName_default = IL
|
||||
countryName_min = 2
|
||||
countryName_max = 2
|
||||
|
||||
stateOrProvinceName = State or Province Name (full name)
|
||||
stateOrProvinceName_default = Center
|
||||
|
||||
localityName = Locality Name (eg, city)
|
||||
localityName_default = Lod
|
||||
|
||||
0.organizationName = Organization Name (eg, company)
|
||||
0.organizationName_default = GoProxy
|
||||
|
||||
# we can do this but it is not needed normally :-)
|
||||
#1.organizationName = Second Organization Name (eg, company)
|
||||
#1.organizationName_default = World Wide Web Pty Ltd
|
||||
|
||||
organizationalUnitName = Organizational Unit Name (eg, section)
|
||||
organizationalUnitName_default = GoProxy
|
||||
|
||||
commonName = Common Name (e.g. server FQDN or YOUR name)
|
||||
commonName_default = goproxy.github.io
|
||||
commonName_max = 64
|
||||
|
||||
emailAddress = Email Address
|
||||
emailAddress_default = elazarl@gmail.com
|
||||
emailAddress_max = 64
|
99
vendor/github.com/elazarl/goproxy/counterecryptor_test.go
generated
vendored
99
vendor/github.com/elazarl/goproxy/counterecryptor_test.go
generated
vendored
|
@ -1,99 +0,0 @@
|
|||
package goproxy_test
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/rsa"
|
||||
"encoding/binary"
|
||||
"github.com/elazarl/goproxy"
|
||||
"io"
|
||||
"math"
|
||||
"math/rand"
|
||||
"testing"
|
||||
)
|
||||
|
||||
type RandSeedReader struct {
|
||||
r rand.Rand
|
||||
}
|
||||
|
||||
func (r *RandSeedReader) Read(b []byte) (n int, err error) {
|
||||
for i := range b {
|
||||
b[i] = byte(r.r.Int() & 0xFF)
|
||||
}
|
||||
return len(b), nil
|
||||
}
|
||||
|
||||
func TestCounterEncDifferentConsecutive(t *testing.T) {
|
||||
k, err := rsa.GenerateKey(&RandSeedReader{*rand.New(rand.NewSource(0xFF43109))}, 128)
|
||||
fatalOnErr(err, "rsa.GenerateKey", t)
|
||||
c, err := goproxy.NewCounterEncryptorRandFromKey(k, []byte("the quick brown fox run over the lazy dog"))
|
||||
fatalOnErr(err, "NewCounterEncryptorRandFromKey", t)
|
||||
for i := 0; i < 100*1000; i++ {
|
||||
var a, b int64
|
||||
binary.Read(&c, binary.BigEndian, &a)
|
||||
binary.Read(&c, binary.BigEndian, &b)
|
||||
if a == b {
|
||||
t.Fatal("two consecutive equal int64", a, b)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestCounterEncIdenticalStreams(t *testing.T) {
|
||||
k, err := rsa.GenerateKey(&RandSeedReader{*rand.New(rand.NewSource(0xFF43109))}, 128)
|
||||
fatalOnErr(err, "rsa.GenerateKey", t)
|
||||
c1, err := goproxy.NewCounterEncryptorRandFromKey(k, []byte("the quick brown fox run over the lazy dog"))
|
||||
fatalOnErr(err, "NewCounterEncryptorRandFromKey", t)
|
||||
c2, err := goproxy.NewCounterEncryptorRandFromKey(k, []byte("the quick brown fox run over the lazy dog"))
|
||||
fatalOnErr(err, "NewCounterEncryptorRandFromKey", t)
|
||||
nout := 1000
|
||||
out1, out2 := make([]byte, nout), make([]byte, nout)
|
||||
io.ReadFull(&c1, out1)
|
||||
tmp := out2[:]
|
||||
rand.Seed(0xFF43109)
|
||||
for len(tmp) > 0 {
|
||||
n := 1 + rand.Intn(256)
|
||||
if n > len(tmp) {
|
||||
n = len(tmp)
|
||||
}
|
||||
n, err := c2.Read(tmp[:n])
|
||||
fatalOnErr(err, "CounterEncryptorRand.Read", t)
|
||||
tmp = tmp[n:]
|
||||
}
|
||||
if !bytes.Equal(out1, out2) {
|
||||
t.Error("identical CSPRNG does not produce the same output")
|
||||
}
|
||||
}
|
||||
|
||||
func stddev(data []int) float64 {
|
||||
var sum, sum_sqr float64 = 0, 0
|
||||
for _, h := range data {
|
||||
sum += float64(h)
|
||||
sum_sqr += float64(h) * float64(h)
|
||||
}
|
||||
n := float64(len(data))
|
||||
variance := (sum_sqr - ((sum * sum) / n)) / (n - 1)
|
||||
return math.Sqrt(variance)
|
||||
}
|
||||
|
||||
func TestCounterEncStreamHistogram(t *testing.T) {
|
||||
k, err := rsa.GenerateKey(&RandSeedReader{*rand.New(rand.NewSource(0xFF43109))}, 128)
|
||||
fatalOnErr(err, "rsa.GenerateKey", t)
|
||||
c, err := goproxy.NewCounterEncryptorRandFromKey(k, []byte("the quick brown fox run over the lazy dog"))
|
||||
fatalOnErr(err, "NewCounterEncryptorRandFromKey", t)
|
||||
nout := 100 * 1000
|
||||
out := make([]byte, nout)
|
||||
io.ReadFull(&c, out)
|
||||
refhist := make([]int, 256)
|
||||
for i := 0; i < nout; i++ {
|
||||
refhist[rand.Intn(256)]++
|
||||
}
|
||||
hist := make([]int, 256)
|
||||
for _, b := range out {
|
||||
hist[int(b)]++
|
||||
}
|
||||
refstddev, stddev := stddev(refhist), stddev(hist)
|
||||
// due to lack of time, I guestimate
|
||||
t.Logf("ref:%v - act:%v = %v", refstddev, stddev, math.Abs(refstddev-stddev))
|
||||
if math.Abs(refstddev-stddev) >= 1 {
|
||||
t.Errorf("stddev of ref histogram different than regular PRNG: %v %v", refstddev, stddev)
|
||||
}
|
||||
}
|
29
vendor/github.com/elazarl/goproxy/examples/goproxy-basic/README.md
generated
vendored
29
vendor/github.com/elazarl/goproxy/examples/goproxy-basic/README.md
generated
vendored
|
@ -1,29 +0,0 @@
|
|||
# Simple HTTP Proxy
|
||||
|
||||
`goproxy-basic` starts an HTTP proxy on :8080. It only handles explicit CONNECT
|
||||
requests.
|
||||
|
||||
Start it in one shell:
|
||||
|
||||
```sh
|
||||
goproxy-basic -v
|
||||
```
|
||||
|
||||
Fetch goproxy homepage in another:
|
||||
|
||||
```sh
|
||||
http_proxy=http://127.0.0.1:8080 wget -O - \
|
||||
http://ripper234.com/p/introducing-goproxy-light-http-proxy/
|
||||
```
|
||||
|
||||
The homepage HTML content should be displayed in the console. The proxy should
|
||||
have logged the request being processed:
|
||||
|
||||
```sh
|
||||
2015/04/09 18:19:17 [001] INFO: Got request /p/introducing-goproxy-light-http-proxy/ ripper234.com GET http://ripper234.com/p/introducing-goproxy-light-http-proxy/
|
||||
2015/04/09 18:19:17 [001] INFO: Sending request GET http://ripper234.com/p/introducing-goproxy-light-http-proxy/
|
||||
2015/04/09 18:19:18 [001] INFO: Received response 200 OK
|
||||
2015/04/09 18:19:18 [001] INFO: Copying response to client 200 OK [200]
|
||||
2015/04/09 18:19:18 [001] INFO: Copied 44333 bytes to client error=<nil>
|
||||
```
|
||||
|
17
vendor/github.com/elazarl/goproxy/examples/goproxy-basic/main.go
generated
vendored
17
vendor/github.com/elazarl/goproxy/examples/goproxy-basic/main.go
generated
vendored
|
@ -1,17 +0,0 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"github.com/elazarl/goproxy"
|
||||
"log"
|
||||
"flag"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
func main() {
|
||||
verbose := flag.Bool("v", false, "should every proxy request be logged to stdout")
|
||||
addr := flag.String("addr", ":8080", "proxy listen address")
|
||||
flag.Parse()
|
||||
proxy := goproxy.NewProxyHttpServer()
|
||||
proxy.Verbose = *verbose
|
||||
log.Fatal(http.ListenAndServe(*addr, proxy))
|
||||
}
|
75
vendor/github.com/elazarl/goproxy/examples/goproxy-customca/cert.go
generated
vendored
75
vendor/github.com/elazarl/goproxy/examples/goproxy-customca/cert.go
generated
vendored
|
@ -1,75 +0,0 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"crypto/x509"
|
||||
|
||||
"github.com/elazarl/goproxy"
|
||||
)
|
||||
|
||||
var caCert = []byte(`-----BEGIN CERTIFICATE-----
|
||||
MIIDkzCCAnugAwIBAgIJAKe/ZGdfcHdPMA0GCSqGSIb3DQEBCwUAMGAxCzAJBgNV
|
||||
BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX
|
||||
aWRnaXRzIFB0eSBMdGQxGTAXBgNVBAMMEGRlbW8gZm9yIGdvcHJveHkwHhcNMTYw
|
||||
OTI3MTQzNzQ3WhcNMTkwOTI3MTQzNzQ3WjBgMQswCQYDVQQGEwJBVTETMBEGA1UE
|
||||
CAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0cyBQdHkgTHRk
|
||||
MRkwFwYDVQQDDBBkZW1vIGZvciBnb3Byb3h5MIIBIjANBgkqhkiG9w0BAQEFAAOC
|
||||
AQ8AMIIBCgKCAQEA2+W48YZoch72zj0a+ZlyFVY2q2MWmqsEY9f/u53fAeTxvPE6
|
||||
1/DnqsydnA3FnGvxw9Dz0oZO6xG+PZvp+lhN07NZbuXK1nie8IpxCa342axpu4C0
|
||||
69lZwxikpGyJO4IL5ywp/qfb5a2DxPTAyQOQ8ROAaydoEmktRp25yicnQ2yeZW//
|
||||
1SIQxt7gRxQIGmuOQ/Gqr/XN/z2cZdbGJVRUvQXk7N6NhQiCX1zlmp1hzUW9jwC+
|
||||
JEKKF1XVpQbc94Bo5supxhkKJ70CREPy8TH9mAUcQUZQRohnPvvt/lKneYAGhjHK
|
||||
vhpajwlbMMSocVXFvY7o/IqIE/+ZUeQTs1SUwQIDAQABo1AwTjAdBgNVHQ4EFgQU
|
||||
GnlWcIbfsWJW7GId+6xZIK8YlFEwHwYDVR0jBBgwFoAUGnlWcIbfsWJW7GId+6xZ
|
||||
IK8YlFEwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAoFUjSD15rKlY
|
||||
xudzyVlr6n0fRNhITkiZMX3JlFOvtHNYif8RfK4TH/oHNBTmle69AgixjMgy8GGd
|
||||
H90prytGQ5zCs1tKcCFsN5gRSgdAkc2PpRFOK6u8HwOITV5lV7sjucsddXJcOJbQ
|
||||
4fyVe47V9TTxI+A7lRnUP2HYTR1Bd0R/IgRAH57d1ZHs7omHIuQ+Ea8ph2ppXMnP
|
||||
DXVOlZ9zfczSnPnQoomqULOU9Fq2ycyi8Y/ROtAHP6O7wCFbYHXhxojdaHSdhkcd
|
||||
troTflFMD2/4O6MtBKbHxSmEG6H0FBYz5xUZhZq7WUH24V3xYsfge29/lOCd5/Xf
|
||||
A+j0RJc/lQ==
|
||||
-----END CERTIFICATE-----`)
|
||||
|
||||
var caKey = []byte(`-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEowIBAAKCAQEA2+W48YZoch72zj0a+ZlyFVY2q2MWmqsEY9f/u53fAeTxvPE6
|
||||
1/DnqsydnA3FnGvxw9Dz0oZO6xG+PZvp+lhN07NZbuXK1nie8IpxCa342axpu4C0
|
||||
69lZwxikpGyJO4IL5ywp/qfb5a2DxPTAyQOQ8ROAaydoEmktRp25yicnQ2yeZW//
|
||||
1SIQxt7gRxQIGmuOQ/Gqr/XN/z2cZdbGJVRUvQXk7N6NhQiCX1zlmp1hzUW9jwC+
|
||||
JEKKF1XVpQbc94Bo5supxhkKJ70CREPy8TH9mAUcQUZQRohnPvvt/lKneYAGhjHK
|
||||
vhpajwlbMMSocVXFvY7o/IqIE/+ZUeQTs1SUwQIDAQABAoIBAHK94ww8W0G5QIWL
|
||||
Qwkc9XeGvg4eLUxVknva2Ll4fkZJxY4WveKx9OCd1lv4n7WoacYIwUGIDaQBZShW
|
||||
s/eKnkmqGy+PvpC87gqL4sHvQpuqqJ1LYpxylLEFqduWOuGPUVC2Lc+QnWCycsCS
|
||||
CgqZzsbMq0S+kkKRGSvw32JJneZCzqLgLNssQNVk+Gm6SI3s4jJsGPesjhnvoPaa
|
||||
xZK14uFpltaA05GSTDaQeZJFEdnnb3f/eNPc2xMEfi0S2ZlJ6Q92WJEOepAetDlR
|
||||
cRFi004bNyTb4Bphg8s4+9Cti5is199aFkGCRDWxeqEnc6aMY3Ezu9Qg3uttLVUd
|
||||
uy830GUCgYEA7qS0X+9UH1R02L3aoANyADVbFt2ZpUwQGauw9WM92pH52xeHAw1S
|
||||
ohus6FI3OC8xQq2CN525tGLUbFDZnNZ3YQHqFsfgevfnTs1//gbKXomitev0oFKh
|
||||
VT+WYS4lkgYtPlXzhdGuk32q99T/wIocAguvCUY3PiA7yBz93ReyausCgYEA6+P8
|
||||
bugMqT8qjoiz1q/YCfxsw9bAGWjlVqme2xmp256AKtxvCf1BPsToAaJU3nFi3vkw
|
||||
ICLxUWAYoMBODJ3YnbOsIZOavdXZwYHv54JqwqFealC3DG0Du6fZYZdiY8pK+E6m
|
||||
3fiYzP1WoVK5tU4bH8ibuIQvpcI8j7Gy0cV6/AMCgYBHl7fZNAZro72uLD7DVGVF
|
||||
9LvP/0kR0uDdoqli5JPw12w6szM40i1hHqZfyBJy042WsFDpeHL2z9Nkb1jpeVm1
|
||||
C4r7rJkGqwqElJf6UHUzqVzb8N6hnkhyN7JYkyyIQzwdgFGfaslRzBiXYxoa3BQM
|
||||
9Q5c3OjDxY3JuhDa3DoVYwKBgDNqrWJLSD832oHZAEIicBe1IswJKjQfriWWsV6W
|
||||
mHSbdtpg0/88aZVR/DQm+xLFakSp0jifBTS0momngRu06Dtvp2xmLQuF6oIIXY97
|
||||
2ON1owvPbibSOEcWDgb8pWCU/oRjOHIXts6vxctCKeKAFN93raGphm0+Ck9T72NU
|
||||
BTubAoGBAMEhI/Wy9wAETuXwN84AhmPdQsyCyp37YKt2ZKaqu37x9v2iL8JTbPEz
|
||||
pdBzkA2Gc0Wdb6ekIzRrTsJQl+c/0m9byFHsRsxXW2HnezfOFX1H4qAmF6KWP0ub
|
||||
M8aIn6Rab4sNPSrvKGrU6rFpv/6M33eegzldVnV9ku6uPJI1fFTC
|
||||
-----END RSA PRIVATE KEY-----`)
|
||||
|
||||
func setCA(caCert, caKey []byte) error {
|
||||
goproxyCa, err := tls.X509KeyPair(caCert, caKey)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if goproxyCa.Leaf, err = x509.ParseCertificate(goproxyCa.Certificate[0]); err != nil {
|
||||
return err
|
||||
}
|
||||
goproxy.GoproxyCa = goproxyCa
|
||||
goproxy.OkConnect = &goproxy.ConnectAction{Action: goproxy.ConnectAccept, TLSConfig: goproxy.TLSConfigFromCA(&goproxyCa)}
|
||||
goproxy.MitmConnect = &goproxy.ConnectAction{Action: goproxy.ConnectMitm, TLSConfig: goproxy.TLSConfigFromCA(&goproxyCa)}
|
||||
goproxy.HTTPMitmConnect = &goproxy.ConnectAction{Action: goproxy.ConnectHTTPMitm, TLSConfig: goproxy.TLSConfigFromCA(&goproxyCa)}
|
||||
goproxy.RejectConnect = &goproxy.ConnectAction{Action: goproxy.ConnectReject, TLSConfig: goproxy.TLSConfigFromCA(&goproxyCa)}
|
||||
return nil
|
||||
}
|
20
vendor/github.com/elazarl/goproxy/examples/goproxy-customca/main.go
generated
vendored
20
vendor/github.com/elazarl/goproxy/examples/goproxy-customca/main.go
generated
vendored
|
@ -1,20 +0,0 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"log"
|
||||
"net/http"
|
||||
|
||||
"github.com/elazarl/goproxy"
|
||||
)
|
||||
|
||||
func main() {
|
||||
verbose := flag.Bool("v", false, "should every proxy request be logged to stdout")
|
||||
addr := flag.String("addr", ":8080", "proxy listen address")
|
||||
flag.Parse()
|
||||
setCA(caCert, caKey)
|
||||
proxy := goproxy.NewProxyHttpServer()
|
||||
proxy.OnRequest().HandleConnect(goproxy.AlwaysMitm)
|
||||
proxy.Verbose = *verbose
|
||||
log.Fatal(http.ListenAndServe(*addr, proxy))
|
||||
}
|
56
vendor/github.com/elazarl/goproxy/examples/goproxy-eavesdropper/main.go
generated
vendored
56
vendor/github.com/elazarl/goproxy/examples/goproxy-eavesdropper/main.go
generated
vendored
|
@ -1,56 +0,0 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"flag"
|
||||
"log"
|
||||
"net"
|
||||
"net/http"
|
||||
"regexp"
|
||||
|
||||
"github.com/elazarl/goproxy"
|
||||
)
|
||||
|
||||
func orPanic(err error) {
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
proxy := goproxy.NewProxyHttpServer()
|
||||
proxy.OnRequest(goproxy.ReqHostMatches(regexp.MustCompile("^.*baidu.com$"))).
|
||||
HandleConnect(goproxy.AlwaysReject)
|
||||
proxy.OnRequest(goproxy.ReqHostMatches(regexp.MustCompile("^.*$"))).
|
||||
HandleConnect(goproxy.AlwaysMitm)
|
||||
// enable curl -p for all hosts on port 80
|
||||
proxy.OnRequest(goproxy.ReqHostMatches(regexp.MustCompile("^.*:80$"))).
|
||||
HijackConnect(func(req *http.Request, client net.Conn, ctx *goproxy.ProxyCtx) {
|
||||
defer func() {
|
||||
if e := recover(); e != nil {
|
||||
ctx.Logf("error connecting to remote: %v", e)
|
||||
client.Write([]byte("HTTP/1.1 500 Cannot reach destination\r\n\r\n"))
|
||||
}
|
||||
client.Close()
|
||||
}()
|
||||
clientBuf := bufio.NewReadWriter(bufio.NewReader(client), bufio.NewWriter(client))
|
||||
remote, err := net.Dial("tcp", req.URL.Host)
|
||||
orPanic(err)
|
||||
remoteBuf := bufio.NewReadWriter(bufio.NewReader(remote), bufio.NewWriter(remote))
|
||||
for {
|
||||
req, err := http.ReadRequest(clientBuf.Reader)
|
||||
orPanic(err)
|
||||
orPanic(req.Write(remoteBuf))
|
||||
orPanic(remoteBuf.Flush())
|
||||
resp, err := http.ReadResponse(remoteBuf.Reader, req)
|
||||
orPanic(err)
|
||||
orPanic(resp.Write(clientBuf.Writer))
|
||||
orPanic(clientBuf.Flush())
|
||||
}
|
||||
})
|
||||
verbose := flag.Bool("v", false, "should every proxy request be logged to stdout")
|
||||
addr := flag.String("addr", ":8080", "proxy listen address")
|
||||
flag.Parse()
|
||||
proxy.Verbose = *verbose
|
||||
log.Fatal(http.ListenAndServe(*addr, proxy))
|
||||
}
|
30
vendor/github.com/elazarl/goproxy/examples/goproxy-httpdump/README.md
generated
vendored
30
vendor/github.com/elazarl/goproxy/examples/goproxy-httpdump/README.md
generated
vendored
|
@ -1,30 +0,0 @@
|
|||
# Trace HTTP Requests and Responses
|
||||
|
||||
`goproxy-httpdump` starts an HTTP proxy on :8080. It handles explicit CONNECT
|
||||
requests and traces them in a "db" directory created in the proxy working
|
||||
directory. Each request type and headers are logged in a "log" file, while
|
||||
their bodies are dumped in files prefixed with the request session identifier.
|
||||
|
||||
Additionally, the example demonstrates how to:
|
||||
- Log information asynchronously (see HttpLogger)
|
||||
- Allow the proxy to be stopped manually while ensuring all pending requests
|
||||
have been processed (in this case, logged).
|
||||
|
||||
Start it in one shell:
|
||||
|
||||
```sh
|
||||
goproxy-httpdump
|
||||
```
|
||||
|
||||
Fetch goproxy homepage in another:
|
||||
|
||||
```sh
|
||||
http_proxy=http://127.0.0.1:8080 wget -O - \
|
||||
http://ripper234.com/p/introducing-goproxy-light-http-proxy/
|
||||
```
|
||||
|
||||
A "db" directory should have appeared where you started the proxy, containing
|
||||
two files:
|
||||
- log: the request/response traces
|
||||
- 1\_resp: the first response body
|
||||
|
285
vendor/github.com/elazarl/goproxy/examples/goproxy-httpdump/httpdump.go
generated
vendored
285
vendor/github.com/elazarl/goproxy/examples/goproxy-httpdump/httpdump.go
generated
vendored
|
@ -1,285 +0,0 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"flag"
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/http/httputil"
|
||||
"os"
|
||||
"os/signal"
|
||||
"path"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/elazarl/goproxy"
|
||||
"github.com/elazarl/goproxy/transport"
|
||||
)
|
||||
|
||||
type FileStream struct {
|
||||
path string
|
||||
f *os.File
|
||||
}
|
||||
|
||||
func NewFileStream(path string) *FileStream {
|
||||
return &FileStream{path, nil}
|
||||
}
|
||||
|
||||
func (fs *FileStream) Write(b []byte) (nr int, err error) {
|
||||
if fs.f == nil {
|
||||
fs.f, err = os.Create(fs.path)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
}
|
||||
return fs.f.Write(b)
|
||||
}
|
||||
|
||||
func (fs *FileStream) Close() error {
|
||||
fmt.Println("Close", fs.path)
|
||||
if fs.f == nil {
|
||||
return errors.New("FileStream was never written into")
|
||||
}
|
||||
return fs.f.Close()
|
||||
}
|
||||
|
||||
type Meta struct {
|
||||
req *http.Request
|
||||
resp *http.Response
|
||||
err error
|
||||
t time.Time
|
||||
sess int64
|
||||
bodyPath string
|
||||
from string
|
||||
}
|
||||
|
||||
func fprintf(nr *int64, err *error, w io.Writer, pat string, a ...interface{}) {
|
||||
if *err != nil {
|
||||
return
|
||||
}
|
||||
var n int
|
||||
n, *err = fmt.Fprintf(w, pat, a...)
|
||||
*nr += int64(n)
|
||||
}
|
||||
|
||||
func write(nr *int64, err *error, w io.Writer, b []byte) {
|
||||
if *err != nil {
|
||||
return
|
||||
}
|
||||
var n int
|
||||
n, *err = w.Write(b)
|
||||
*nr += int64(n)
|
||||
}
|
||||
|
||||
func (m *Meta) WriteTo(w io.Writer) (nr int64, err error) {
|
||||
if m.req != nil {
|
||||
fprintf(&nr, &err, w, "Type: request\r\n")
|
||||
} else if m.resp != nil {
|
||||
fprintf(&nr, &err, w, "Type: response\r\n")
|
||||
}
|
||||
fprintf(&nr, &err, w, "ReceivedAt: %v\r\n", m.t)
|
||||
fprintf(&nr, &err, w, "Session: %d\r\n", m.sess)
|
||||
fprintf(&nr, &err, w, "From: %v\r\n", m.from)
|
||||
if m.err != nil {
|
||||
// note the empty response
|
||||
fprintf(&nr, &err, w, "Error: %v\r\n\r\n\r\n\r\n", m.err)
|
||||
} else if m.req != nil {
|
||||
fprintf(&nr, &err, w, "\r\n")
|
||||
buf, err2 := httputil.DumpRequest(m.req, false)
|
||||
if err2 != nil {
|
||||
return nr, err2
|
||||
}
|
||||
write(&nr, &err, w, buf)
|
||||
} else if m.resp != nil {
|
||||
fprintf(&nr, &err, w, "\r\n")
|
||||
buf, err2 := httputil.DumpResponse(m.resp, false)
|
||||
if err2 != nil {
|
||||
return nr, err2
|
||||
}
|
||||
write(&nr, &err, w, buf)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// HttpLogger is an asynchronous HTTP request/response logger. It traces
|
||||
// requests and responses headers in a "log" file in logger directory and dumps
|
||||
// their bodies in files prefixed with the session identifiers.
|
||||
// Close it to ensure pending items are correctly logged.
|
||||
type HttpLogger struct {
|
||||
path string
|
||||
c chan *Meta
|
||||
errch chan error
|
||||
}
|
||||
|
||||
func NewLogger(basepath string) (*HttpLogger, error) {
|
||||
f, err := os.Create(path.Join(basepath, "log"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
logger := &HttpLogger{basepath, make(chan *Meta), make(chan error)}
|
||||
go func() {
|
||||
for m := range logger.c {
|
||||
if _, err := m.WriteTo(f); err != nil {
|
||||
log.Println("Can't write meta", err)
|
||||
}
|
||||
}
|
||||
logger.errch <- f.Close()
|
||||
}()
|
||||
return logger, nil
|
||||
}
|
||||
|
||||
func (logger *HttpLogger) LogResp(resp *http.Response, ctx *goproxy.ProxyCtx) {
|
||||
body := path.Join(logger.path, fmt.Sprintf("%d_resp", ctx.Session))
|
||||
from := ""
|
||||
if ctx.UserData != nil {
|
||||
from = ctx.UserData.(*transport.RoundTripDetails).TCPAddr.String()
|
||||
}
|
||||
if resp == nil {
|
||||
resp = emptyResp
|
||||
} else {
|
||||
resp.Body = NewTeeReadCloser(resp.Body, NewFileStream(body))
|
||||
}
|
||||
logger.LogMeta(&Meta{
|
||||
resp: resp,
|
||||
err: ctx.Error,
|
||||
t: time.Now(),
|
||||
sess: ctx.Session,
|
||||
from: from})
|
||||
}
|
||||
|
||||
var emptyResp = &http.Response{}
|
||||
var emptyReq = &http.Request{}
|
||||
|
||||
func (logger *HttpLogger) LogReq(req *http.Request, ctx *goproxy.ProxyCtx) {
|
||||
body := path.Join(logger.path, fmt.Sprintf("%d_req", ctx.Session))
|
||||
if req == nil {
|
||||
req = emptyReq
|
||||
} else {
|
||||
req.Body = NewTeeReadCloser(req.Body, NewFileStream(body))
|
||||
}
|
||||
logger.LogMeta(&Meta{
|
||||
req: req,
|
||||
err: ctx.Error,
|
||||
t: time.Now(),
|
||||
sess: ctx.Session,
|
||||
from: req.RemoteAddr})
|
||||
}
|
||||
|
||||
func (logger *HttpLogger) LogMeta(m *Meta) {
|
||||
logger.c <- m
|
||||
}
|
||||
|
||||
func (logger *HttpLogger) Close() error {
|
||||
close(logger.c)
|
||||
return <-logger.errch
|
||||
}
|
||||
|
||||
// TeeReadCloser extends io.TeeReader by allowing reader and writer to be
|
||||
// closed.
|
||||
type TeeReadCloser struct {
|
||||
r io.Reader
|
||||
w io.WriteCloser
|
||||
c io.Closer
|
||||
}
|
||||
|
||||
func NewTeeReadCloser(r io.ReadCloser, w io.WriteCloser) io.ReadCloser {
|
||||
return &TeeReadCloser{io.TeeReader(r, w), w, r}
|
||||
}
|
||||
|
||||
func (t *TeeReadCloser) Read(b []byte) (int, error) {
|
||||
return t.r.Read(b)
|
||||
}
|
||||
|
||||
// Close attempts to close the reader and write. It returns an error if both
|
||||
// failed to Close.
|
||||
func (t *TeeReadCloser) Close() error {
|
||||
err1 := t.c.Close()
|
||||
err2 := t.w.Close()
|
||||
if err1 != nil {
|
||||
return err1
|
||||
}
|
||||
return err2
|
||||
}
|
||||
|
||||
// stoppableListener serves stoppableConn and tracks their lifetime to notify
|
||||
// when it is safe to terminate the application.
|
||||
type stoppableListener struct {
|
||||
net.Listener
|
||||
sync.WaitGroup
|
||||
}
|
||||
|
||||
type stoppableConn struct {
|
||||
net.Conn
|
||||
wg *sync.WaitGroup
|
||||
}
|
||||
|
||||
func newStoppableListener(l net.Listener) *stoppableListener {
|
||||
return &stoppableListener{l, sync.WaitGroup{}}
|
||||
}
|
||||
|
||||
func (sl *stoppableListener) Accept() (net.Conn, error) {
|
||||
c, err := sl.Listener.Accept()
|
||||
if err != nil {
|
||||
return c, err
|
||||
}
|
||||
sl.Add(1)
|
||||
return &stoppableConn{c, &sl.WaitGroup}, nil
|
||||
}
|
||||
|
||||
func (sc *stoppableConn) Close() error {
|
||||
sc.wg.Done()
|
||||
return sc.Conn.Close()
|
||||
}
|
||||
|
||||
func main() {
|
||||
verbose := flag.Bool("v", false, "should every proxy request be logged to stdout")
|
||||
addr := flag.String("l", ":8080", "on which address should the proxy listen")
|
||||
flag.Parse()
|
||||
proxy := goproxy.NewProxyHttpServer()
|
||||
proxy.Verbose = *verbose
|
||||
if err := os.MkdirAll("db", 0755); err != nil {
|
||||
log.Fatal("Can't create dir", err)
|
||||
}
|
||||
logger, err := NewLogger("db")
|
||||
if err != nil {
|
||||
log.Fatal("can't open log file", err)
|
||||
}
|
||||
tr := transport.Transport{Proxy: transport.ProxyFromEnvironment}
|
||||
// For every incoming request, override the RoundTripper to extract
|
||||
// connection information. Store it is session context log it after
|
||||
// handling the response.
|
||||
proxy.OnRequest().DoFunc(func(req *http.Request, ctx *goproxy.ProxyCtx) (*http.Request, *http.Response) {
|
||||
ctx.RoundTripper = goproxy.RoundTripperFunc(func(req *http.Request, ctx *goproxy.ProxyCtx) (resp *http.Response, err error) {
|
||||
ctx.UserData, resp, err = tr.DetailedRoundTrip(req)
|
||||
return
|
||||
})
|
||||
logger.LogReq(req, ctx)
|
||||
return req, nil
|
||||
})
|
||||
proxy.OnResponse().DoFunc(func(resp *http.Response, ctx *goproxy.ProxyCtx) *http.Response {
|
||||
logger.LogResp(resp, ctx)
|
||||
return resp
|
||||
})
|
||||
l, err := net.Listen("tcp", *addr)
|
||||
if err != nil {
|
||||
log.Fatal("listen:", err)
|
||||
}
|
||||
sl := newStoppableListener(l)
|
||||
ch := make(chan os.Signal)
|
||||
signal.Notify(ch, os.Interrupt)
|
||||
go func() {
|
||||
<-ch
|
||||
log.Println("Got SIGINT exiting")
|
||||
sl.Add(1)
|
||||
sl.Close()
|
||||
logger.Close()
|
||||
sl.Done()
|
||||
}()
|
||||
log.Println("Starting Proxy")
|
||||
http.Serve(sl, proxy)
|
||||
sl.Wait()
|
||||
log.Println("All connections closed - exit")
|
||||
}
|
31
vendor/github.com/elazarl/goproxy/examples/goproxy-jquery-version/README.md
generated
vendored
31
vendor/github.com/elazarl/goproxy/examples/goproxy-jquery-version/README.md
generated
vendored
|
@ -1,31 +0,0 @@
|
|||
# Content Analysis
|
||||
|
||||
`goproxy-jquery-version` starts an HTTP proxy on :8080. It checks HTML
|
||||
responses, looks for scripts referencing jQuery library and emits warnings if
|
||||
different versions of the library are being used for a given host.
|
||||
|
||||
Start it in one shell:
|
||||
|
||||
```sh
|
||||
goproxy-jquery-version
|
||||
```
|
||||
|
||||
Fetch goproxy homepage in another:
|
||||
|
||||
```sh
|
||||
http_proxy=http://127.0.0.1:8080 wget -O - \
|
||||
http://ripper234.com/p/introducing-goproxy-light-http-proxy/
|
||||
```
|
||||
|
||||
Goproxy homepage uses jQuery and a mix of plugins. First the proxy reports the
|
||||
first use of jQuery it detects for the domain. Then, because the regular
|
||||
expression matching the jQuery sources is imprecise, it reports a mismatch with
|
||||
a plugin reference:
|
||||
|
||||
```sh
|
||||
2015/04/11 11:23:02 [001] WARN: ripper234.com uses //ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js
|
||||
2015/04/11 11:23:02 [001] WARN: In http://ripper234.com/p/introducing-goproxy-light-http-proxy/, \
|
||||
Contradicting jqueries //ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js \
|
||||
http://ripper234.wpengine.netdna-cdn.com/wp-content/plugins/wp-ajax-edit-comments/js/jquery.colorbox.min.js?ver=5.0.36
|
||||
```
|
||||
|
8
vendor/github.com/elazarl/goproxy/examples/goproxy-jquery-version/jquery1.html
generated
vendored
8
vendor/github.com/elazarl/goproxy/examples/goproxy-jquery-version/jquery1.html
generated
vendored
|
@ -1,8 +0,0 @@
|
|||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<script src="jquery.1.4.js"></script>
|
||||
</head>
|
||||
<body/>
|
||||
</html>
|
||||
|
8
vendor/github.com/elazarl/goproxy/examples/goproxy-jquery-version/jquery2.html
generated
vendored
8
vendor/github.com/elazarl/goproxy/examples/goproxy-jquery-version/jquery2.html
generated
vendored
|
@ -1,8 +0,0 @@
|
|||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<script src="jquery.1.3.js"></script>
|
||||
</head>
|
||||
<body/>
|
||||
</html>
|
||||
|
233
vendor/github.com/elazarl/goproxy/examples/goproxy-jquery-version/jquery_homepage.html
generated
vendored
233
vendor/github.com/elazarl/goproxy/examples/goproxy-jquery-version/jquery_homepage.html
generated
vendored
|
@ -1,233 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
|
||||
<title>jQuery: The Write Less, Do More, JavaScript Library</title>
|
||||
<link rel="stylesheet" href="http://static.jquery.com/files/rocker/css/reset.css" type="text/css" />
|
||||
<link rel="stylesheet" href="http://static.jquery.com/files/rocker/css/screen.css" type="text/css" />
|
||||
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
|
||||
<script>!window.jQuery && document.write('<script src="http://code.jquery.com/jquery-1.4.2.min.js"><\/script>');</script>
|
||||
<script src="http://static.jquery.com/files/rocker/scripts/custom.js"></script>
|
||||
<link rel="alternate" type="application/rss+xml" title="jQuery Blog" href="http://jquery.com/blog/feed/" />
|
||||
<link rel="shortcut icon" href="http://static.jquery.com/favicon.ico" type="image/x-icon"/>
|
||||
</head>
|
||||
<body>
|
||||
<div id="jq-siteContain">
|
||||
<div id="jq-header">
|
||||
<a id="jq-siteLogo" href="http://jquery.com" title="jQuery Home"><img src="http://static.jquery.com/files/rocker/images/logo_jquery_215x53.gif" width="215" height="53" alt="jQuery: Write Less, Do More." /></a>
|
||||
|
||||
<div id="jq-primaryNavigation">
|
||||
<ul>
|
||||
<li class="jq-jquery jq-current"><a href="http://jquery.com/" title="jQuery Home">jQuery</a></li>
|
||||
<li class="jq-ui"><a href="http://jqueryui.com/" title="jQuery UI">UI</a></li>
|
||||
<li class="jq-mobile"><a href="http://jquerymobile.com/" title="jQuery Mobile">Mobile</a></li>
|
||||
<li class="jq-plugins"><a href="http://plugins.jquery.com/" title="jQuery Plugins">Plugins</a></li>
|
||||
<li class="jq-meetup"><a href="http://meetups.jquery.com/" title="jQuery Meetups">Meetups</a></li>
|
||||
<li class="jq-forum"><a href="http://forum.jquery.com/" title="jQuery Forum">Forum</a></li>
|
||||
<li class="jq-blog"><a href="http://blog.jquery.com/" title="jQuery Blog">Blog</a></li>
|
||||
<li class="jq-about"><a href="http://jquery.org/about" title="About jQuery">About</a></li>
|
||||
<li class="jq-donate"><a href="http://jquery.org/donate" title="Donate to jQuery">Donate</a></li>
|
||||
</ul>
|
||||
</div><!-- /#primaryNavigation -->
|
||||
|
||||
<div id="jq-secondaryNavigation">
|
||||
<ul>
|
||||
<li class="jq-download jq-first"><a href="http://docs.jquery.com/Downloading_jQuery">Download</a></li>
|
||||
|
||||
<li class="jq-documentation"><a href="http://docs.jquery.com">Documentation</a></li>
|
||||
<li class="jq-tutorials"><a href="http://docs.jquery.com/Tutorials">Tutorials</a></li>
|
||||
<li class="jq-bugTracker"><a href="http://dev.jquery.com/">Bug Tracker</a></li>
|
||||
<li class="jq-discussion jq-last"><a href="http://docs.jquery.com/Discussion">Discussion</a></li>
|
||||
</ul>
|
||||
</div><!-- /#secondaryNavigation -->
|
||||
|
||||
|
||||
|
||||
</div><!-- /#header -->
|
||||
|
||||
<div id="jq-content" class="jq-clearfix">
|
||||
|
||||
<div id="jq-intro" class="jq-clearfix">
|
||||
<h2><span class="jq-jquery"><span>jQuery</span></span> is a new kind of JavaScript Library.</h2>
|
||||
<p>jQuery is a fast and concise JavaScript Library that simplifies HTML document traversing, event handling, animating, and Ajax interactions for rapid web development. <strong>jQuery is designed to change the way that you write JavaScript.</strong></p>
|
||||
<ul class="jq-checkpoints jq-clearfix">
|
||||
<li><a href="http://docs.jquery.com/Tutorials" title="Lightweight Footprint" class="jq-thickbox">Lightweight Footprint</a>
|
||||
<div class="jq-checkpointSubhead">
|
||||
|
||||
<p>About 31KB in size <em>(Minified and Gzipped)</em></p>
|
||||
</div>
|
||||
</li>
|
||||
<li><a href="http://docs.jquery.com/Tutorials" title="CSS3 Compliant" class="jq-thickbox">CSS3 Compliant</a>
|
||||
<div class="jq-checkpointSubhead">
|
||||
<p>Supports CSS 1-3 selectors and more!</p>
|
||||
</div>
|
||||
|
||||
</li>
|
||||
<li><a href="http://docs.jquery.com/Tutorials" title="Cross-browser" class="jq-thickbox">Cross-browser</a>
|
||||
<div class="jq-checkpointSubhead">
|
||||
<p>IE 6.0+, FF 3.6+, Safari 5.0+, Opera, Chrome</p>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div><!-- /#intro -->
|
||||
|
||||
<div id="jq-download">
|
||||
<h2>Grab the latest version!</h2>
|
||||
<form action="" method="get">
|
||||
<fieldset>
|
||||
<legend>Choose your compression level:</legend>
|
||||
<div id="jq-compression" class="jq-clearfix">
|
||||
<input type="radio" name="name" value="http://code.jquery.com/jquery-1.7.2.min.js" id="jq-production" checked="checked" />
|
||||
<a class="jq-radioToggle name jq-checked" href="http://code.jquery.com/jquery-1.7.2.min.js">jquery-1.7.2.min.js</a>
|
||||
<label for="jq-production">Production <em>(<strong>32KB</strong>, Minified and Gzipped)</em></label>
|
||||
<input type="radio" name="name" value="http://code.jquery.com/jquery-1.7.2.js" id="jq-development" />
|
||||
<a class="jq-radioToggle name" href="http://code.jquery.com/jquery-1.7.2.js">jquery-1.7.2.js</a>
|
||||
<label for="jq-development">Development <em>(<strong>247KB</strong>, Uncompressed Code)</em></label>
|
||||
</div>
|
||||
<button type="submit" name="downloadBtn" id="jq-downloadBtn"><span>Download</span></button>
|
||||
<p class="jq-version"><strong>Current Release:</strong> v1.7.2</p>
|
||||
</fieldset>
|
||||
</form>
|
||||
<script>
|
||||
jQuery("#jq-download form").submit(function(){
|
||||
window.location = jQuery(this).find("input:checked").val();
|
||||
return false;
|
||||
});
|
||||
</script>
|
||||
</div><!-- /#download -->
|
||||
|
||||
<div id="jq-whosUsing">
|
||||
<h2 class="jq-whosUsing">Who's using jQuery?</h2>
|
||||
<ul class="jq-whosUsing">
|
||||
<li><a href="http://www.google.com" class="jq-google" title="Google">Google</a></li>
|
||||
<li><a href="http://www.dell.com" class="jq-dell" title="Dell">Dell</a></li>
|
||||
<li><a href="http://www.bankofamerica.com" class="jq-boa" title="Bank of America">Bank of America</a></li>
|
||||
<li><a href="http://www.mlb.com" class="jq-mlb" title="Major League Baseball">Major League Baseball</a></li>
|
||||
<li><a href="http://www.digg.com" class="jq-digg" title="Digg">Digg</a></li>
|
||||
<li><a href="http://www.nbc.com" class="jq-nbc" title="NBC">NBC</a></li>
|
||||
<li><a href="http://www.cbs.com" class="jq-cbs" title="CBS News">CBS News</a></li>
|
||||
<li><a href="http://www.netflix.com" class="jq-netflix" title="Netflix">Netflix</a></li>
|
||||
<li><a href="http://www.technorati.com" class="jq-technorati" title="Technorati">Technorati</a></li>
|
||||
<li><a href="http://www.mozilla.org" class="jq-mozilla" title="Mozilla">Mozilla</a></li>
|
||||
<li><a href="http://www.wordpress.org" class="jq-wordpress" title="Wordpress">Wordpress</a></li>
|
||||
<li><a href="http://www.drupal.org" class="jq-drupal" title="Drupal">Drupal</a></li>
|
||||
</ul>
|
||||
</div><!-- /#jq-whosUsing -->
|
||||
|
||||
|
||||
<div id="jq-learnjQuery" class="jq-clearfix">
|
||||
|
||||
<div id="jq-learnNow">
|
||||
<h2>Learn <span class="jq-jquery"><span>jQuery</span></span> Now!</h2>
|
||||
<p>What does jQuery code look like? Here's the quick and dirty:</p>
|
||||
<div class="jq-codeDemo jq-clearfix">
|
||||
<pre><code>$("p.neat").addClass("ohmy").show("slow");</code></pre>
|
||||
<a href="http://docs.jquery.com/Tutorials" class="jq-runCode">Run Code</a>
|
||||
|
||||
<p class="neat"><strong>Congratulations!</strong> You just ran a snippet of jQuery code. Wasn't that easy? There's lots of example code throughout the <strong><a href="http://docs.jquery.com/">documentation</a></strong> on this site. Be sure to give all the code a test run to see what happens.</p>
|
||||
</div>
|
||||
</div><!-- /#learnNow -->
|
||||
|
||||
|
||||
|
||||
<div id="jq-resources" class="clearfix">
|
||||
<h2>jQuery Resources</h2>
|
||||
|
||||
<div class="jq-gettingStarted">
|
||||
<h3>Getting Started With jQuery</h3>
|
||||
<ul>
|
||||
<li><a href="http://docs.jquery.com/How_jQuery_Works">How jQuery Works</a></li>
|
||||
<li><a href="http://docs.jquery.com/Tutorials">Tutorials</a></li>
|
||||
<li><a href="http://docs.jquery.com/Using_jQuery_with_Other_Libraries">Using jQuery with other libraries</a></li>
|
||||
<li><a href="http://docs.jquery.com/">jQuery Documentation</a></li>
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
<div class="jq-devResources">
|
||||
<h3>Developer Resources</h3>
|
||||
<ul>
|
||||
<li><a href="http://docs.jquery.com/Discussion">Mailing List</a></li>
|
||||
<li><a href="http://docs.jquery.com/Downloading_jQuery">Source code / Git</a></li>
|
||||
|
||||
<li><a href="http://docs.jquery.com/Plugins/Authoring">Plugin Authoring</a></li>
|
||||
<li><a href="http://dev.jquery.com/newticket/">Submit a New Bug Report</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div><!-- /#resources -->
|
||||
|
||||
</div><!-- /#learnjQuery -->
|
||||
|
||||
<div id="jq-books" style="width:auto; float: none">
|
||||
<h2>Books About jQuery</h2>
|
||||
|
||||
<ul>
|
||||
<li class="jq-clearfix" style="width:270px;float:left;clear:none;">
|
||||
<a href="http://link.packtpub.com/S3Fr9Q" class="jq-bookImg"><img src="http://learningjquery.kswedberg.netdna-cdn.com/wp-content/themes/ljq/images/ljq3rded.jpg" alt="Learning jQuery Third Edition" width="55" height="70" /></a>
|
||||
<h3><a href="http://link.packtpub.com/S3Fr9Q">Learning jQuery Third Edition</a></h3>
|
||||
<div class="jq-author">Karl Swedberg and <br />Jonathan Chaffer</div>
|
||||
<a href="http://link.packtpub.com/S3Fr9Q" class="jq-buyNow">Buy Now</a>
|
||||
</li>
|
||||
<li class="jq-clearfix" style="width:270px;float:left;clear:none;">
|
||||
<a href="http://www.packtpub.com/jquery-1-4-animation-techniques-beginners-guide/book/mid/1803111nkj15" class="jq-bookImg"><img src="http://static.jquery.com/books/jquery-animation-beginners-guide.jpg" alt="jQuery 1.4 Animation Techniques: Beginners Guide" width="55" height="70" /></a>
|
||||
<h3><a href="http://www.packtpub.com/jquery-1-4-animation-techniques-beginners-guide/book/mid/1803111nkj15">jQuery 1.4 Animation Techniques: Beginners Guide</a></h3>
|
||||
<div class="jq-author">Dan Wellman</div>
|
||||
<a href="http://www.packtpub.com/jquery-1-4-animation-techniques-beginners-guide/book/mid/1803111nkj15" class="jq-buyNow">Buy Now</a>
|
||||
</li>
|
||||
<li class="jq-clearfix" style="width:270px;float:left;clear:none;">
|
||||
<a href="http://www.packtpub.com/jquery-plugin-development-beginners-guide/book/mid/1911104odmdz" class="jq-bookImg"><img src="http://static.jquery.com/books/jquery-plugin-developers-guide_thumb.jpg" alt="jQuery Plugin Development Beginner's Guide" width="55" height="70" /></a>
|
||||
<h3><a href="http://www.packtpub.com/jquery-plugin-development-beginners-guide/book/mid/1911104odmdz">jQuery Plugin Development Beginner's Guide</a></h3>
|
||||
<div class="jq-author">Guilio Bai</div>
|
||||
<a href="http://www.packtpub.com/jquery-plugin-development-beginners-guide/book/mid/1911104odmdz" class="jq-buyNow">Buy Now</a>
|
||||
</li>
|
||||
|
||||
<li class="jq-clearfix" style="width:270px;float:left;clear:left;">
|
||||
<a href="http://www.manning.com/affiliate/idevaffiliate.php?id=648_176" class="jq-bookImg"><img src="http://static.jquery.com/books/jquery-in-action-2ed_thumb.jpg" alt="jQuery in Action" width="55" height="70" /></a>
|
||||
<h3><a href="http://www.manning.com/affiliate/idevaffiliate.php?id=648_176">jQuery in Action</a></h3>
|
||||
<div class="jq-author">Bear Bibeault
|
||||
<br />and Yehuda Katz</div>
|
||||
<a href="http://www.manning.com/affiliate/idevaffiliate.php?id=648_176" class="jq-buyNow">Buy Now</a>
|
||||
</li>
|
||||
<li class="jq-clearfix" style="width:270px;float:left;clear:none;">
|
||||
<a class="jq-bookImg" href="http://jqueryenlightenment.com/"><img src="http://static.jquery.com/books/jquery-enlightenment_thumb.jpg" alt="jQuery Enlightenment" width="55" height="70" /></a>
|
||||
<h3><a href="http://jqueryenlightenment.com/">jQuery Enlightenment</a></h3>
|
||||
<div class="jq-author">Cody Lindley</div>
|
||||
<a href="http://jqueryenlightenment.com/" class="jq-buyNow">Buy Now</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
</div><!-- /#news -->
|
||||
|
||||
|
||||
|
||||
</div><!-- /#content -->
|
||||
|
||||
|
||||
<div id="jq-footer" class="jq-clearfix">
|
||||
|
||||
<div id="jq-credits">
|
||||
<p id="jq-copyright">© 2010 <a href="http://jquery.org/">The jQuery Project</a></p>
|
||||
<p id="jq-hosting">Sponsored by <a href="http://mediatemple.net" class="jq-mediaTemple">Media Temple</a> and <a href="http://jquery.org/sponsors">others</a>.</p>
|
||||
</div>
|
||||
|
||||
<div id="jq-footerNavigation">
|
||||
<ul>
|
||||
<li class="jq-download jq-first"><a href="http://docs.jquery.com/Downloading_jQuery">Download</a></li>
|
||||
<li class="jq-documentation"><a href="http://docs.jquery.com">Documentation</a></li>
|
||||
|
||||
<li class="jq-tutorials"><a href="http://docs.jquery.com/Tutorials">Tutorials</a></li>
|
||||
<li class="jq-bugTracker"><a href="http://dev.jquery.com/">Bug Tracker</a></li>
|
||||
<li class="jq-discussion jq-last"><a href="http://docs.jquery.com/Discussion">Discussion</a></li>
|
||||
</ul>
|
||||
</div><!-- /#secondaryNavigation -->
|
||||
|
||||
</div><!-- /#footer -->
|
||||
</div><!-- /#siteContain -->
|
||||
<script src="http://static.jquery.com/donate/donate.js" type="text/javascript"></script>
|
||||
<script type="text/javascript">
|
||||
var _gaq = _gaq || []; _gaq.push(['_setAccount', 'UA-1076265-1']); _gaq.push(['_trackPageview']); _gaq.push(['_setDomainName', '.jquery.com']);
|
||||
(function() {var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
|
||||
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
|
||||
(document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(ga);})();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
118
vendor/github.com/elazarl/goproxy/examples/goproxy-jquery-version/jquery_test.go
generated
vendored
118
vendor/github.com/elazarl/goproxy/examples/goproxy-jquery-version/jquery_test.go
generated
vendored
|
@ -1,118 +0,0 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"net/url"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func equal(u, v []string) bool {
|
||||
if len(u) != len(v) {
|
||||
return false
|
||||
}
|
||||
for i, _ := range u {
|
||||
if u[i] != v[i] {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func readFile(fname string, t *testing.T) string {
|
||||
b, err := ioutil.ReadFile(fname)
|
||||
if err != nil {
|
||||
t.Fatal("readFile", err)
|
||||
}
|
||||
return string(b)
|
||||
}
|
||||
|
||||
func TestDefectiveScriptParser(t *testing.T) {
|
||||
if l := len(findScriptSrc(`<!DOCTYPE HTML>
|
||||
<html>
|
||||
<body>
|
||||
|
||||
<video width="320" height="240" controls="controls">
|
||||
<source src="movie.mp4" type="video/mp4" />
|
||||
<source src="movie.ogg" type="video/ogg" />
|
||||
<source src="movie.webm" type="video/webm" />
|
||||
Your browser does not support the video tag.
|
||||
</video>
|
||||
|
||||
</body>
|
||||
</html>`)); l != 0 {
|
||||
t.Fail()
|
||||
}
|
||||
urls := findScriptSrc(readFile("w3schools.html", t))
|
||||
if !equal(urls, []string{"http://partner.googleadservices.com/gampad/google_service.js",
|
||||
"//translate.google.com/translate_a/element.js?cb=googleTranslateElementInit"}) {
|
||||
t.Error("w3schools.html", "src scripts are not recognized", urls)
|
||||
}
|
||||
urls = findScriptSrc(readFile("jquery_homepage.html", t))
|
||||
if !equal(urls, []string{"http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js",
|
||||
"http://code.jquery.com/jquery-1.4.2.min.js",
|
||||
"http://static.jquery.com/files/rocker/scripts/custom.js",
|
||||
"http://static.jquery.com/donate/donate.js"}) {
|
||||
t.Error("jquery_homepage.html", "src scripts are not recognized", urls)
|
||||
}
|
||||
}
|
||||
|
||||
func proxyWithLog() (*http.Client, *bytes.Buffer) {
|
||||
proxy := NewJqueryVersionProxy()
|
||||
proxyServer := httptest.NewServer(proxy)
|
||||
buf := new(bytes.Buffer)
|
||||
proxy.Logger = log.New(buf, "", 0)
|
||||
proxyUrl, _ := url.Parse(proxyServer.URL)
|
||||
tr := &http.Transport{Proxy: http.ProxyURL(proxyUrl)}
|
||||
client := &http.Client{Transport: tr}
|
||||
return client, buf
|
||||
}
|
||||
|
||||
func get(t *testing.T, server *httptest.Server, client *http.Client, url string) {
|
||||
resp, err := client.Get(server.URL + url)
|
||||
if err != nil {
|
||||
t.Fatal("cannot get proxy", err)
|
||||
}
|
||||
ioutil.ReadAll(resp.Body)
|
||||
resp.Body.Close()
|
||||
}
|
||||
|
||||
func TestProxyServiceTwoVersions(t *testing.T) {
|
||||
var fs = httptest.NewServer(http.FileServer(http.Dir(".")))
|
||||
defer fs.Close()
|
||||
|
||||
client, buf := proxyWithLog()
|
||||
|
||||
get(t, fs, client, "/w3schools.html")
|
||||
get(t, fs, client, "/php_man.html")
|
||||
if buf.String() != "" &&
|
||||
!strings.Contains(buf.String(), " uses jquery ") {
|
||||
t.Error("shouldn't warn on a single URL", buf.String())
|
||||
}
|
||||
get(t, fs, client, "/jquery1.html")
|
||||
warnings := buf.String()
|
||||
if !strings.Contains(warnings, "http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js") ||
|
||||
!strings.Contains(warnings, "jquery.1.4.js") ||
|
||||
!strings.Contains(warnings, "Contradicting") {
|
||||
t.Error("contradicting jquery versions (php_man.html, w3schools.html) does not issue warning", warnings)
|
||||
}
|
||||
}
|
||||
|
||||
func TestProxyService(t *testing.T) {
|
||||
var fs = httptest.NewServer(http.FileServer(http.Dir(".")))
|
||||
defer fs.Close()
|
||||
|
||||
client, buf := proxyWithLog()
|
||||
|
||||
get(t, fs, client, "/jquery_homepage.html")
|
||||
warnings := buf.String()
|
||||
if !strings.Contains(warnings, "http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js") ||
|
||||
!strings.Contains(warnings, "http://code.jquery.com/jquery-1.4.2.min.js") ||
|
||||
!strings.Contains(warnings, "Contradicting") {
|
||||
t.Error("contradicting jquery versions does not issue warning")
|
||||
}
|
||||
}
|
64
vendor/github.com/elazarl/goproxy/examples/goproxy-jquery-version/main.go
generated
vendored
64
vendor/github.com/elazarl/goproxy/examples/goproxy-jquery-version/main.go
generated
vendored
|
@ -1,64 +0,0 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"github.com/elazarl/goproxy"
|
||||
"github.com/elazarl/goproxy/ext/html"
|
||||
"log"
|
||||
"net/http"
|
||||
"regexp"
|
||||
)
|
||||
|
||||
var (
|
||||
// who said we can't parse HTML with regexp?
|
||||
scriptMatcher = regexp.MustCompile(`(?i:<script\s+)`)
|
||||
srcAttrMatcher = regexp.MustCompile(`^(?i:[^>]*\ssrc=["']([^"']*)["'])`)
|
||||
)
|
||||
|
||||
// findScripts returns all sources of HTML script tags found in input text.
|
||||
func findScriptSrc(html string) []string {
|
||||
srcs := make([]string, 0)
|
||||
matches := scriptMatcher.FindAllStringIndex(html, -1)
|
||||
for _, match := range matches {
|
||||
// -1 to capture the whitespace at the end of the script tag
|
||||
srcMatch := srcAttrMatcher.FindStringSubmatch(html[match[1]-1:])
|
||||
if srcMatch != nil {
|
||||
srcs = append(srcs, srcMatch[1])
|
||||
}
|
||||
}
|
||||
return srcs
|
||||
}
|
||||
|
||||
// NewJQueryVersionProxy creates a proxy checking responses HTML content, looks
|
||||
// for scripts referencing jQuery library and emits warnings if different
|
||||
// versions of the library are being used for a given host.
|
||||
func NewJqueryVersionProxy() *goproxy.ProxyHttpServer {
|
||||
proxy := goproxy.NewProxyHttpServer()
|
||||
m := make(map[string]string)
|
||||
jqueryMatcher := regexp.MustCompile(`(?i:jquery\.)`)
|
||||
proxy.OnResponse(goproxy_html.IsHtml).Do(goproxy_html.HandleString(
|
||||
func(s string, ctx *goproxy.ProxyCtx) string {
|
||||
for _, src := range findScriptSrc(s) {
|
||||
if !jqueryMatcher.MatchString(src) {
|
||||
continue
|
||||
}
|
||||
prev, ok := m[ctx.Req.Host]
|
||||
if ok {
|
||||
if prev != src {
|
||||
ctx.Warnf("In %v, Contradicting jqueries %v %v",
|
||||
ctx.Req.URL, prev, src)
|
||||
break
|
||||
}
|
||||
} else {
|
||||
ctx.Warnf("%s uses jquery %s", ctx.Req.Host, src)
|
||||
m[ctx.Req.Host] = src
|
||||
}
|
||||
}
|
||||
return s
|
||||
}))
|
||||
return proxy
|
||||
}
|
||||
|
||||
func main() {
|
||||
proxy := NewJqueryVersionProxy()
|
||||
log.Fatal(http.ListenAndServe(":8080", proxy))
|
||||
}
|
323
vendor/github.com/elazarl/goproxy/examples/goproxy-jquery-version/php_man.html
generated
vendored
323
vendor/github.com/elazarl/goproxy/examples/goproxy-jquery-version/php_man.html
generated
vendored
File diff suppressed because one or more lines are too long
1610
vendor/github.com/elazarl/goproxy/examples/goproxy-jquery-version/w3schools.html
generated
vendored
1610
vendor/github.com/elazarl/goproxy/examples/goproxy-jquery-version/w3schools.html
generated
vendored
File diff suppressed because it is too large
Load diff
21
vendor/github.com/elazarl/goproxy/examples/goproxy-no-reddit-at-worktime/README.md
generated
vendored
21
vendor/github.com/elazarl/goproxy/examples/goproxy-no-reddit-at-worktime/README.md
generated
vendored
|
@ -1,21 +0,0 @@
|
|||
# Request Filtering
|
||||
|
||||
`goproxy-no-reddit-at-work` starts an HTTP proxy on :8080. It denies requests
|
||||
to "www.reddit.com" made between 8am to 5pm inclusive, local time.
|
||||
|
||||
Start it in one shell:
|
||||
|
||||
```sh
|
||||
$ goproxy-no-reddit-at-work
|
||||
```
|
||||
|
||||
Fetch reddit in another:
|
||||
|
||||
```sh
|
||||
$ http_proxy=http://127.0.0.1:8080 wget -O - http://www.reddit.com
|
||||
--2015-04-11 16:59:01-- http://www.reddit.com/
|
||||
Connecting to 127.0.0.1:8080... connected.
|
||||
Proxy request sent, awaiting response... 403 Forbidden
|
||||
2015-04-11 16:59:01 ERROR 403: Forbidden.
|
||||
```
|
||||
|
25
vendor/github.com/elazarl/goproxy/examples/goproxy-no-reddit-at-worktime/noreddit.go
generated
vendored
25
vendor/github.com/elazarl/goproxy/examples/goproxy-no-reddit-at-worktime/noreddit.go
generated
vendored
|
@ -1,25 +0,0 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"github.com/elazarl/goproxy"
|
||||
"log"
|
||||
"net/http"
|
||||
"time"
|
||||
)
|
||||
|
||||
func main() {
|
||||
proxy := goproxy.NewProxyHttpServer()
|
||||
proxy.OnRequest(goproxy.DstHostIs("www.reddit.com")).DoFunc(
|
||||
func(r *http.Request, ctx *goproxy.ProxyCtx) (*http.Request, *http.Response) {
|
||||
h, _, _ := time.Now().Clock()
|
||||
if h >= 8 && h <= 17 {
|
||||
return r, goproxy.NewResponse(r,
|
||||
goproxy.ContentTypeText, http.StatusForbidden,
|
||||
"Don't waste your time!")
|
||||
} else {
|
||||
ctx.Warnf("clock: %d, you can waste your time...", h)
|
||||
}
|
||||
return r, nil
|
||||
})
|
||||
log.Fatalln(http.ListenAndServe(":8080", proxy))
|
||||
}
|
25
vendor/github.com/elazarl/goproxy/examples/goproxy-sokeepalive/sokeepalive.go
generated
vendored
25
vendor/github.com/elazarl/goproxy/examples/goproxy-sokeepalive/sokeepalive.go
generated
vendored
|
@ -1,25 +0,0 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"github.com/elazarl/goproxy"
|
||||
"log"
|
||||
"net"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
func main() {
|
||||
verbose := flag.Bool("v", false, "should every proxy request be logged to stdout")
|
||||
addr := flag.String("addr", ":8080", "proxy listen address")
|
||||
flag.Parse()
|
||||
proxy := goproxy.NewProxyHttpServer()
|
||||
proxy.Tr.Dial = func(network, addr string) (c net.Conn, err error) {
|
||||
c, err = net.Dial(network, addr)
|
||||
if c, ok := c.(*net.TCPConn); err == nil && ok {
|
||||
c.SetKeepAlive(true)
|
||||
}
|
||||
return
|
||||
}
|
||||
proxy.Verbose = *verbose
|
||||
log.Fatal(http.ListenAndServe(*addr, proxy))
|
||||
}
|
24
vendor/github.com/elazarl/goproxy/examples/goproxy-sslstrip/sslstrip.go
generated
vendored
24
vendor/github.com/elazarl/goproxy/examples/goproxy-sslstrip/sslstrip.go
generated
vendored
|
@ -1,24 +0,0 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"github.com/elazarl/goproxy"
|
||||
"log"
|
||||
"flag"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
func main() {
|
||||
verbose := flag.Bool("v", false, "should every proxy request be logged to stdout")
|
||||
addr := flag.String("addr", ":8080", "proxy listen address")
|
||||
flag.Parse()
|
||||
proxy := goproxy.NewProxyHttpServer()
|
||||
proxy.OnRequest().HandleConnect(goproxy.AlwaysMitm)
|
||||
proxy.OnRequest().DoFunc(func (req *http.Request, ctx *goproxy.ProxyCtx) (*http.Request, *http.Response) {
|
||||
if req.URL.Scheme == "https" {
|
||||
req.URL.Scheme = "http"
|
||||
}
|
||||
return req, nil
|
||||
})
|
||||
proxy.Verbose = *verbose
|
||||
log.Fatal(http.ListenAndServe(*addr, proxy))
|
||||
}
|
43
vendor/github.com/elazarl/goproxy/examples/goproxy-stats/README.md
generated
vendored
43
vendor/github.com/elazarl/goproxy/examples/goproxy-stats/README.md
generated
vendored
|
@ -1,43 +0,0 @@
|
|||
# Gather Browsing Statistics
|
||||
|
||||
`goproxy-stats` starts an HTTP proxy on :8080, counts the bytes received for
|
||||
web resources and prints the cumulative sum per URL every 20 seconds.
|
||||
|
||||
Start it in one shell:
|
||||
|
||||
```sh
|
||||
goproxy-stats
|
||||
```
|
||||
|
||||
Fetch goproxy homepage in another:
|
||||
|
||||
```sh
|
||||
mkdir tmp
|
||||
cd tmp
|
||||
http_proxy=http://127.0.0.1:8080 wget -r -l 1 -H \
|
||||
http://ripper234.com/p/introducing-goproxy-light-http-proxy/
|
||||
```
|
||||
|
||||
Stop it after a moment. `goproxy-stats` should eventually print:
|
||||
```sh
|
||||
listening on :8080
|
||||
statistics
|
||||
http://www.telerik.com/fiddler -> 84335
|
||||
http://msmvps.com/robots.txt -> 157
|
||||
http://eli.thegreenplace.net/robots.txt -> 294
|
||||
http://www.phdcomics.com/robots.txt -> 211
|
||||
http://resharper.blogspot.com/robots.txt -> 221
|
||||
http://idanz.blogli.co.il/robots.txt -> 271
|
||||
http://ripper234.com/p/introducing-goproxy-light-http-proxy/ -> 44407
|
||||
http://live.gnome.org/robots.txt -> 298
|
||||
http://ponetium.wordpress.com/robots.txt -> 178
|
||||
http://pilaheleg.blogli.co.il/robots.txt -> 321
|
||||
http://pilaheleg.wordpress.com/robots.txt -> 178
|
||||
http://blogli.co.il/ -> 9165
|
||||
http://nimrod-code.org/robots.txt -> 289
|
||||
http://www.joelonsoftware.com/robots.txt -> 1245
|
||||
http://top-performance.blogspot.com/robots.txt -> 227
|
||||
http://ooc-lang.org/robots.txt -> 345
|
||||
http://blogs.jetbrains.com/robots.txt -> 293
|
||||
```
|
||||
|
66
vendor/github.com/elazarl/goproxy/examples/goproxy-stats/main.go
generated
vendored
66
vendor/github.com/elazarl/goproxy/examples/goproxy-stats/main.go
generated
vendored
|
@ -1,66 +0,0 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/elazarl/goproxy"
|
||||
"github.com/elazarl/goproxy/ext/html"
|
||||
"io"
|
||||
"log"
|
||||
. "net/http"
|
||||
"time"
|
||||
)
|
||||
|
||||
type Count struct {
|
||||
Id string
|
||||
Count int64
|
||||
}
|
||||
type CountReadCloser struct {
|
||||
Id string
|
||||
R io.ReadCloser
|
||||
ch chan<- Count
|
||||
nr int64
|
||||
}
|
||||
|
||||
func (c *CountReadCloser) Read(b []byte) (n int, err error) {
|
||||
n, err = c.R.Read(b)
|
||||
c.nr += int64(n)
|
||||
return
|
||||
}
|
||||
func (c CountReadCloser) Close() error {
|
||||
c.ch <- Count{c.Id, c.nr}
|
||||
return c.R.Close()
|
||||
}
|
||||
|
||||
func main() {
|
||||
proxy := goproxy.NewProxyHttpServer()
|
||||
timer := make(chan bool)
|
||||
ch := make(chan Count, 10)
|
||||
go func() {
|
||||
for {
|
||||
time.Sleep(20 * time.Second)
|
||||
timer <- true
|
||||
}
|
||||
}()
|
||||
go func() {
|
||||
m := make(map[string]int64)
|
||||
for {
|
||||
select {
|
||||
case c := <-ch:
|
||||
m[c.Id] = m[c.Id] + c.Count
|
||||
case <-timer:
|
||||
fmt.Printf("statistics\n")
|
||||
for k, v := range m {
|
||||
fmt.Printf("%s -> %d\n", k, v)
|
||||
}
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
// IsWebRelatedText filters on html/javascript/css resources
|
||||
proxy.OnResponse(goproxy_html.IsWebRelatedText).DoFunc(func(resp *Response, ctx *goproxy.ProxyCtx) *Response {
|
||||
resp.Body = &CountReadCloser{ctx.Req.URL.String(), resp.Body, ch, 0}
|
||||
return resp
|
||||
})
|
||||
fmt.Printf("listening on :8080\n")
|
||||
log.Fatal(ListenAndServe(":8080", proxy))
|
||||
}
|
17
vendor/github.com/elazarl/goproxy/examples/goproxy-transparent/README.md
generated
vendored
17
vendor/github.com/elazarl/goproxy/examples/goproxy-transparent/README.md
generated
vendored
|
@ -1,17 +0,0 @@
|
|||
# Transparent Proxy
|
||||
|
||||
This transparent example in goproxy is meant to show how to transparenty proxy and hijack all http and https connections while doing a man-in-the-middle to the TLS session. It requires that goproxy sees all the packets traversing out to the internet. Linux iptables rules deal with changing the source/destination IPs to act transparently, but you do need to setup your network configuration so that goproxy is a mandatory stop on the outgoing route. Primarily you can do this by placing the proxy inline. goproxy does not have any WCCP support itself; patches welcome.
|
||||
|
||||
## Why not explicit?
|
||||
|
||||
Transparent proxies are more difficult to maintain and setup from a server side, but they require no configuration on the client(s) which could be in unmanaged systems or systems that don't support a proxy configuration. See the [eavesdropper example](https://github.com/elazarl/goproxy/blob/master/examples/goproxy-eavesdropper/main.go) if you want to see an explicit proxy example.
|
||||
|
||||
## Potential Issues
|
||||
|
||||
Support for very old clients using HTTPS will fail. Clients need to send the SNI value in the TLS ClientHello which most modern clients do these days, but old clients will break.
|
||||
|
||||
If you're routing table allows for it, an explicit http request to goproxy will cause it to fail in an endless loop since it will try to request resources from itself repeatedly. This could be solved in the goproxy code by looking up the hostnames, but it adds a delay that is much easier/faster to handle on the routing side.
|
||||
|
||||
## Routing Rules
|
||||
|
||||
Example routing rules are included in [proxy.sh](https://github.com/elazarl/goproxy/blob/master/examples/goproxy-transparent/proxy.sh) but are best when setup using your distribution's configuration.
|
29
vendor/github.com/elazarl/goproxy/examples/goproxy-transparent/proxy.sh
generated
vendored
29
vendor/github.com/elazarl/goproxy/examples/goproxy-transparent/proxy.sh
generated
vendored
|
@ -1,29 +0,0 @@
|
|||
#!/bin/sh
|
||||
# goproxy IP
|
||||
GOPROXY_SERVER="10.10.10.1"
|
||||
# goproxy port
|
||||
GOPROXY_PORT="3129"
|
||||
GOPROXY_PORT_TLS="3128"
|
||||
# DO NOT MODIFY BELOW
|
||||
# Load IPTABLES modules for NAT and IP conntrack support
|
||||
modprobe ip_conntrack
|
||||
modprobe ip_conntrack_ftp
|
||||
echo 1 > /proc/sys/net/ipv4/ip_forward
|
||||
echo 2 > /proc/sys/net/ipv4/conf/all/rp_filter
|
||||
|
||||
# Clean old firewall
|
||||
iptables -t nat -F
|
||||
iptables -t nat -X
|
||||
iptables -t mangle -F
|
||||
iptables -t mangle -X
|
||||
|
||||
# Write new rules
|
||||
iptables -t nat -A PREROUTING -s $GOPROXY_SERVER -p tcp --dport $GOPROXY_PORT -j ACCEPT
|
||||
iptables -t nat -A PREROUTING -s $GOPROXY_SERVER -p tcp --dport $GOPROXY_PORT_TLS -j ACCEPT
|
||||
iptables -t nat -A PREROUTING -p tcp --dport 80 -j DNAT --to-destination $GOPROXY_SERVER:$GOPROXY_PORT
|
||||
iptables -t nat -A PREROUTING -p tcp --dport 443 -j DNAT --to-destination $GOPROXY_SERVER:$GOPROXY_PORT_TLS
|
||||
# The following line supports using goproxy as an explicit proxy in addition
|
||||
iptables -t nat -A PREROUTING -p tcp --dport 8080 -j DNAT --to-destination $GOPROXY_SERVER:$GOPROXY_PORT
|
||||
iptables -t nat -A POSTROUTING -j MASQUERADE
|
||||
iptables -t mangle -A PREROUTING -p tcp --dport $GOPROXY_PORT -j DROP
|
||||
iptables -t mangle -A PREROUTING -p tcp --dport $GOPROXY_PORT_TLS -j DROP
|
148
vendor/github.com/elazarl/goproxy/examples/goproxy-transparent/transparent.go
generated
vendored
148
vendor/github.com/elazarl/goproxy/examples/goproxy-transparent/transparent.go
generated
vendored
|
@ -1,148 +0,0 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"flag"
|
||||
"fmt"
|
||||
"log"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"regexp"
|
||||
|
||||
"github.com/elazarl/goproxy"
|
||||
"github.com/inconshreveable/go-vhost"
|
||||
)
|
||||
|
||||
func orPanic(err error) {
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
verbose := flag.Bool("v", true, "should every proxy request be logged to stdout")
|
||||
http_addr := flag.String("httpaddr", ":3129", "proxy http listen address")
|
||||
https_addr := flag.String("httpsaddr", ":3128", "proxy https listen address")
|
||||
flag.Parse()
|
||||
|
||||
proxy := goproxy.NewProxyHttpServer()
|
||||
proxy.Verbose = *verbose
|
||||
if proxy.Verbose {
|
||||
log.Printf("Server starting up! - configured to listen on http interface %s and https interface %s", *http_addr, *https_addr)
|
||||
}
|
||||
|
||||
proxy.NonproxyHandler = http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
|
||||
if req.Host == "" {
|
||||
fmt.Fprintln(w, "Cannot handle requests without Host header, e.g., HTTP 1.0")
|
||||
return
|
||||
}
|
||||
req.URL.Scheme = "http"
|
||||
req.URL.Host = req.Host
|
||||
proxy.ServeHTTP(w, req)
|
||||
})
|
||||
proxy.OnRequest(goproxy.ReqHostMatches(regexp.MustCompile("^.*$"))).
|
||||
HandleConnect(goproxy.AlwaysMitm)
|
||||
proxy.OnRequest(goproxy.ReqHostMatches(regexp.MustCompile("^.*:80$"))).
|
||||
HijackConnect(func(req *http.Request, client net.Conn, ctx *goproxy.ProxyCtx) {
|
||||
defer func() {
|
||||
if e := recover(); e != nil {
|
||||
ctx.Logf("error connecting to remote: %v", e)
|
||||
client.Write([]byte("HTTP/1.1 500 Cannot reach destination\r\n\r\n"))
|
||||
}
|
||||
client.Close()
|
||||
}()
|
||||
clientBuf := bufio.NewReadWriter(bufio.NewReader(client), bufio.NewWriter(client))
|
||||
remote, err := connectDial(proxy, "tcp", req.URL.Host)
|
||||
orPanic(err)
|
||||
remoteBuf := bufio.NewReadWriter(bufio.NewReader(remote), bufio.NewWriter(remote))
|
||||
for {
|
||||
req, err := http.ReadRequest(clientBuf.Reader)
|
||||
orPanic(err)
|
||||
orPanic(req.Write(remoteBuf))
|
||||
orPanic(remoteBuf.Flush())
|
||||
resp, err := http.ReadResponse(remoteBuf.Reader, req)
|
||||
orPanic(err)
|
||||
orPanic(resp.Write(clientBuf.Writer))
|
||||
orPanic(clientBuf.Flush())
|
||||
}
|
||||
})
|
||||
|
||||
go func() {
|
||||
log.Fatalln(http.ListenAndServe(*http_addr, proxy))
|
||||
}()
|
||||
|
||||
// listen to the TLS ClientHello but make it a CONNECT request instead
|
||||
ln, err := net.Listen("tcp", *https_addr)
|
||||
if err != nil {
|
||||
log.Fatalf("Error listening for https connections - %v", err)
|
||||
}
|
||||
for {
|
||||
c, err := ln.Accept()
|
||||
if err != nil {
|
||||
log.Printf("Error accepting new connection - %v", err)
|
||||
continue
|
||||
}
|
||||
go func(c net.Conn) {
|
||||
tlsConn, err := vhost.TLS(c)
|
||||
if err != nil {
|
||||
log.Printf("Error accepting new connection - %v", err)
|
||||
}
|
||||
if tlsConn.Host() == "" {
|
||||
log.Printf("Cannot support non-SNI enabled clients")
|
||||
return
|
||||
}
|
||||
connectReq := &http.Request{
|
||||
Method: "CONNECT",
|
||||
URL: &url.URL{
|
||||
Opaque: tlsConn.Host(),
|
||||
Host: net.JoinHostPort(tlsConn.Host(), "443"),
|
||||
},
|
||||
Host: tlsConn.Host(),
|
||||
Header: make(http.Header),
|
||||
}
|
||||
resp := dumbResponseWriter{tlsConn}
|
||||
proxy.ServeHTTP(resp, connectReq)
|
||||
}(c)
|
||||
}
|
||||
}
|
||||
|
||||
// copied/converted from https.go
|
||||
func dial(proxy *goproxy.ProxyHttpServer, network, addr string) (c net.Conn, err error) {
|
||||
if proxy.Tr.Dial != nil {
|
||||
return proxy.Tr.Dial(network, addr)
|
||||
}
|
||||
return net.Dial(network, addr)
|
||||
}
|
||||
|
||||
// copied/converted from https.go
|
||||
func connectDial(proxy *goproxy.ProxyHttpServer, network, addr string) (c net.Conn, err error) {
|
||||
if proxy.ConnectDial == nil {
|
||||
return dial(proxy, network, addr)
|
||||
}
|
||||
return proxy.ConnectDial(network, addr)
|
||||
}
|
||||
|
||||
type dumbResponseWriter struct {
|
||||
net.Conn
|
||||
}
|
||||
|
||||
func (dumb dumbResponseWriter) Header() http.Header {
|
||||
panic("Header() should not be called on this ResponseWriter")
|
||||
}
|
||||
|
||||
func (dumb dumbResponseWriter) Write(buf []byte) (int, error) {
|
||||
if bytes.Equal(buf, []byte("HTTP/1.0 200 OK\r\n\r\n")) {
|
||||
return len(buf), nil // throw away the HTTP OK response from the faux CONNECT request
|
||||
}
|
||||
return dumb.Conn.Write(buf)
|
||||
}
|
||||
|
||||
func (dumb dumbResponseWriter) WriteHeader(code int) {
|
||||
panic("WriteHeader() should not be called on this ResponseWriter")
|
||||
}
|
||||
|
||||
func (dumb dumbResponseWriter) Hijack() (net.Conn, *bufio.ReadWriter, error) {
|
||||
return dumb, bufio.NewReadWriter(bufio.NewReader(dumb), bufio.NewWriter(dumb)), nil
|
||||
}
|
26
vendor/github.com/elazarl/goproxy/examples/goproxy-upside-down-ternet/main.go
generated
vendored
26
vendor/github.com/elazarl/goproxy/examples/goproxy-upside-down-ternet/main.go
generated
vendored
|
@ -1,26 +0,0 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"github.com/elazarl/goproxy"
|
||||
"github.com/elazarl/goproxy/ext/image"
|
||||
"image"
|
||||
"log"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
func main() {
|
||||
proxy := goproxy.NewProxyHttpServer()
|
||||
proxy.OnResponse().Do(goproxy_image.HandleImage(func(img image.Image, ctx *goproxy.ProxyCtx) image.Image {
|
||||
dx, dy := img.Bounds().Dx(), img.Bounds().Dy()
|
||||
|
||||
nimg := image.NewRGBA(img.Bounds())
|
||||
for i := 0; i < dx; i++ {
|
||||
for j := 0; j <= dy; j++ {
|
||||
nimg.Set(i, j, img.At(i, dy-j-1))
|
||||
}
|
||||
}
|
||||
return nimg
|
||||
}))
|
||||
proxy.Verbose = true
|
||||
log.Fatal(http.ListenAndServe(":8080", proxy))
|
||||
}
|
91
vendor/github.com/elazarl/goproxy/examples/goproxy-yui-minify/yui.go
generated
vendored
91
vendor/github.com/elazarl/goproxy/examples/goproxy-yui-minify/yui.go
generated
vendored
|
@ -1,91 +0,0 @@
|
|||
// This example would minify standalone Javascript files (identified by their content type)
|
||||
// using the command line utility YUI compressor http://yui.github.io/yuicompressor/
|
||||
// Example usage:
|
||||
//
|
||||
// ./yui -java /usr/local/bin/java -yuicompressor ~/Downloads/yuicompressor-2.4.8.jar
|
||||
// $ curl -vx localhost:8080 http://golang.org/lib/godoc/godocs.js
|
||||
// (function(){function g(){var u=$("#search");if(u.length===0){return}function t(){if(....
|
||||
// $ curl http://golang.org/lib/godoc/godocs.js | head -n 3
|
||||
// // Copyright 2012 The Go Authors. All rights reserved.
|
||||
// // Use of this source code is governed by a BSD-style
|
||||
// // license that can be found in the LICENSE file.
|
||||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path"
|
||||
"strings"
|
||||
|
||||
"github.com/elazarl/goproxy"
|
||||
)
|
||||
|
||||
func main() {
|
||||
verbose := flag.Bool("v", false, "should every proxy request be logged to stdout")
|
||||
addr := flag.String("addr", ":8080", "proxy listen address")
|
||||
java := flag.String("javapath", "java", "where the Java executable is located")
|
||||
yuicompressor := flag.String("yuicompressor", "", "where the yuicompressor is located, assumed to be in CWD")
|
||||
yuicompressordir := flag.String("yuicompressordir", ".", "a folder to search yuicompressor in, will be ignored if yuicompressor is set")
|
||||
flag.Parse()
|
||||
if *yuicompressor == "" {
|
||||
files, err := ioutil.ReadDir(*yuicompressordir)
|
||||
if err != nil {
|
||||
log.Fatal("Cannot find yuicompressor jar")
|
||||
}
|
||||
for _, file := range files {
|
||||
if strings.HasPrefix(file.Name(), "yuicompressor") && strings.HasSuffix(file.Name(), ".jar") {
|
||||
c := path.Join(*yuicompressordir, file.Name())
|
||||
yuicompressor = &c
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
if *yuicompressor == "" {
|
||||
log.Fatal("Can't find yuicompressor jar, searched yuicompressor*.jar in dir ", *yuicompressordir)
|
||||
}
|
||||
if _, err := os.Stat(*yuicompressor); os.IsNotExist(err) {
|
||||
log.Fatal("Can't find yuicompressor jar specified ", *yuicompressor)
|
||||
}
|
||||
proxy := goproxy.NewProxyHttpServer()
|
||||
proxy.Verbose = *verbose
|
||||
proxy.OnResponse().DoFunc(func(resp *http.Response, ctx *goproxy.ProxyCtx) *http.Response {
|
||||
contentType := resp.Header.Get("Content-Type")
|
||||
if contentType == "application/javascript" || contentType == "application/x-javascript" {
|
||||
// in real code, response should be streamed as well
|
||||
var err error
|
||||
cmd := exec.Command(*java, "-jar", *yuicompressor, "--type", "js")
|
||||
cmd.Stdin = resp.Body
|
||||
resp.Body, err = cmd.StdoutPipe()
|
||||
if err != nil {
|
||||
ctx.Warnf("Cannot minify content in %v: %v", ctx.Req.URL, err)
|
||||
return goproxy.TextResponse(ctx.Req, "Error getting stdout pipe")
|
||||
}
|
||||
stderr, err := cmd.StderrPipe()
|
||||
if err != nil {
|
||||
ctx.Logf("Error obtaining stderr from yuicompress: %s", err)
|
||||
return goproxy.TextResponse(ctx.Req, "Error getting stderr pipe")
|
||||
}
|
||||
if err := cmd.Start(); err != nil {
|
||||
ctx.Warnf("Cannot minify content in %v: %v", ctx.Req.URL, err)
|
||||
}
|
||||
go func() {
|
||||
defer stderr.Close()
|
||||
const kb = 1024
|
||||
msg, err := ioutil.ReadAll(&io.LimitedReader{stderr, 50 * kb})
|
||||
if len(msg) != 0 {
|
||||
ctx.Logf("Error executing yuicompress: %s", string(msg))
|
||||
}
|
||||
if err != nil {
|
||||
ctx.Logf("Error reading stderr from yuicompress: %s", string(msg))
|
||||
}
|
||||
}()
|
||||
}
|
||||
return resp
|
||||
})
|
||||
log.Fatal(http.ListenAndServe(*addr, proxy))
|
||||
}
|
76
vendor/github.com/elazarl/goproxy/ext/auth/basic.go
generated
vendored
76
vendor/github.com/elazarl/goproxy/ext/auth/basic.go
generated
vendored
|
@ -1,76 +0,0 @@
|
|||
package auth
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/base64"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/elazarl/goproxy"
|
||||
)
|
||||
|
||||
var unauthorizedMsg = []byte("407 Proxy Authentication Required")
|
||||
|
||||
func BasicUnauthorized(req *http.Request, realm string) *http.Response {
|
||||
// TODO(elazar): verify realm is well formed
|
||||
return &http.Response{
|
||||
StatusCode: 407,
|
||||
ProtoMajor: 1,
|
||||
ProtoMinor: 1,
|
||||
Request: req,
|
||||
Header: http.Header{"Proxy-Authenticate": []string{"Basic realm=" + realm}},
|
||||
Body: ioutil.NopCloser(bytes.NewBuffer(unauthorizedMsg)),
|
||||
ContentLength: int64(len(unauthorizedMsg)),
|
||||
}
|
||||
}
|
||||
|
||||
var proxyAuthorizationHeader = "Proxy-Authorization"
|
||||
|
||||
func auth(req *http.Request, f func(user, passwd string) bool) bool {
|
||||
authheader := strings.SplitN(req.Header.Get(proxyAuthorizationHeader), " ", 2)
|
||||
req.Header.Del(proxyAuthorizationHeader)
|
||||
if len(authheader) != 2 || authheader[0] != "Basic" {
|
||||
return false
|
||||
}
|
||||
userpassraw, err := base64.StdEncoding.DecodeString(authheader[1])
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
userpass := strings.SplitN(string(userpassraw), ":", 2)
|
||||
if len(userpass) != 2 {
|
||||
return false
|
||||
}
|
||||
return f(userpass[0], userpass[1])
|
||||
}
|
||||
|
||||
// Basic returns a basic HTTP authentication handler for requests
|
||||
//
|
||||
// You probably want to use auth.ProxyBasic(proxy) to enable authentication for all proxy activities
|
||||
func Basic(realm string, f func(user, passwd string) bool) goproxy.ReqHandler {
|
||||
return goproxy.FuncReqHandler(func(req *http.Request, ctx *goproxy.ProxyCtx) (*http.Request, *http.Response) {
|
||||
if !auth(req, f) {
|
||||
return nil, BasicUnauthorized(req, realm)
|
||||
}
|
||||
return req, nil
|
||||
})
|
||||
}
|
||||
|
||||
// BasicConnect returns a basic HTTP authentication handler for CONNECT requests
|
||||
//
|
||||
// You probably want to use auth.ProxyBasic(proxy) to enable authentication for all proxy activities
|
||||
func BasicConnect(realm string, f func(user, passwd string) bool) goproxy.HttpsHandler {
|
||||
return goproxy.FuncHttpsHandler(func(host string, ctx *goproxy.ProxyCtx) (*goproxy.ConnectAction, string) {
|
||||
if !auth(ctx.Req, f) {
|
||||
ctx.Resp = BasicUnauthorized(ctx.Req, realm)
|
||||
return goproxy.RejectConnect, host
|
||||
}
|
||||
return goproxy.OkConnect, host
|
||||
})
|
||||
}
|
||||
|
||||
// ProxyBasic will force HTTP authentication before any request to the proxy is processed
|
||||
func ProxyBasic(proxy *goproxy.ProxyHttpServer, realm string, f func(user, passwd string) bool) {
|
||||
proxy.OnRequest().Do(Basic(realm, f))
|
||||
proxy.OnRequest().HandleConnect(BasicConnect(realm, f))
|
||||
}
|
175
vendor/github.com/elazarl/goproxy/ext/auth/basic_test.go
generated
vendored
175
vendor/github.com/elazarl/goproxy/ext/auth/basic_test.go
generated
vendored
|
@ -1,175 +0,0 @@
|
|||
package auth_test
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"net/url"
|
||||
"os"
|
||||
"os/exec"
|
||||
"os/signal"
|
||||
"sync/atomic"
|
||||
"testing"
|
||||
|
||||
"github.com/elazarl/goproxy"
|
||||
"github.com/elazarl/goproxy/ext/auth"
|
||||
)
|
||||
|
||||
type ConstantHanlder string
|
||||
|
||||
func (h ConstantHanlder) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
io.WriteString(w, string(h))
|
||||
}
|
||||
|
||||
func oneShotProxy(proxy *goproxy.ProxyHttpServer) (client *http.Client, s *httptest.Server) {
|
||||
s = httptest.NewServer(proxy)
|
||||
|
||||
proxyUrl, _ := url.Parse(s.URL)
|
||||
tr := &http.Transport{Proxy: http.ProxyURL(proxyUrl)}
|
||||
client = &http.Client{Transport: tr}
|
||||
return
|
||||
}
|
||||
|
||||
func times(n int, s string) string {
|
||||
r := make([]byte, 0, n*len(s))
|
||||
for i := 0; i < n; i++ {
|
||||
r = append(r, s...)
|
||||
}
|
||||
return string(r)
|
||||
}
|
||||
|
||||
func TestBasicConnectAuthWithCurl(t *testing.T) {
|
||||
expected := ":c>"
|
||||
background := httptest.NewTLSServer(ConstantHanlder(expected))
|
||||
defer background.Close()
|
||||
proxy := goproxy.NewProxyHttpServer()
|
||||
proxy.OnRequest().HandleConnect(auth.BasicConnect("my_realm", func(user, passwd string) bool {
|
||||
return user == "user" && passwd == "open sesame"
|
||||
}))
|
||||
_, proxyserver := oneShotProxy(proxy)
|
||||
defer proxyserver.Close()
|
||||
|
||||
cmd := exec.Command("curl",
|
||||
"--silent", "--show-error", "--insecure",
|
||||
"-x", proxyserver.URL,
|
||||
"-U", "user:open sesame",
|
||||
"-p",
|
||||
"--url", background.URL+"/[1-3]",
|
||||
)
|
||||
out, err := cmd.CombinedOutput() // if curl got error, it'll show up in stderr
|
||||
if err != nil {
|
||||
t.Fatal(err, string(out))
|
||||
}
|
||||
finalexpected := times(3, expected)
|
||||
if string(out) != finalexpected {
|
||||
t.Error("Expected", finalexpected, "got", string(out))
|
||||
}
|
||||
}
|
||||
|
||||
func TestBasicAuthWithCurl(t *testing.T) {
|
||||
expected := ":c>"
|
||||
background := httptest.NewServer(ConstantHanlder(expected))
|
||||
defer background.Close()
|
||||
proxy := goproxy.NewProxyHttpServer()
|
||||
proxy.OnRequest().Do(auth.Basic("my_realm", func(user, passwd string) bool {
|
||||
return user == "user" && passwd == "open sesame"
|
||||
}))
|
||||
_, proxyserver := oneShotProxy(proxy)
|
||||
defer proxyserver.Close()
|
||||
|
||||
cmd := exec.Command("curl",
|
||||
"--silent", "--show-error",
|
||||
"-x", proxyserver.URL,
|
||||
"-U", "user:open sesame",
|
||||
"--url", background.URL+"/[1-3]",
|
||||
)
|
||||
out, err := cmd.CombinedOutput() // if curl got error, it'll show up in stderr
|
||||
if err != nil {
|
||||
t.Fatal(err, string(out))
|
||||
}
|
||||
finalexpected := times(3, expected)
|
||||
if string(out) != finalexpected {
|
||||
t.Error("Expected", finalexpected, "got", string(out))
|
||||
}
|
||||
}
|
||||
|
||||
func TestBasicAuth(t *testing.T) {
|
||||
expected := "hello"
|
||||
background := httptest.NewServer(ConstantHanlder(expected))
|
||||
defer background.Close()
|
||||
proxy := goproxy.NewProxyHttpServer()
|
||||
proxy.OnRequest().Do(auth.Basic("my_realm", func(user, passwd string) bool {
|
||||
return user == "user" && passwd == "open sesame"
|
||||
}))
|
||||
client, proxyserver := oneShotProxy(proxy)
|
||||
defer proxyserver.Close()
|
||||
|
||||
// without auth
|
||||
resp, err := client.Get(background.URL)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if resp.Header.Get("Proxy-Authenticate") != "Basic realm=my_realm" {
|
||||
t.Error("Expected Proxy-Authenticate header got", resp.Header.Get("Proxy-Authenticate"))
|
||||
}
|
||||
if resp.StatusCode != 407 {
|
||||
t.Error("Expected status 407 Proxy Authentication Required, got", resp.Status)
|
||||
}
|
||||
|
||||
// with auth
|
||||
req, err := http.NewRequest("GET", background.URL, nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
req.Header.Set("Proxy-Authorization",
|
||||
"Basic "+base64.StdEncoding.EncodeToString([]byte("user:open sesame")))
|
||||
resp, err = client.Do(req)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if resp.StatusCode != 200 {
|
||||
t.Error("Expected status 200 OK, got", resp.Status)
|
||||
}
|
||||
msg, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if string(msg) != "hello" {
|
||||
t.Errorf("Expected '%s', actual '%s'", expected, string(msg))
|
||||
}
|
||||
}
|
||||
|
||||
func TestWithBrowser(t *testing.T) {
|
||||
// an easy way to check if auth works with webserver
|
||||
// to test, run with
|
||||
// $ go test -run TestWithBrowser -- server
|
||||
// configure a browser to use the printed proxy address, use the proxy
|
||||
// and exit with Ctrl-C. It will throw error if your haven't acutally used the proxy
|
||||
if os.Args[len(os.Args)-1] != "server" {
|
||||
return
|
||||
}
|
||||
proxy := goproxy.NewProxyHttpServer()
|
||||
println("proxy localhost port 8082")
|
||||
access := int32(0)
|
||||
proxy.OnRequest().Do(auth.Basic("my_realm", func(user, passwd string) bool {
|
||||
atomic.AddInt32(&access, 1)
|
||||
return user == "user" && passwd == "1234"
|
||||
}))
|
||||
l, err := net.Listen("tcp", "localhost:8082")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
ch := make(chan os.Signal)
|
||||
signal.Notify(ch, os.Interrupt)
|
||||
go func() {
|
||||
<-ch
|
||||
l.Close()
|
||||
}()
|
||||
http.Serve(l, proxy)
|
||||
if access <= 0 {
|
||||
t.Error("No one accessed the proxy")
|
||||
}
|
||||
}
|
585
vendor/github.com/elazarl/goproxy/ext/html/cp1255.html
generated
vendored
585
vendor/github.com/elazarl/goproxy/ext/html/cp1255.html
generated
vendored
|
@ -1,585 +0,0 @@
|
|||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||||
|
||||
<html lang="he">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=windows-1255">
|
||||
<meta http-equiv="Content-Language" content="he"/>
|
||||
<!--meta http-equiv="Content-Type" content="text/html; charset=utf-8" /-->
|
||||
<META NAME="Keywords" CONTENT="àåðéáøñéèä, äåøàä îøçå÷, ÷åøñéí, Distance Learning, E-Learning, University, Education, Open, Courseware, Israel, Higher Education, Satellite, Telecourses, Courses, educational technology, computer-mediated, studies">
|
||||
<meta http-equiv="Content-Style-Type" content="text/css">
|
||||
<title>ãó äáéú ùì ùä"í</title>
|
||||
<link rel="alternate" href="rss/rss.xml" type="application/rss+xml" title="çãùåú åòãëåðéí îùä"í, äîøëæ ìùéìåá èëðåìåâéåú áäåøàä îøçå÷ áàåðéáøñéèä äôúåçä"/>
|
||||
<link rel="stylesheet" type="text/css" href="design/common.css">
|
||||
<link rel="stylesheet" type="text/css" href="design/news.css">
|
||||
|
||||
<script language="javascript" type="text/javascript" src="js_scripts/shoham_common.js"></script>
|
||||
<script language="JavaScript" src="include/email_unobfuscator.js" type="text/javascript"></script>
|
||||
<script type="text/javascript" src="/js_scripts/toolbox.js"></script>
|
||||
|
||||
<script type="text/javascript">
|
||||
var semester='2012b'; // current semester
|
||||
var hebrewSemester;
|
||||
|
||||
//js for the flash movie:
|
||||
function getSemester(){
|
||||
return semester;
|
||||
//return '2009a';
|
||||
}
|
||||
|
||||
setSemester(semester);
|
||||
switchLinkSemester(semester);
|
||||
createSuggestionScript();
|
||||
switchCoursesSuggestionSource(semester);
|
||||
|
||||
addLoadEvent(function() {
|
||||
|
||||
// ADD JAVASCRIPT EVENTS/FUNCTIONS ETC. YOU WANT TO BE CALLED ONLOAD HERE AND ONLY HERE
|
||||
|
||||
showHideMessage();
|
||||
//addIt();
|
||||
//setAddThis();
|
||||
|
||||
} )
|
||||
|
||||
|
||||
|
||||
var tBox = new QQtoolBox();
|
||||
|
||||
</script>
|
||||
|
||||
<!--script language="javascript" src="js_scripts/flash2.js"></script-->
|
||||
|
||||
<link rel="stylesheet" href="suggestion/suggestion.css" media="screen" type="text/css">
|
||||
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="container">
|
||||
<div id="header">
|
||||
<div id="header_right">
|
||||
<a href="/" target="_self" title="ùä"í"><img src="graphics_nhp/shoam_logo_s.jpg" border="0" alt="ùä"í" target="_self"></a>
|
||||
</div>
|
||||
|
||||
<div id="header_left">
|
||||
|
||||
<div id="header_left_op">
|
||||
<a href="http://www.openu.ac.il/" target="_self" title="àåôð'è"><img src="graphics_nhp/openu.gif" border="0" alt="àåôð'è"></a>
|
||||
</div>
|
||||
<!--div id="search"-->
|
||||
<!-- search_hp.html (START) -->
|
||||
|
||||
<!--script language="javascript" src="opusSearch.js" type="text/javascript"></script-->
|
||||
|
||||
<div id="search">
|
||||
|
||||
|
||||
<form name="form" action="http://www.google.co.il/search" id="simpleSearch" target="" method="get">
|
||||
<input type="text" id="as_q" name="as_q" onFocus="this.select()" value="çôùå áàúø æä åáàúøé ä÷åøñéí">
|
||||
<input type="hidden" id="hl" name="hl" value="iw">
|
||||
<input type="hidden" id="as_sitesearch" name="as_sitesearch" value="telem.openu.ac.il">
|
||||
<!--a id="button" title="çéôåù áâåâì" href="javascript:simpleSearch();"><span> çôù</span></a-->
|
||||
<a id="button" title="çéôåù áâåâì" onclick="form.submit()"><span> çôù</span></a>
|
||||
</form>
|
||||
|
||||
<div id="header_eng"><span class="eng"><a href="http://www-e.openu.ac.il/geninfor/shoham.html" target="_self" title="shoham english site">English</a></span></div>
|
||||
|
||||
</div>
|
||||
<!-- search_hp.html (END) -->
|
||||
<!--/div-->
|
||||
|
||||
</div>
|
||||
<!--end of header-->
|
||||
</div>
|
||||
|
||||
<div id="content">
|
||||
|
||||
<div id="text">
|
||||
|
||||
<div id="right">
|
||||
<div id="top_right">
|
||||
<div id="top_right_text">
|
||||
|
||||
<h1>ëðéñä ìàúøé ä÷åøñéí</h1>
|
||||
<!-- suggestion.htm (START) -->
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=windows-1255">
|
||||
<meta http-equiv="Content-Language" content="he"/>
|
||||
|
||||
<link rel="stylesheet" href="suggestion/suggestion.css" media="screen" type="text/css">
|
||||
|
||||
<style type="text/css">
|
||||
/* script suggestion CSS START */
|
||||
/* uri: don't touch this section unless your name is "Uri Shefi" */
|
||||
#suggestion_box{
|
||||
/*dawidth: 245px; */ /* causes some courses to disapear */
|
||||
border:solid 0px;
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
#course_suggestion{ /* input */
|
||||
direction: rtl;
|
||||
font-family: Arial, Verdana, Tahoma;
|
||||
font-size: 12px;
|
||||
border: 1px solid #CCCCCC;
|
||||
width: 170px;
|
||||
height:15px;
|
||||
|
||||
}
|
||||
.autocomplete{
|
||||
/* right: 178px; */
|
||||
width: 280px;
|
||||
}
|
||||
/* script suggestion CSS END */
|
||||
|
||||
.suggestion_button{
|
||||
border: 0px solid #CCCCCC;
|
||||
vertical-align:middle;
|
||||
cursor: pointer;
|
||||
|
||||
/*
|
||||
width:23px;
|
||||
height:19px;
|
||||
*/
|
||||
padding-bottom:2px;
|
||||
|
||||
/*cursor: hand;*/
|
||||
}
|
||||
#current_semester{
|
||||
|
||||
font-family: Arial, Verdana, Tahoma;
|
||||
font-size: 15px;
|
||||
text-transform: uppercase;
|
||||
width: 122px;
|
||||
|
||||
}
|
||||
#autoComplteMessageLayer{
|
||||
|
||||
}
|
||||
|
||||
#summerLink, #summerLink a{
|
||||
color: red;
|
||||
display: none;
|
||||
font-weight: bold;
|
||||
font-size: 15px;
|
||||
text-decoration: underline;
|
||||
cursor: hand;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div id="switch_semester_box">
|
||||
<span id="koteret">ñîñèø</span>
|
||||
<select id="current_semester" onChange="refreshSemester(this.options[this.selectedIndex].value);">
|
||||
<option value="2012b">2012 á (àáéá)</option>
|
||||
<option value="2012a">2012 à (ñúéå)</option>
|
||||
<option value="2011c">2011 â (÷éõ)</option>
|
||||
<option value="2011b">2011 á (àáéá)</option>
|
||||
<option value="2011a">2011 à (ñúéå)</option>
|
||||
<option value="2010c">2010 â (÷éõ)</option>
|
||||
<option value="2010b">2010 á (àáéá)</option>
|
||||
<option value="2010a">2010 à (ñúéå)</option>
|
||||
<option value="2009c">2009 â (÷éõ)</option>
|
||||
<option value="2009b">2009 á (àáéá)</option>
|
||||
<option value="2009a">2009 à (ñúéå)</option>
|
||||
<option value="2008c">2008 â (÷éõ)</option>
|
||||
<option value="2008b">2008 á (àáéá)</option>
|
||||
<option value="2008a">2008 à (ñúéå)</option>
|
||||
<option value="2007c">2007 â (÷éõ)</option>
|
||||
<option value="2007b">2007 á (àáéá)</option>
|
||||
<option value="2007a">2007 à (ñúéå)</option>
|
||||
<option value="2006c">2006 â (÷éõ)</option>
|
||||
<option value="2006b">2006 á (àáéá)</option>
|
||||
<option value="2006a">2006 à (ñúéå)</option>
|
||||
<option value="2005c">2005 â (÷éõ)</option>
|
||||
<option value="2005b">2005 á (àáéá)</option>
|
||||
<option value="2005a">2005 à (ñúéå)</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<!-- SEGGUESTION BOX (START) -->
|
||||
<div style="text-align: right; color:#404040" id="suggestion_box">
|
||||
ùí ÷åøñ àå îñôø ÷åøñ <div id="suggestion_course_display"></div><br/>
|
||||
<input type="text" id="course_suggestion" value="øùéîú ä÷åøñéí äîåöòéí áñîñèø äðáçø" maxlength="60" title="øùéîú ä÷åøñéí äîåöòéí áñîñèø æä"><img src="graphics_nhp/mgIcon2.jpg" onclick="evalChoice();" class="suggestion_button" alt="ìàúø ä÷åøñ" />
|
||||
<!--div id="autoComplteMessageLayer"></div-->
|
||||
<!--<span id='summerLink' onClick="refreshSemester('2011c');">ìñîñèø ÷éõ 2011â ìçõ ëàï</span>-->
|
||||
<span id='summerLink'><a href="courses_lists/courses_2011c.html">ìñîñèø ÷éõ 2011â ìçõ ëàï</a></span>
|
||||
</div>
|
||||
<!-- SEGGUESTION BOX (END) -->
|
||||
|
||||
|
||||
<div id="fulllist">
|
||||
<a href="courses_lists/courses_2009a.html" id="courses_full_link" target="_self"> ìøùéîú àúøé ä÷åøñéí åäîçì÷åú</a> <div id="courses_full_link_display"></div>
|
||||
</div>
|
||||
<!-- suggestion.htm (END) -->
|
||||
</div>
|
||||
<!--end of top_right-->
|
||||
</div>
|
||||
|
||||
<div id="bottom_right">
|
||||
<div id="bottom_right_text">
|
||||
<h1>öååúé äåøàä</h1>
|
||||
<div class="linklist_a">
|
||||
<a href="content/help_staff.html" target="_self" class="linklist_item_a" title="úîéëä åòæøä">úîéëä åòæøä</a><br>
|
||||
<a href="content/training.html" target="_self" class="linklist_item_a" title="äãøëåú ìñâì ääåøàä">äãøëåú ìñâì ääåøàä </a> <img src="graphics_nhp/star_bg_gray.gif" border="0" alt=""> <span class="new">çãù</span><br>
|
||||
<a href="http://telem.openu.ac.il/segel/" target="_self" class="linklist_item_a" title="àúø öååúé äåøàä">àúø öååúé äåøàä</a><br>
|
||||
<a href="http://telem.openu.ac.il/content/virtual_shoham.html" target="_self" class="linklist_item_a" title="ëéúä åéøèåàìéú">ëéúä åéøèåàìéú</a><br>
|
||||
<a href="http://telem.openu.ac.il/content/matalot_staff.html" target="_self" class="linklist_item_a" title="îòøëú äîèìåú">îòøëú äîèìåú</a><br>
|
||||
<a href="http://telem.openu.ac.il/tikshuv_prize/" target="_blank" class="linklist_item_a" title="úçøåú îú÷ùá îöèééï">úçøåú îú÷ùá îöèééï</a><br>
|
||||
<a href="http://telem.openu.ac.il/content/hp_search.html" target="_blank" class="linklist_item_a" title="çéôåù áàúøé ä÷åøñéí">çéôåù áàúøé ä÷åøñéí</a><br>
|
||||
<!--a href="http://telem.openu.ac.il/courses/resources/private/oracle_Brochure.pdf" target="_blank" class="linklist_item_a" title="äòìàú çåáøú ä÷åøñ ìàúø ">äòìàú çåáøú ä÷åøñ</a> (<a href="https://sheilta.apps.openu.ac.il/pls/myopr/BOOKLET.FIRST" target="_blank" title="ëðéñä ìîåøùéí">ëðéñä ìîåøùéí</a>)<!-- <img src="graphics_nhp/star_bg_gray.gif" border="0" alt=""> <span class="new">çãù</span>--><br-->
|
||||
<a href="http://www.openu.ac.il/surveys/teaching_reports.html" target="_blank" class="linklist_item_a" title="ãåçåú ñ÷ø äåøàä">ãåçåú ñ÷ø äåøàä</a> (<img border="0" src="graphics_nhp/content_img/lockg.gif" title="ëðéñä ìáòìé äøùàåú áìáã îúåê äàå"ô" alt="ëðéñä ìáòìé äøùàåú áìáã îúåê äàå"ô" />)
|
||||
<!-- <img src="graphics_nhp/star_bg_gray.gif" border="0" alt=""> <span class="new">çãù</span>--><br>
|
||||
|
||||
|
||||
<a href="https://sso.apps.openu.ac.il/login?T_PLACE=https://sheilta.apps.openu.ac.il/pls/myopr/PELE.FIRST" target="_blank" class="linklist_item_a" title="ôåøèì îðçéí">ôåøèì îðçéí </a>
|
||||
(<img border="0" src="graphics_nhp/content_img/lockg.gif" title="ëðéñä ìáòìé äøùàåú áìáã îúåê äàå"ô" alt="ëðéñä ìáòìé äøùàåú áìáã îúåê äàå"ô" />)
|
||||
|
||||
<!-- <img src="graphics_nhp/star_bg_gray.gif" border="0" alt=""> <span class="new">çãù</span>--><br>
|
||||
|
||||
|
||||
<a href="http://opal.openu.ac.il" title="ëðéñä ìñáéáú äìîéãä äçãùä" target="_blank" class="new">îòøëú àåÉôÌÈì</a><!-- <img src="graphics_nhp/star_bg_gray.gif" border="0" alt=""> <span class="new">çãù</span>--><br>
|
||||
|
||||
|
||||
|
||||
<a href="http://opal.openu.ac.il/course/view.php?id=107" title=" " target="_blank">ðéäåì àúøé ÷åøñéí - îãøéê ìîøëæéí</a> (<img border="0" src="graphics_nhp/content_img/lockg.gif" title="ëðéñä ìáòìé äøùàåú áìáã îúåê äàå"ô" alt="ëðéñä ìáòìé äøùàåú áìáã îúåê äàå"ô" />)
|
||||
<img src="graphics_nhp/star_bg_gray.gif" border="0" alt=""><span class="new">çãù</span><br>
|
||||
|
||||
|
||||
|
||||
<br>
|
||||
</div>
|
||||
|
||||
<h1>ñèåãðèéí</h1>
|
||||
<div class="linklist_a">
|
||||
<a href="/content/help_students.html" target="_self" class="linklist_item_a" title="úîéëä åòæøä">úîéëä åòæøä</a><br>
|
||||
<a href="https://sheilta.apps.openu.ac.il/pls/dmyopt2/user_form.first?p_from=http://telem.openu.ac.il/hp_files/html_files/user_info.html" target="_blank" class="linklist_item_a" title="òãëåï ôøèéí àéùééí">òãëåï ôøèéí àéùééí</a><br>
|
||||
|
||||
<a href="http://www.openu.ac.il/sheilta/" target="_blank" class="linklist_item_a" title="ùàéìú'à">ùàéìú"à</a><br>
|
||||
|
||||
<a href="https://sheilta.apps.openu.ac.il/pls/dmyopt2/LUACH_SHANA.first?p_time=" target="_blank" class="linklist_item_a" title="ìåç æîðéí îô'ä">ìåç æîðéí - îô"ä</a><br>
|
||||
|
||||
<a href="/content/matalot_stud.html" target="_self" class="linklist_item_a" title="îòøëú äîèìåú">îòøëú äîèìåú</a><br>
|
||||
|
||||
<a href="/content/ofek.html" target="_self" class="linklist_item_a" title="àåô÷">àåô÷ - ùéòåøéí áåéãéàå</a> <!--img src="graphics_nhp/star_bg_gray.gif" border="0" alt=""> <span class="new">çãù</span--><br>
|
||||
|
||||
|
||||
|
||||
<a href="http://telem.openu.ac.il/content/elluminate_support.html" target="_self" class="linklist_item_a" title=" ëéúä åéøèåàìéú (Elluminate)"> ëéúä åéøèåàìéú (Elluminate) </a><br>
|
||||
|
||||
|
||||
<!--<a href="http://telem.openu.ac.il/content/GoToMeeting.html" target="_self" class="linklist_item_a" title=" ëéúä åéøèåàìéú (GoToMeeting)"> ëéúä åéøèåàìéú (GoToMeeting) </a><br>-->
|
||||
|
||||
|
||||
<a href="/content/courseware.html" target="_self" class="linklist_item_a" title="îàâø äìåîãåú åäú÷ìéèåøéí">îàâø äìåîãåú åäú÷ìéèåøéí</a><br>
|
||||
|
||||
<a href="http://telem.openu.ac.il/academic-paper/index.htm" target="_blank" class="linklist_item_a" title="ëúéáú òáåãä ñîéðøéåðéú">ëúéáú òáåãä ñîéðøéåðéú (ìåîãä)</a><br>
|
||||
|
||||
<a href="http://estudy.openu.ac.il/opus/bin/en.jsp?enPage=AnnotationsPage&enDispWho=Annotations&enZone=Annotations" target="_blank" class="linklist_item_a" title="ëðéñä ìôð÷ñ äàéùé">ôð÷ñ àéùé</a><br>
|
||||
|
||||
|
||||
<a href="http://www.openu.ac.il/new-student/" target="_blank" class="linklist_item_a" title="àúø äñèåãðè">äîãøéê ìñèåãðè äçãù</a>
|
||||
<br>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<!--<div id="mashov_gen">
|
||||
<div class="mashov"><a href="http://forum.openu.ac.il/opus/bin/en.jsp?enZone=Forum117583" target="_blank" title="îùåá ìùä"í">ôåøåí îùåá - çåå ãòúëí òì àúøé ä÷åøñéí, äìåîãåú, åé÷é... </a></div>
|
||||
</div>-->
|
||||
</div>
|
||||
|
||||
<!--end of bootom_right-->
|
||||
</div>
|
||||
<!--end of right-->
|
||||
</div>
|
||||
|
||||
<div id="left">
|
||||
<div id="flash_zone" title="Falsh Movie" astyle="background:url(graphics_nhp/flash.jpg) 100 0 no-repeat;">
|
||||
<!-- <script type="text/javascript" src="js_scripts/flash.js"></script>
|
||||
--><!--must be after the last </boject> -->
|
||||
|
||||
<img src="graphics_nhp/flash.jpg" border="0" alt="rss" valign="left" align="abstop">
|
||||
</div>
|
||||
|
||||
<div id="message" class="messageHidden">
|
||||
|
||||
|
||||
<!--ôúéçú ñîñèø-->
|
||||
<!--spring-->
|
||||
<div class="tm">
|
||||
<div class="img">
|
||||
<IMG alt="" src="graphics_nhp/message_gifs/icon_spring.gif" border=0></div>
|
||||
<strong> àúøé 2012á ðôúçå ìñèåãðèéí. öååú ùä"í îàçì ìëí ñîñèø îåöìç.</strong>
|
||||
<span class="date">(4.3.12)</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!--center><img src="content/happy_holiday.gif" style="padding: 3px; margin: 3px;"></center-->
|
||||
|
||||
<div id="links_zone">
|
||||
|
||||
|
||||
<div id="links_right">
|
||||
<h1>
|
||||
<span class="news">çãùåú åòãëåðéí</span>
|
||||
<span class="rss">
|
||||
<span class="rss_text"><a href="content/rss_help.html" target="_blank" title="òæøä"><span id="rss_gif">?</span>rss </a><img src="graphics_nhp/rss.jpg" border="0" alt="rss" valign="left" align="abstop"></span></span>
|
||||
|
||||
|
||||
</h1>
|
||||
|
||||
<div id="rss_list">
|
||||
<ul class='newsBriefList'>
|
||||
|
||||
<li class='newsBriefItem'><a href='http://shohamnews.blogspot.com/2012/03/html5.html' target='_blank'>HTML5</a>
|
||||
<div class='newsBriefDate'>2012-03-21 12:45:00</div>
|
||||
</li>
|
||||
<li class='newsBriefItem'><a href='http://shohamnews.blogspot.com/2012/03/2012.html' target='_blank'>÷åì ÷åøà ìäâùú äöòåú ìëðñ îéè"ì äòùéøé 2012</a>
|
||||
<div class='newsBriefDate'>2012-03-07 12:52:00</div>
|
||||
</li>
|
||||
<li class='newsBriefItem'><a href='http://shohamnews.blogspot.com/2012/03/19312.html' target='_blank'>äæîðä ìäøöàä áñîéðø äîç÷ø ùì äîç÷ø ìç÷ø çãùðåú åùä"í - 19.3.12</a>
|
||||
<div class='newsBriefDate'>2012-03-07 09:03:00</div>
|
||||
</li>
|
||||
<li class='newsBriefItem'><a href='http://peer-news.blogspot.com/2012/01/blog-post_18.html' target='_blank'>ñôø ÷åìé ðåñó á÷åøñ â'ðåñééã: "äùîãú äòîéí äàéðãéàðéí ùì àîøé÷ä äñôøãéú</a>
|
||||
<div class='newsBriefDate'>2012-01-18 14:41:00</div>
|
||||
</li>
|
||||
<li class='newsBriefItem'><a href='http://peer-news.blogspot.com/2012/01/blog-post.html' target='_blank'>ñôø ÷åìé çãù á÷åøñ â'ðåñééã: "áéï âæòðåú ìâ'ðåñééã áòú äîåãøðéú</a>
|
||||
<div class='newsBriefDate'>2012-01-18 14:31:00</div>
|
||||
</li>
|
||||
<li class='newsBriefItem'><a href='http://peer-news.blogspot.com/2012/01/10934.html' target='_blank'>ëøê ðåñó á÷åøñ "áèäåáï - îåøã åøåîðèé÷ï" (10934)</a>
|
||||
<div class='newsBriefDate'>2012-01-15 14:21:00</div>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
|
||||
<div id="allnews">
|
||||
<div id="allnews_link">
|
||||
<a href="content/news.html"> ìøùéîä äîìàä</a>
|
||||
<!--a href="/content/news.html" target="_blank" title="ìøùéîú äòéãëåðéí äîìàä"-->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<div id="links_mid">
|
||||
<h1>ôòéìåéåú äîøëæ</h1>
|
||||
<div class="linklist">
|
||||
<a href="/content/about_shoham.html" target="_self" class="linklist_item" title="àåãåú ùä"í">àåãåú ùä"í</a><br>
|
||||
|
||||
|
||||
<a href="http://telem.openu.ac.il/content/about_shoham.html#organizational_structure" target="_self" class="linklist_item" title="îáðä àøâåðé">îáðä àøâåðé</a><!-- <img src="graphics_nhp/star_bg_gray.gif" border="0" alt=""> <span class="new">çãù</span>--> <br>
|
||||
|
||||
|
||||
<a href="/content/distance_edu.html" target="_self" class="linklist_item" title="äåøàä åìîéãä îøçå÷">äåøàä åìîéãä îøçå÷</a><br>
|
||||
<a href="/content/courses_sites.html" target="_self" class="linklist_item" title="àúøé ä÷åøñéí">àúøé ä÷åøñéí</a><br>
|
||||
|
||||
|
||||
<a href="http://telem.openu.ac.il/content/moodle_move.html" target="_self" class="linklist_item" title="ñáéáú ìîéãä çãùä áàå"ô Moodle">ñáéáú ìîéãä çãùä áàå"ô Moodle</a> <img src="graphics_nhp/star.gif" border="0" alt=""><br>
|
||||
|
||||
<a href="/content/vid_learning.html" target="_self" class="linklist_item" title=" åéãàå áäåøàä ñéðëøåðéú ">åéãàå åäåøàä ñéðëøåðéú</a> <img src="graphics_nhp/star.gif" border="0" alt=""> <span class="new">çãù</span><br>
|
||||
|
||||
|
||||
<a href="/content/virtual_class.html" target="_self" class="linklist_item" title=" ëéúä åéøèåàìéú - ìîéãä îäáéú ">ëéúä åéøèåàìéú - ìîéãä îäáéú</a> <!--<img src="graphics_nhp/star.gif" border="0" alt=""> <span class="new">çãù</span>--><br>
|
||||
|
||||
<!--<a href="http://telem.openu.ac.il/content/elluminate.html" target="_self" class="linklist_item" title="ëéúä åéøèåàìéú - ðéñåé Elluminate">ëéúä åéøèåàìéú - ðéñåé Elluminate</a> -->
|
||||
|
||||
|
||||
<a href="http://telem.openu.ac.il/content/video_classes.html" target="_self" class="linklist_item" title=" öéìåí îôâùé äðçéä áëéúåú">öéìåí îôâùé äðçéä áëéúåú</a><!-- <img src="graphics_nhp/star.gif" border="0" alt=""> <span class="new">çãù</span>--><br>
|
||||
|
||||
|
||||
<a href="/content/digital.html" target="_self" class="linklist_item" title="çåîøé ìîéãä àéðèøà÷èéáééí">çåîøé ìîéãä àéðèøà÷èéáééí</a> <!--<img src="graphics_nhp/star.gif" border="0" alt=""> <span class="new">çãù</span>--><br>
|
||||
<a href="/content/pedagogical_dev.html" target="_self" class="linklist_item" title="ôéúåç ôãâåâé, äèîòä åäãøëä">ôéúåç ôãâåâé, äèîòä åäãøëä</a><br>
|
||||
<a href="/content/tools.html" target="_self" class="linklist_item" title="ëìéí ìàéøâåï åðéäåì äìîéãä">ëìéí ìàéøâåï åðéäåì äìîéãä</a><br>
|
||||
<!--<a href="/content/future_project.html" target="_self" class="linklist_item" title="ðéñåééí åôøåé÷èéí îéåçãéí"> ðéñåééí åôøåé÷èéí îéåçãéí</a> --><!--<img src="graphics_nhp/star.gif" border="0" alt=""> <span class="new">çãù</span>-->
|
||||
|
||||
<a href="http://telem.openu.ac.il/content/sadan.html" target="_self" class="linklist_item" title="ñã"ï - ñôøéí ãéâéèàìééí ðééãéí">ñôøéí ãéâéèàìééí ðééãéí</a> <img src="graphics_nhp/star.gif" border="0" alt=""> <span class="new">çãù</span><br>
|
||||
|
||||
|
||||
<a href="http://telem.openu.ac.il/content/audio_books.html" target="_self" class="linklist_item" title="ñôøéí ÷åìééí – òøåõ ìîéãä ðåñó">ñôøéí ÷åìééí – òøåõ ìîéãä ðåñó</a> <!-- <img src="graphics_nhp/star.gif" border="0" alt=""> <span class="new"> çãù --><br>
|
||||
|
||||
|
||||
|
||||
<a href="/content/cooperative_learning.html" target="_self" class="linklist_item" title="ìîéãä ùéúåôéú">ìîéãä ùéúåôéú</a><br>
|
||||
<a href="http://wiki-openu.openu.ac.il/courses/wikiop" target="_blank" class="linklist_item" title="åé÷éàåô"><img src="graphics_nhp/wiki.gif" border="0" alt="åé÷éàåô"> åé÷éàåô</a><br>
|
||||
</div>
|
||||
|
||||
<br>
|
||||
<div class="linklist_em">
|
||||
<a href="http://telem.openu.ac.il/hp_files/paper/archive/index.html" target="_self" class="linklist_item" title="öìéì î÷ååï">öìéì î÷ååï - òìåï ùä"í</a><!-- <img src="graphics_nhp/star.gif" border="0" alt=""> <span class="new">çãù</span>--><br>
|
||||
<a href="http://www.shoham-at-ou.blogspot.com/" target="_blank" class="linklist_item" title="áìåâ ùä"í">áìåâ ùä"í</a><br>
|
||||
<img src="graphics_nhp/twitter_icon_small.gif" border="0" alt="èååéèø" align="absbottom"> <a href="http://twitter.com/shoham1" target="_blank" class="linklist_item" title="twitter">ò÷áå àçøéðå á-twitter </a><!--img src="graphics_nhp/star_bg_gray.gif" border="0" alt=""> <span class="new">çãù</span--><br>
|
||||
<a href="content/articles.html" target="_self" class="linklist_item" title="îàîøéí åîöâåú îëðñéí">îç÷øé äòøëä, îàîøéí åîöâåú</a><!-- <img src="graphics_nhp/star_bg_gray.gif" border="0" alt=""> <span class="new">çãù</span>--><br>
|
||||
<a href="content/lectures.html" target="_self" class="linklist_item" title="éîé òéåï">éîé òéåï áèëðåìåâéåú ìîéãä</a><!-- <img src="graphics_nhp/star.gif" border="0" alt=""> <span class="new">çãù</span><br>-->
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
<div id="links_left">
|
||||
|
||||
<!--div class="linklist" id="linklist"-->
|
||||
<!--a href="http://telem.openu.ac.il/content/contact_us.html" class="linklist_item" title="öåø ÷ùø">öåø ÷ùø</a><br-->
|
||||
<!--a href="http://www-e.openu.ac.il/geninfor/136.html" target="_self" class="linklist_item" title="english">English</a><br><br-->
|
||||
<!--a href="http://ocw.openu.ac.il/" target="_blank" class="linklist_item_gif" title="ôà'ø"><img src="graphics_nhp/ocw.gif" border="0" alt="ôà'ø"></a><br-->
|
||||
<!--/div-->
|
||||
|
||||
|
||||
<h1>çåîøé ìéîåã ôúåçéí</h1>
|
||||
<img src="graphics_nhp/logos8.jpg" width="170" border="1" usemap="#Map">
|
||||
<map name="Map">
|
||||
<area shape="rect" coords="2,68,81,106" href="http://goo.gl/4BPH" target="_blank" title="ñôøé äàå"ô áâøñä àì÷èøåðéú">
|
||||
<area shape="rect" coords="89,68,167,108" href="http://www.youtube.com/user/openofek" target="_blank" title="òøåõ YouTub ùì äàå"ô">
|
||||
<area shape="rect" coords="90,112,168,154" href="http://www.kotar.co.il/" target="_blank" title="ñôøé äàå"ô áñôøéä äî÷ååðú ùì îè"ç">
|
||||
<area shape="rect" coords="13,2,155,61" href="http://ocw.openu.ac.il/" target="_blank" alt="ñôøéí åçåîøé ìéîåã ôúåçéí ìëì" title="ñôøéí åçåîøé ìéîåã ôúåçéí ìëì">
|
||||
<area shape="rect" coords="2,113,81,154" onclick="tBox.objVisibility('iconmenu');" target="_blank" title="ñôøé äàå"ô áâøñä ÷åìéú">
|
||||
|
||||
</map>
|
||||
|
||||
<div id="iconmenu" style="display: none; border: 1px solid gray; background-color: white; padding-right:2px; font-size:1.3em; color:#336699; padding-right:2px; ">
|
||||
<a href="http://goo.gl/kBQ1F" title="äøöàåú" target="_blank" class="linklist_item">äøöàåú</a><br>
|
||||
<a href="http://goo.gl/dywt" title="ñôøéí ÷åìééí" target="_blank"class="linklist_item">ñôøéí ÷åìééí</a>
|
||||
|
||||
|
||||
<div style="color: blue; cursor: pointer; text-align: center;" onclick="tBox.objVisibility('iconmenu', 0);">[x] ñâåø</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<br><br>
|
||||
<div class="linklist_em">
|
||||
<a href="/content/opensources.html" target="_self" class="linklist_item" title="ìôéøåè àåãåú äòøåöéí äôúåçéí"> ìôéøåè àåãåú äòøåöéí äôúåçéí </a><!--img src="graphics_nhp/star.gif" border="0" alt=""> <span class="new">çãù</span--><br>
|
||||
|
||||
</div>
|
||||
<!--<div class="linklist_em">
|
||||
<a href="http://ocw.openu.ac.il/" target="_blank" class="linklist_item_gif" title="ôà'ø"><img src="graphics_nhp/ocw_s1_gray.gif" border="0" alt='ôà"ø - ôúéçú àåöøåú øåç'></a><br>
|
||||
<a href="http://www.kotar.co.il/" target="_blank" class="linklist_item" title='ñôøé äàå"ô áëåúø – îè"ç'> ñôøé äàå"ô áëåúø – îè"ç</a><br>
|
||||
<a href="http://goo.gl/4BPH" target="_blank" class="linklist_item" title='ñôøé äàå"ô google books'> ñôøé äàå"ô google books </a> <br>
|
||||
<a href="http://www.youtube.com/user/openofek" target="_blank" class="linklist_item" title=' YouTube òøåõ äàå"ô'><img src="graphics_nhp/youtube_small.gif" alt="youtube" width="40" height="17" border="0" align="absbottom"> òøåõ äàå"ô</a>
|
||||
<a href="http://www.icast.co.il/default.aspx?p=default&c_list=1&c=82" target="_blank" class="linklist_item" title='òøåõ äàå"ô á- iCast'>òøåõ äàå"ô á- iCast <!--img src="graphics_nhp/icast_logo.png" border="0" alt="youtube" align="absbottom"></a><br>-->
|
||||
|
||||
<!--<a href="http://ocw.openu.ac.il/newsletter/01.html" target="_blank" class="linklist_item" title='àåöøåú - òìåï ôà"ø'> àåöøåú - òìåï ôà"ø </a> <br> -->
|
||||
|
||||
<!--a href="content/presentations.html" target="_self" class="linklist_item" title="îöâåú áëðñéí">îöâåú áëðñéí</a><br>
|
||||
|
||||
</div>-->
|
||||
<br>
|
||||
<h1>÷éùåøéí</h1>
|
||||
<div class="linklist" id="links">
|
||||
<a href="http://www.openu.ac.il/Library/" target="_blank" class="linklist_item" title="ñôøéä åîàâøé îéãò">ñôøéä åîàâøé îéãò</a><br>
|
||||
<a href="http://www.openu.ac.il/innovation/" target="_blank" class="linklist_item" title="äîøëæ ìç÷ø çãùðåú áèëðåìåâéåú ìîéãä">äîøëæ ìç÷ø çãùðåú áèëðåìåâéåú ìîéãä</a><br>
|
||||
<a href="http://meital.iucc.ac.il/" target="_blank" class="linklist_item" title="îøëæ éãò èëðåìåâéåú ìîéãä ">îéè"ì</a><br>
|
||||
|
||||
<!--<a href="http://wiki-openu.openu.ac.il/courses/wikiop" target="_blank" class="linklist_item" title=""><img src="graphics_nhp/oui_books_icon.jpg" alt="ñôøéí ãéâéèìéí" width="23" height="13" border="0"> äñôøéí äãéâéèìéí áôééñáå÷</a><br>-->
|
||||
</div>
|
||||
|
||||
|
||||
<!-- share this button (start)
|
||||
<span class='st_sharethis' displayText='ShareThis' style="width: 100px; height: 100px;"></span>
|
||||
<script type="text/javascript">var switchTo5x=false;</script><script type="text/javascript" src="http://w.sharethis.com/button/buttons.js"></script><script type="text/javascript">stLight.options({publisher:'c009e98c-ad2e-4156-afda-95a59aca520c'});</script>
|
||||
share this button (end) -->
|
||||
|
||||
|
||||
<!-- AddToAny BEGIN -->
|
||||
<a class="a2a_dd" href="http://www.addtoany.com/share_save"><img src="http://static.addtoany.com/buttons/share_save_171_16.png" width="171" height="16" border="0" alt="Share"/></a>
|
||||
<script type="text/javascript">
|
||||
var a2a_config = a2a_config || {};
|
||||
a2a_config.onclick = 1;
|
||||
a2a_config.locale = "he";
|
||||
a2a_config.num_services = 4;
|
||||
</script>
|
||||
<script type="text/javascript" src="http://static.addtoany.com/menu/page.js"></script>
|
||||
<!-- AddToAny END -->
|
||||
|
||||
<!-- google +1 (START) -->
|
||||
<script type="text/javascript" src="http://apis.google.com/js/plusone.js">
|
||||
{lang: 'iw'}
|
||||
</script>
|
||||
<g:plusone size="small"></g:plusone>
|
||||
<!-- google +1 (START) -->
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<!--end of links_zone-->
|
||||
</div>
|
||||
|
||||
<!--end of left-->
|
||||
</div>
|
||||
|
||||
<!--end of text-->
|
||||
</div>
|
||||
<div id="close">
|
||||
|
||||
</div>
|
||||
|
||||
<!--end of content-->
|
||||
</div>
|
||||
<div id="footer">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=windows-1255" />
|
||||
<meta http-equiv="Content-Language" content="he" />
|
||||
|
||||
<div id="footer1">
|
||||
|
||||
<a href="http://telem.openu.ac.il/content/about_shoham.html" id="abouts" title="àåãåú" target="_blank">àåãåú</a><!-- |-->
|
||||
<a href="http://telem.openu.ac.il/content/contact_us.html" id="conts" title="öåø ÷ùø" target="_blank">öåø ÷ùø</a><!-- |-->
|
||||
<a href="/" id="hps" title="ãó äáéú" target="_self">ãó äáéú</a><!-- |-->
|
||||
<a href="http://www.openu.ac.il/" id="opnets" title="àåôð'è" target="_self"><img src="http://telem.openu.ac.il/graphics_nhp/openu_icon.gif" border="0" alt="àåôðè" /></a><!-- |-->
|
||||
</div>
|
||||
|
||||
<div id="footer2">
|
||||
<table id="copyRight" style="display: none;" align="center" width="180" cellspacing="0" cellpadding="1" border="0" bgcolor="#000000">
|
||||
<tr>
|
||||
<td>
|
||||
<table cellspacing="0" cellpadding="3" border="0" width="100%">
|
||||
<tr>
|
||||
<td bgcolor="#FFFFFF">
|
||||
<span id="open" style="cursor: pointer;" onclick="showHideLayer('copyRight', '', '');">[ñâåø]</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td bgcolor="#FFFFFF">
|
||||
<center><b>ùéîåù îñçøé áçåîø äëìåì áàúøéí àìä àñåø áäçìè, àìà áøùåú îôåøùú åáëúá îîãåø æëåéåú éåöøéí ùì äàå'ô <BR /></b>
|
||||
</center>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
Copyright ©,The Open University of Israel 1997-2012 <b style="cursor: pointer;" onclick="showHideLayer('copyRight', '', '');">all rights reserved<br />
|
||||
ëì äæëåéåú ùîåøåú </b>© ìàåðéáøñéèä äôúåçä. úùò"á - 2012
|
||||
</div>
|
||||
|
||||
<!--include virtual="/include/general/footer_source_popup_shoham_logical.htm" -->
|
||||
<!--include virtual="/include/general/footer_code_popup_shoham_logical.html" -->
|
||||
|
||||
|
||||
<!-- GOOGLE ANALYTICS (TELEM ONLY) START -->
|
||||
<script type="text/javascript">
|
||||
var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
|
||||
document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
|
||||
</script>
|
||||
<script type="text/javascript">
|
||||
var pageTracker = _gat._getTracker("UA-4646503-5");
|
||||
//pageTracker._initData();
|
||||
pageTracker._trackPageview();
|
||||
</script>
|
||||
<!-- GOOGLE ANALYTICS (TELEM ONLY) END -->
|
||||
|
||||
|
||||
</div>
|
||||
<!--end of container-->
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
1
vendor/github.com/elazarl/goproxy/ext/html/cp1255.txt
generated
vendored
1
vendor/github.com/elazarl/goproxy/ext/html/cp1255.txt
generated
vendored
|
@ -1 +0,0 @@
|
|||
胚
|
104
vendor/github.com/elazarl/goproxy/ext/html/html.go
generated
vendored
104
vendor/github.com/elazarl/goproxy/ext/html/html.go
generated
vendored
|
@ -1,104 +0,0 @@
|
|||
// extension to goproxy that will allow you to easily filter web browser related content.
|
||||
package goproxy_html
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/rogpeppe/go-charset/charset"
|
||||
_ "github.com/rogpeppe/go-charset/data"
|
||||
"github.com/elazarl/goproxy"
|
||||
)
|
||||
|
||||
var IsHtml goproxy.RespCondition = goproxy.ContentTypeIs("text/html")
|
||||
|
||||
var IsCss goproxy.RespCondition = goproxy.ContentTypeIs("text/css")
|
||||
|
||||
var IsJavaScript goproxy.RespCondition = goproxy.ContentTypeIs("text/javascript",
|
||||
"application/javascript")
|
||||
|
||||
var IsJson goproxy.RespCondition = goproxy.ContentTypeIs("text/json")
|
||||
|
||||
var IsXml goproxy.RespCondition = goproxy.ContentTypeIs("text/xml")
|
||||
|
||||
var IsWebRelatedText goproxy.RespCondition = goproxy.ContentTypeIs("text/html",
|
||||
"text/css",
|
||||
"text/javascript", "application/javascript",
|
||||
"text/xml",
|
||||
"text/json")
|
||||
|
||||
// HandleString will receive a function that filters a string, and will convert the
|
||||
// request body to a utf8 string, according to the charset specified in the Content-Type
|
||||
// header.
|
||||
// guessing Html charset encoding from the <META> tags is not yet implemented.
|
||||
func HandleString(f func(s string, ctx *goproxy.ProxyCtx) string) goproxy.RespHandler {
|
||||
return HandleStringReader(func(r io.Reader, ctx *goproxy.ProxyCtx) io.Reader {
|
||||
b, err := ioutil.ReadAll(r)
|
||||
if err != nil {
|
||||
ctx.Warnf("Cannot read string from resp body: %v", err)
|
||||
return r
|
||||
}
|
||||
return bytes.NewBufferString(f(string(b), ctx))
|
||||
})
|
||||
}
|
||||
|
||||
// Will receive an input stream which would convert the response to utf-8
|
||||
// The given function must close the reader r, in order to close the response body.
|
||||
func HandleStringReader(f func(r io.Reader, ctx *goproxy.ProxyCtx) io.Reader) goproxy.RespHandler {
|
||||
return goproxy.FuncRespHandler(func(resp *http.Response, ctx *goproxy.ProxyCtx) *http.Response {
|
||||
if ctx.Error != nil {
|
||||
return nil
|
||||
}
|
||||
charsetName := ctx.Charset()
|
||||
if charsetName == "" {
|
||||
charsetName = "utf-8"
|
||||
}
|
||||
|
||||
if strings.ToLower(charsetName) != "utf-8" {
|
||||
r, err := charset.NewReader(charsetName, resp.Body)
|
||||
if err != nil {
|
||||
ctx.Warnf("Cannot convert from %v to utf-8: %v", charsetName, err)
|
||||
return resp
|
||||
}
|
||||
tr, err := charset.TranslatorTo(charsetName)
|
||||
if err != nil {
|
||||
ctx.Warnf("Can't translate to %v from utf-8: %v", charsetName, err)
|
||||
return resp
|
||||
}
|
||||
if err != nil {
|
||||
ctx.Warnf("Cannot translate to %v: %v", charsetName, err)
|
||||
return resp
|
||||
}
|
||||
newr := charset.NewTranslatingReader(f(r, ctx), tr)
|
||||
resp.Body = &readFirstCloseBoth{ioutil.NopCloser(newr), resp.Body}
|
||||
} else {
|
||||
//no translation is needed, already at utf-8
|
||||
resp.Body = &readFirstCloseBoth{ioutil.NopCloser(f(resp.Body, ctx)), resp.Body}
|
||||
}
|
||||
return resp
|
||||
})
|
||||
}
|
||||
|
||||
type readFirstCloseBoth struct {
|
||||
r io.ReadCloser
|
||||
c io.Closer
|
||||
}
|
||||
|
||||
func (rfcb *readFirstCloseBoth) Read(b []byte) (nr int, err error) {
|
||||
return rfcb.r.Read(b)
|
||||
}
|
||||
func (rfcb *readFirstCloseBoth) Close() error {
|
||||
err1 := rfcb.r.Close()
|
||||
err2 := rfcb.c.Close()
|
||||
if err1 != nil && err2 != nil {
|
||||
return errors.New(err1.Error() + ", " + err2.Error())
|
||||
}
|
||||
if err1 != nil {
|
||||
return err1
|
||||
}
|
||||
return err2
|
||||
}
|
60
vendor/github.com/elazarl/goproxy/ext/html/html_test.go
generated
vendored
60
vendor/github.com/elazarl/goproxy/ext/html/html_test.go
generated
vendored
|
@ -1,60 +0,0 @@
|
|||
package goproxy_html_test
|
||||
|
||||
import (
|
||||
"github.com/elazarl/goproxy"
|
||||
"github.com/elazarl/goproxy/ext/html"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"net/url"
|
||||
"testing"
|
||||
)
|
||||
|
||||
type ConstantServer int
|
||||
|
||||
func (s ConstantServer) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "text/plain; charset=iso-8859-8")
|
||||
//w.Header().Set("Content-Type","text/plain; charset=cp-1255")
|
||||
w.Write([]byte{0xe3, 0xf3})
|
||||
}
|
||||
|
||||
func TestCharset(t *testing.T) {
|
||||
s := httptest.NewServer(ConstantServer(1))
|
||||
defer s.Close()
|
||||
|
||||
ch := make(chan string, 2)
|
||||
proxy := goproxy.NewProxyHttpServer()
|
||||
proxy.OnResponse().Do(goproxy_html.HandleString(
|
||||
func(s string, ctx *goproxy.ProxyCtx) string {
|
||||
ch <- s
|
||||
return s
|
||||
}))
|
||||
proxyServer := httptest.NewServer(proxy)
|
||||
defer proxyServer.Close()
|
||||
|
||||
proxyUrl, _ := url.Parse(proxyServer.URL)
|
||||
client := &http.Client{Transport: &http.Transport{Proxy: http.ProxyURL(proxyUrl)}}
|
||||
|
||||
resp, err := client.Get(s.URL + "/cp1255.txt")
|
||||
if err != nil {
|
||||
t.Fatal("GET:", err)
|
||||
}
|
||||
b, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
t.Fatal("readAll:", err)
|
||||
}
|
||||
resp.Body.Close()
|
||||
|
||||
inHandleString := ""
|
||||
select {
|
||||
case inHandleString = <-ch:
|
||||
default:
|
||||
}
|
||||
|
||||
if len(b) != 2 || b[0] != 0xe3 || b[1] != 0xf3 {
|
||||
t.Error("Did not translate back to 0xe3,0xf3, instead", b)
|
||||
}
|
||||
if inHandleString != "דף" {
|
||||
t.Error("HandleString did not convert DALET & PEH SOFIT (דף) from ISO-8859-8 to utf-8, got", []byte(inHandleString))
|
||||
}
|
||||
}
|
78
vendor/github.com/elazarl/goproxy/ext/image/image.go
generated
vendored
78
vendor/github.com/elazarl/goproxy/ext/image/image.go
generated
vendored
|
@ -1,78 +0,0 @@
|
|||
package goproxy_image
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"image"
|
||||
_ "image/gif"
|
||||
"image/jpeg"
|
||||
"image/png"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
. "github.com/elazarl/goproxy"
|
||||
"github.com/elazarl/goproxy/regretable"
|
||||
)
|
||||
|
||||
var RespIsImage = ContentTypeIs("image/gif",
|
||||
"image/jpeg",
|
||||
"image/pjpeg",
|
||||
"application/octet-stream",
|
||||
"image/png")
|
||||
|
||||
// "image/tiff" tiff support is in external package, and rarely used, so we omitted it
|
||||
|
||||
func HandleImage(f func(img image.Image, ctx *ProxyCtx) image.Image) RespHandler {
|
||||
return FuncRespHandler(func(resp *http.Response, ctx *ProxyCtx) *http.Response {
|
||||
if !RespIsImage.HandleResp(resp, ctx) {
|
||||
return resp
|
||||
}
|
||||
if resp.StatusCode != 200 {
|
||||
// we might get 304 - not modified response without data
|
||||
return resp
|
||||
}
|
||||
contentType := resp.Header.Get("Content-Type")
|
||||
|
||||
const kb = 1024
|
||||
regret := regretable.NewRegretableReaderCloserSize(resp.Body, 16*kb)
|
||||
resp.Body = regret
|
||||
img, imgType, err := image.Decode(resp.Body)
|
||||
if err != nil {
|
||||
regret.Regret()
|
||||
ctx.Warnf("%s: %s", ctx.Req.Method+" "+ctx.Req.URL.String()+" Image from "+ctx.Req.RequestURI+"content type"+
|
||||
contentType+"cannot be decoded returning original image", err)
|
||||
return resp
|
||||
}
|
||||
result := f(img, ctx)
|
||||
buf := bytes.NewBuffer([]byte{})
|
||||
switch contentType {
|
||||
// No gif image encoder in go - convert to png
|
||||
case "image/gif", "image/png":
|
||||
if err := png.Encode(buf, result); err != nil {
|
||||
ctx.Warnf("Cannot encode image, returning orig %v %v", ctx.Req.URL.String(), err)
|
||||
return resp
|
||||
}
|
||||
resp.Header.Set("Content-Type", "image/png")
|
||||
case "image/jpeg", "image/pjpeg":
|
||||
if err := jpeg.Encode(buf, result, nil); err != nil {
|
||||
ctx.Warnf("Cannot encode image, returning orig %v %v", ctx.Req.URL.String(), err)
|
||||
return resp
|
||||
}
|
||||
case "application/octet-stream":
|
||||
switch imgType {
|
||||
case "jpeg":
|
||||
if err := jpeg.Encode(buf, result, nil); err != nil {
|
||||
ctx.Warnf("Cannot encode image as jpeg, returning orig %v %v", ctx.Req.URL.String(), err)
|
||||
return resp
|
||||
}
|
||||
case "png", "gif":
|
||||
if err := png.Encode(buf, result); err != nil {
|
||||
ctx.Warnf("Cannot encode image as png, returning orig %v %v", ctx.Req.URL.String(), err)
|
||||
return resp
|
||||
}
|
||||
}
|
||||
default:
|
||||
panic("unhandlable type" + contentType)
|
||||
}
|
||||
resp.Body = ioutil.NopCloser(buf)
|
||||
return resp
|
||||
})
|
||||
}
|
836
vendor/github.com/elazarl/goproxy/proxy_test.go
generated
vendored
836
vendor/github.com/elazarl/goproxy/proxy_test.go
generated
vendored
|
@ -1,836 +0,0 @@
|
|||
package goproxy_test
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"crypto/tls"
|
||||
"crypto/x509"
|
||||
"encoding/base64"
|
||||
"image"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"net/url"
|
||||
"os"
|
||||
"os/exec"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/elazarl/goproxy"
|
||||
"github.com/elazarl/goproxy/ext/image"
|
||||
)
|
||||
|
||||
var acceptAllCerts = &tls.Config{InsecureSkipVerify: true}
|
||||
|
||||
var noProxyClient = &http.Client{Transport: &http.Transport{TLSClientConfig: acceptAllCerts}}
|
||||
|
||||
var https = httptest.NewTLSServer(nil)
|
||||
var srv = httptest.NewServer(nil)
|
||||
var fs = httptest.NewServer(http.FileServer(http.Dir(".")))
|
||||
|
||||
type QueryHandler struct{}
|
||||
|
||||
func (QueryHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||
if err := req.ParseForm(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
io.WriteString(w, req.Form.Get("result"))
|
||||
}
|
||||
|
||||
func init() {
|
||||
http.DefaultServeMux.Handle("/bobo", ConstantHanlder("bobo"))
|
||||
http.DefaultServeMux.Handle("/query", QueryHandler{})
|
||||
}
|
||||
|
||||
type ConstantHanlder string
|
||||
|
||||
func (h ConstantHanlder) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
io.WriteString(w, string(h))
|
||||
}
|
||||
|
||||
func get(url string, client *http.Client) ([]byte, error) {
|
||||
resp, err := client.Get(url)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
txt, err := ioutil.ReadAll(resp.Body)
|
||||
defer resp.Body.Close()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return txt, nil
|
||||
}
|
||||
|
||||
func getOrFail(url string, client *http.Client, t *testing.T) []byte {
|
||||
txt, err := get(url, client)
|
||||
if err != nil {
|
||||
t.Fatal("Can't fetch url", url, err)
|
||||
}
|
||||
return txt
|
||||
}
|
||||
|
||||
func localFile(url string) string { return fs.URL + "/" + url }
|
||||
func localTls(url string) string { return https.URL + url }
|
||||
|
||||
func TestSimpleHttpReqWithProxy(t *testing.T) {
|
||||
client, s := oneShotProxy(goproxy.NewProxyHttpServer(), t)
|
||||
defer s.Close()
|
||||
|
||||
if r := string(getOrFail(srv.URL+"/bobo", client, t)); r != "bobo" {
|
||||
t.Error("proxy server does not serve constant handlers", r)
|
||||
}
|
||||
if r := string(getOrFail(srv.URL+"/bobo", client, t)); r != "bobo" {
|
||||
t.Error("proxy server does not serve constant handlers", r)
|
||||
}
|
||||
|
||||
if string(getOrFail(https.URL+"/bobo", client, t)) != "bobo" {
|
||||
t.Error("TLS server does not serve constant handlers, when proxy is used")
|
||||
}
|
||||
}
|
||||
|
||||
func oneShotProxy(proxy *goproxy.ProxyHttpServer, t *testing.T) (client *http.Client, s *httptest.Server) {
|
||||
s = httptest.NewServer(proxy)
|
||||
|
||||
proxyUrl, _ := url.Parse(s.URL)
|
||||
tr := &http.Transport{TLSClientConfig: acceptAllCerts, Proxy: http.ProxyURL(proxyUrl)}
|
||||
client = &http.Client{Transport: tr}
|
||||
return
|
||||
}
|
||||
|
||||
func TestSimpleHook(t *testing.T) {
|
||||
proxy := goproxy.NewProxyHttpServer()
|
||||
proxy.OnRequest(goproxy.SrcIpIs("127.0.0.1")).DoFunc(func(req *http.Request, ctx *goproxy.ProxyCtx) (*http.Request, *http.Response) {
|
||||
req.URL.Path = "/bobo"
|
||||
return req, nil
|
||||
})
|
||||
client, l := oneShotProxy(proxy, t)
|
||||
defer l.Close()
|
||||
|
||||
if result := string(getOrFail(srv.URL+("/momo"), client, t)); result != "bobo" {
|
||||
t.Error("Redirecting all requests from 127.0.0.1 to bobo, didn't work." +
|
||||
" (Might break if Go's client sets RemoteAddr to IPv6 address). Got: " +
|
||||
result)
|
||||
}
|
||||
}
|
||||
|
||||
func TestAlwaysHook(t *testing.T) {
|
||||
proxy := goproxy.NewProxyHttpServer()
|
||||
proxy.OnRequest().DoFunc(func(req *http.Request, ctx *goproxy.ProxyCtx) (*http.Request, *http.Response) {
|
||||
req.URL.Path = "/bobo"
|
||||
return req, nil
|
||||
})
|
||||
client, l := oneShotProxy(proxy, t)
|
||||
defer l.Close()
|
||||
|
||||
if result := string(getOrFail(srv.URL+("/momo"), client, t)); result != "bobo" {
|
||||
t.Error("Redirecting all requests from 127.0.0.1 to bobo, didn't work." +
|
||||
" (Might break if Go's client sets RemoteAddr to IPv6 address). Got: " +
|
||||
result)
|
||||
}
|
||||
}
|
||||
|
||||
func TestReplaceResponse(t *testing.T) {
|
||||
proxy := goproxy.NewProxyHttpServer()
|
||||
proxy.OnResponse().DoFunc(func(resp *http.Response, ctx *goproxy.ProxyCtx) *http.Response {
|
||||
resp.StatusCode = http.StatusOK
|
||||
resp.Body = ioutil.NopCloser(bytes.NewBufferString("chico"))
|
||||
return resp
|
||||
})
|
||||
|
||||
client, l := oneShotProxy(proxy, t)
|
||||
defer l.Close()
|
||||
|
||||
if result := string(getOrFail(srv.URL+("/momo"), client, t)); result != "chico" {
|
||||
t.Error("hooked response, should be chico, instead:", result)
|
||||
}
|
||||
}
|
||||
|
||||
func TestReplaceReponseForUrl(t *testing.T) {
|
||||
proxy := goproxy.NewProxyHttpServer()
|
||||
proxy.OnResponse(goproxy.UrlIs("/koko")).DoFunc(func(resp *http.Response, ctx *goproxy.ProxyCtx) *http.Response {
|
||||
resp.StatusCode = http.StatusOK
|
||||
resp.Body = ioutil.NopCloser(bytes.NewBufferString("chico"))
|
||||
return resp
|
||||
})
|
||||
|
||||
client, l := oneShotProxy(proxy, t)
|
||||
defer l.Close()
|
||||
|
||||
if result := string(getOrFail(srv.URL+("/koko"), client, t)); result != "chico" {
|
||||
t.Error("hooked 'koko', should be chico, instead:", result)
|
||||
}
|
||||
if result := string(getOrFail(srv.URL+("/bobo"), client, t)); result != "bobo" {
|
||||
t.Error("still, bobo should stay as usual, instead:", result)
|
||||
}
|
||||
}
|
||||
|
||||
func TestOneShotFileServer(t *testing.T) {
|
||||
client, l := oneShotProxy(goproxy.NewProxyHttpServer(), t)
|
||||
defer l.Close()
|
||||
|
||||
file := "test_data/panda.png"
|
||||
info, err := os.Stat(file)
|
||||
if err != nil {
|
||||
t.Fatal("Cannot find", file)
|
||||
}
|
||||
if resp, err := client.Get(fs.URL + "/" + file); err == nil {
|
||||
b, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
t.Fatal("got", string(b))
|
||||
}
|
||||
if int64(len(b)) != info.Size() {
|
||||
t.Error("Expected Length", file, info.Size(), "actually", len(b), "starts", string(b[:10]))
|
||||
}
|
||||
} else {
|
||||
t.Fatal("Cannot read from fs server", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestContentType(t *testing.T) {
|
||||
proxy := goproxy.NewProxyHttpServer()
|
||||
proxy.OnResponse(goproxy.ContentTypeIs("image/png")).DoFunc(func(resp *http.Response, ctx *goproxy.ProxyCtx) *http.Response {
|
||||
resp.Header.Set("X-Shmoopi", "1")
|
||||
return resp
|
||||
})
|
||||
|
||||
client, l := oneShotProxy(proxy, t)
|
||||
defer l.Close()
|
||||
|
||||
for _, file := range []string{"test_data/panda.png", "test_data/football.png"} {
|
||||
if resp, err := client.Get(localFile(file)); err != nil || resp.Header.Get("X-Shmoopi") != "1" {
|
||||
if err == nil {
|
||||
t.Error("pngs should have X-Shmoopi header = 1, actually", resp.Header.Get("X-Shmoopi"))
|
||||
} else {
|
||||
t.Error("error reading png", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
file := "baby.jpg"
|
||||
if resp, err := client.Get(localFile(file)); err != nil || resp.Header.Get("X-Shmoopi") != "" {
|
||||
if err == nil {
|
||||
t.Error("Non png images should NOT have X-Shmoopi header at all", resp.Header.Get("X-Shmoopi"))
|
||||
} else {
|
||||
t.Error("error reading png", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func getImage(file string, t *testing.T) image.Image {
|
||||
newimage, err := ioutil.ReadFile(file)
|
||||
if err != nil {
|
||||
t.Fatal("Cannot read file", file, err)
|
||||
}
|
||||
img, _, err := image.Decode(bytes.NewReader(newimage))
|
||||
if err != nil {
|
||||
t.Fatal("Cannot decode image", file, err)
|
||||
}
|
||||
return img
|
||||
}
|
||||
|
||||
func readAll(r io.Reader, t *testing.T) []byte {
|
||||
b, err := ioutil.ReadAll(r)
|
||||
if err != nil {
|
||||
t.Fatal("Cannot read", err)
|
||||
}
|
||||
return b
|
||||
}
|
||||
func readFile(file string, t *testing.T) []byte {
|
||||
b, err := ioutil.ReadFile(file)
|
||||
if err != nil {
|
||||
t.Fatal("Cannot read", err)
|
||||
}
|
||||
return b
|
||||
}
|
||||
func fatalOnErr(err error, msg string, t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatal(msg, err)
|
||||
}
|
||||
}
|
||||
func panicOnErr(err error, msg string) {
|
||||
if err != nil {
|
||||
println(err.Error() + ":-" + msg)
|
||||
os.Exit(-1)
|
||||
}
|
||||
}
|
||||
|
||||
func compareImage(eImg, aImg image.Image, t *testing.T) {
|
||||
if eImg.Bounds().Dx() != aImg.Bounds().Dx() || eImg.Bounds().Dy() != aImg.Bounds().Dy() {
|
||||
t.Error("image sizes different")
|
||||
return
|
||||
}
|
||||
for i := 0; i < eImg.Bounds().Dx(); i++ {
|
||||
for j := 0; j < eImg.Bounds().Dy(); j++ {
|
||||
er, eg, eb, ea := eImg.At(i, j).RGBA()
|
||||
ar, ag, ab, aa := aImg.At(i, j).RGBA()
|
||||
if er != ar || eg != ag || eb != ab || ea != aa {
|
||||
t.Error("images different at", i, j, "vals\n", er, eg, eb, ea, "\n", ar, ag, ab, aa, aa)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestConstantImageHandler(t *testing.T) {
|
||||
proxy := goproxy.NewProxyHttpServer()
|
||||
//panda := getImage("panda.png", t)
|
||||
football := getImage("test_data/football.png", t)
|
||||
proxy.OnResponse().Do(goproxy_image.HandleImage(func(img image.Image, ctx *goproxy.ProxyCtx) image.Image {
|
||||
return football
|
||||
}))
|
||||
|
||||
client, l := oneShotProxy(proxy, t)
|
||||
defer l.Close()
|
||||
|
||||
resp, err := client.Get(localFile("test_data/panda.png"))
|
||||
if err != nil {
|
||||
t.Fatal("Cannot get panda.png", err)
|
||||
}
|
||||
|
||||
img, _, err := image.Decode(resp.Body)
|
||||
if err != nil {
|
||||
t.Error("decode", err)
|
||||
} else {
|
||||
compareImage(football, img, t)
|
||||
}
|
||||
}
|
||||
|
||||
func TestImageHandler(t *testing.T) {
|
||||
proxy := goproxy.NewProxyHttpServer()
|
||||
football := getImage("test_data/football.png", t)
|
||||
|
||||
proxy.OnResponse(goproxy.UrlIs("/test_data/panda.png")).Do(goproxy_image.HandleImage(func(img image.Image, ctx *goproxy.ProxyCtx) image.Image {
|
||||
return football
|
||||
}))
|
||||
|
||||
client, l := oneShotProxy(proxy, t)
|
||||
defer l.Close()
|
||||
|
||||
resp, err := client.Get(localFile("test_data/panda.png"))
|
||||
if err != nil {
|
||||
t.Fatal("Cannot get panda.png", err)
|
||||
}
|
||||
|
||||
img, _, err := image.Decode(resp.Body)
|
||||
if err != nil {
|
||||
t.Error("decode", err)
|
||||
} else {
|
||||
compareImage(football, img, t)
|
||||
}
|
||||
|
||||
// and again
|
||||
resp, err = client.Get(localFile("test_data/panda.png"))
|
||||
if err != nil {
|
||||
t.Fatal("Cannot get panda.png", err)
|
||||
}
|
||||
|
||||
img, _, err = image.Decode(resp.Body)
|
||||
if err != nil {
|
||||
t.Error("decode", err)
|
||||
} else {
|
||||
compareImage(football, img, t)
|
||||
}
|
||||
}
|
||||
|
||||
func TestChangeResp(t *testing.T) {
|
||||
proxy := goproxy.NewProxyHttpServer()
|
||||
proxy.OnResponse().DoFunc(func(resp *http.Response, ctx *goproxy.ProxyCtx) *http.Response {
|
||||
resp.Body.Read([]byte{0})
|
||||
resp.Body = ioutil.NopCloser(new(bytes.Buffer))
|
||||
return resp
|
||||
})
|
||||
|
||||
client, l := oneShotProxy(proxy, t)
|
||||
defer l.Close()
|
||||
|
||||
resp, err := client.Get(localFile("test_data/panda.png"))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
ioutil.ReadAll(resp.Body)
|
||||
_, err = client.Get(localFile("/bobo"))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
func TestReplaceImage(t *testing.T) {
|
||||
proxy := goproxy.NewProxyHttpServer()
|
||||
|
||||
panda := getImage("test_data/panda.png", t)
|
||||
football := getImage("test_data/football.png", t)
|
||||
|
||||
proxy.OnResponse(goproxy.UrlIs("/test_data/panda.png")).Do(goproxy_image.HandleImage(func(img image.Image, ctx *goproxy.ProxyCtx) image.Image {
|
||||
return football
|
||||
}))
|
||||
proxy.OnResponse(goproxy.UrlIs("/test_data/football.png")).Do(goproxy_image.HandleImage(func(img image.Image, ctx *goproxy.ProxyCtx) image.Image {
|
||||
return panda
|
||||
}))
|
||||
|
||||
client, l := oneShotProxy(proxy, t)
|
||||
defer l.Close()
|
||||
|
||||
imgByPandaReq, _, err := image.Decode(bytes.NewReader(getOrFail(localFile("test_data/panda.png"), client, t)))
|
||||
fatalOnErr(err, "decode panda", t)
|
||||
compareImage(football, imgByPandaReq, t)
|
||||
|
||||
imgByFootballReq, _, err := image.Decode(bytes.NewReader(getOrFail(localFile("test_data/football.png"), client, t)))
|
||||
fatalOnErr(err, "decode football", t)
|
||||
compareImage(panda, imgByFootballReq, t)
|
||||
}
|
||||
|
||||
func getCert(c *tls.Conn, t *testing.T) []byte {
|
||||
if err := c.Handshake(); err != nil {
|
||||
t.Fatal("cannot handshake", err)
|
||||
}
|
||||
return c.ConnectionState().PeerCertificates[0].Raw
|
||||
}
|
||||
|
||||
func TestSimpleMitm(t *testing.T) {
|
||||
proxy := goproxy.NewProxyHttpServer()
|
||||
proxy.OnRequest(goproxy.ReqHostIs(https.Listener.Addr().String())).HandleConnect(goproxy.AlwaysMitm)
|
||||
proxy.OnRequest(goproxy.ReqHostIs("no such host exists")).HandleConnect(goproxy.AlwaysMitm)
|
||||
|
||||
client, l := oneShotProxy(proxy, t)
|
||||
defer l.Close()
|
||||
|
||||
c, err := tls.Dial("tcp", https.Listener.Addr().String(), &tls.Config{InsecureSkipVerify: true})
|
||||
if err != nil {
|
||||
t.Fatal("cannot dial to tcp server", err)
|
||||
}
|
||||
origCert := getCert(c, t)
|
||||
c.Close()
|
||||
|
||||
c2, err := net.Dial("tcp", l.Listener.Addr().String())
|
||||
if err != nil {
|
||||
t.Fatal("dialing to proxy", err)
|
||||
}
|
||||
creq, err := http.NewRequest("CONNECT", https.URL, nil)
|
||||
//creq,err := http.NewRequest("CONNECT","https://google.com:443",nil)
|
||||
if err != nil {
|
||||
t.Fatal("create new request", creq)
|
||||
}
|
||||
creq.Write(c2)
|
||||
c2buf := bufio.NewReader(c2)
|
||||
resp, err := http.ReadResponse(c2buf, creq)
|
||||
if err != nil || resp.StatusCode != 200 {
|
||||
t.Fatal("Cannot CONNECT through proxy", err)
|
||||
}
|
||||
c2tls := tls.Client(c2, &tls.Config{InsecureSkipVerify: true})
|
||||
proxyCert := getCert(c2tls, t)
|
||||
|
||||
if bytes.Equal(proxyCert, origCert) {
|
||||
t.Errorf("Certificate after mitm is not different\n%v\n%v",
|
||||
base64.StdEncoding.EncodeToString(origCert),
|
||||
base64.StdEncoding.EncodeToString(proxyCert))
|
||||
}
|
||||
|
||||
if resp := string(getOrFail(https.URL+"/bobo", client, t)); resp != "bobo" {
|
||||
t.Error("Wrong response when mitm", resp, "expected bobo")
|
||||
}
|
||||
if resp := string(getOrFail(https.URL+"/query?result=bar", client, t)); resp != "bar" {
|
||||
t.Error("Wrong response when mitm", resp, "expected bar")
|
||||
}
|
||||
}
|
||||
|
||||
func TestConnectHandler(t *testing.T) {
|
||||
proxy := goproxy.NewProxyHttpServer()
|
||||
althttps := httptest.NewTLSServer(ConstantHanlder("althttps"))
|
||||
proxy.OnRequest().HandleConnectFunc(func(host string, ctx *goproxy.ProxyCtx) (*goproxy.ConnectAction, string) {
|
||||
u, _ := url.Parse(althttps.URL)
|
||||
return goproxy.OkConnect, u.Host
|
||||
})
|
||||
|
||||
client, l := oneShotProxy(proxy, t)
|
||||
defer l.Close()
|
||||
if resp := string(getOrFail(https.URL+"/alturl", client, t)); resp != "althttps" {
|
||||
t.Error("Proxy should redirect CONNECT requests to local althttps server, expected 'althttps' got ", resp)
|
||||
}
|
||||
}
|
||||
|
||||
func TestMitmIsFiltered(t *testing.T) {
|
||||
proxy := goproxy.NewProxyHttpServer()
|
||||
//proxy.Verbose = true
|
||||
proxy.OnRequest(goproxy.ReqHostIs(https.Listener.Addr().String())).HandleConnect(goproxy.AlwaysMitm)
|
||||
proxy.OnRequest(goproxy.UrlIs("/momo")).DoFunc(func(req *http.Request, ctx *goproxy.ProxyCtx) (*http.Request, *http.Response) {
|
||||
return nil, goproxy.TextResponse(req, "koko")
|
||||
})
|
||||
|
||||
client, l := oneShotProxy(proxy, t)
|
||||
defer l.Close()
|
||||
|
||||
if resp := string(getOrFail(https.URL+"/momo", client, t)); resp != "koko" {
|
||||
t.Error("Proxy should capture /momo to be koko and not", resp)
|
||||
}
|
||||
|
||||
if resp := string(getOrFail(https.URL+"/bobo", client, t)); resp != "bobo" {
|
||||
t.Error("But still /bobo should be bobo and not", resp)
|
||||
}
|
||||
}
|
||||
|
||||
func TestFirstHandlerMatches(t *testing.T) {
|
||||
proxy := goproxy.NewProxyHttpServer()
|
||||
proxy.OnRequest().DoFunc(func(req *http.Request, ctx *goproxy.ProxyCtx) (*http.Request, *http.Response) {
|
||||
return nil, goproxy.TextResponse(req, "koko")
|
||||
})
|
||||
proxy.OnRequest().DoFunc(func(req *http.Request, ctx *goproxy.ProxyCtx) (*http.Request, *http.Response) {
|
||||
panic("should never get here, previous response is no null")
|
||||
})
|
||||
|
||||
client, l := oneShotProxy(proxy, t)
|
||||
defer l.Close()
|
||||
|
||||
if resp := string(getOrFail(srv.URL+"/", client, t)); resp != "koko" {
|
||||
t.Error("should return always koko and not", resp)
|
||||
}
|
||||
}
|
||||
|
||||
func constantHttpServer(content []byte) (addr string) {
|
||||
l, err := net.Listen("tcp", "localhost:0")
|
||||
panicOnErr(err, "listen")
|
||||
go func() {
|
||||
c, err := l.Accept()
|
||||
panicOnErr(err, "accept")
|
||||
buf := bufio.NewReader(c)
|
||||
_, err = http.ReadRequest(buf)
|
||||
panicOnErr(err, "readReq")
|
||||
c.Write(content)
|
||||
c.Close()
|
||||
l.Close()
|
||||
}()
|
||||
return l.Addr().String()
|
||||
}
|
||||
|
||||
func TestIcyResponse(t *testing.T) {
|
||||
// TODO: fix this test
|
||||
return // skip for now
|
||||
s := constantHttpServer([]byte("ICY 200 OK\r\n\r\nblablabla"))
|
||||
proxy := goproxy.NewProxyHttpServer()
|
||||
proxy.Verbose = true
|
||||
_, l := oneShotProxy(proxy, t)
|
||||
defer l.Close()
|
||||
req, err := http.NewRequest("GET", "http://"+s, nil)
|
||||
panicOnErr(err, "newReq")
|
||||
proxyip := l.URL[len("http://"):]
|
||||
println("got ip: " + proxyip)
|
||||
c, err := net.Dial("tcp", proxyip)
|
||||
panicOnErr(err, "dial")
|
||||
defer c.Close()
|
||||
req.WriteProxy(c)
|
||||
raw, err := ioutil.ReadAll(c)
|
||||
panicOnErr(err, "readAll")
|
||||
if string(raw) != "ICY 200 OK\r\n\r\nblablabla" {
|
||||
t.Error("Proxy did not send the malformed response received")
|
||||
}
|
||||
}
|
||||
|
||||
type VerifyNoProxyHeaders struct {
|
||||
*testing.T
|
||||
}
|
||||
|
||||
func (v VerifyNoProxyHeaders) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Header.Get("Connection") != "" || r.Header.Get("Proxy-Connection") != "" ||
|
||||
r.Header.Get("Proxy-Authenticate") != "" || r.Header.Get("Proxy-Authorization") != "" {
|
||||
v.Error("Got Connection header from goproxy", r.Header)
|
||||
}
|
||||
}
|
||||
|
||||
func TestNoProxyHeaders(t *testing.T) {
|
||||
s := httptest.NewServer(VerifyNoProxyHeaders{t})
|
||||
client, l := oneShotProxy(goproxy.NewProxyHttpServer(), t)
|
||||
defer l.Close()
|
||||
req, err := http.NewRequest("GET", s.URL, nil)
|
||||
panicOnErr(err, "bad request")
|
||||
req.Header.Add("Connection", "close")
|
||||
req.Header.Add("Proxy-Connection", "close")
|
||||
req.Header.Add("Proxy-Authenticate", "auth")
|
||||
req.Header.Add("Proxy-Authorization", "auth")
|
||||
client.Do(req)
|
||||
}
|
||||
|
||||
func TestNoProxyHeadersHttps(t *testing.T) {
|
||||
s := httptest.NewTLSServer(VerifyNoProxyHeaders{t})
|
||||
proxy := goproxy.NewProxyHttpServer()
|
||||
proxy.OnRequest().HandleConnect(goproxy.AlwaysMitm)
|
||||
client, l := oneShotProxy(proxy, t)
|
||||
defer l.Close()
|
||||
req, err := http.NewRequest("GET", s.URL, nil)
|
||||
panicOnErr(err, "bad request")
|
||||
req.Header.Add("Connection", "close")
|
||||
req.Header.Add("Proxy-Connection", "close")
|
||||
client.Do(req)
|
||||
}
|
||||
|
||||
func TestHeadReqHasContentLength(t *testing.T) {
|
||||
client, l := oneShotProxy(goproxy.NewProxyHttpServer(), t)
|
||||
defer l.Close()
|
||||
|
||||
resp, err := client.Head(localFile("test_data/panda.png"))
|
||||
panicOnErr(err, "resp to HEAD")
|
||||
if resp.Header.Get("Content-Length") == "" {
|
||||
t.Error("Content-Length should exist on HEAD requests")
|
||||
}
|
||||
}
|
||||
|
||||
func TestChunkedResponse(t *testing.T) {
|
||||
l, err := net.Listen("tcp", ":10234")
|
||||
panicOnErr(err, "listen")
|
||||
defer l.Close()
|
||||
go func() {
|
||||
for i := 0; i < 2; i++ {
|
||||
c, err := l.Accept()
|
||||
panicOnErr(err, "accept")
|
||||
_, err = http.ReadRequest(bufio.NewReader(c))
|
||||
panicOnErr(err, "readrequest")
|
||||
io.WriteString(c, "HTTP/1.1 200 OK\r\n"+
|
||||
"Content-Type: text/plain\r\n"+
|
||||
"Transfer-Encoding: chunked\r\n\r\n"+
|
||||
"25\r\n"+
|
||||
"This is the data in the first chunk\r\n\r\n"+
|
||||
"1C\r\n"+
|
||||
"and this is the second one\r\n\r\n"+
|
||||
"3\r\n"+
|
||||
"con\r\n"+
|
||||
"8\r\n"+
|
||||
"sequence\r\n0\r\n\r\n")
|
||||
c.Close()
|
||||
}
|
||||
}()
|
||||
|
||||
c, err := net.Dial("tcp", "localhost:10234")
|
||||
panicOnErr(err, "dial")
|
||||
defer c.Close()
|
||||
req, _ := http.NewRequest("GET", "/", nil)
|
||||
req.Write(c)
|
||||
resp, err := http.ReadResponse(bufio.NewReader(c), req)
|
||||
panicOnErr(err, "readresp")
|
||||
b, err := ioutil.ReadAll(resp.Body)
|
||||
panicOnErr(err, "readall")
|
||||
expected := "This is the data in the first chunk\r\nand this is the second one\r\nconsequence"
|
||||
if string(b) != expected {
|
||||
t.Errorf("Got `%v` expected `%v`", string(b), expected)
|
||||
}
|
||||
|
||||
proxy := goproxy.NewProxyHttpServer()
|
||||
proxy.OnResponse().DoFunc(func(resp *http.Response, ctx *goproxy.ProxyCtx) *http.Response {
|
||||
panicOnErr(ctx.Error, "error reading output")
|
||||
b, err := ioutil.ReadAll(resp.Body)
|
||||
resp.Body.Close()
|
||||
panicOnErr(err, "readall onresp")
|
||||
if enc := resp.Header.Get("Transfer-Encoding"); enc != "" {
|
||||
t.Fatal("Chunked response should be received as plaintext", enc)
|
||||
}
|
||||
resp.Body = ioutil.NopCloser(bytes.NewBufferString(strings.Replace(string(b), "e", "E", -1)))
|
||||
return resp
|
||||
})
|
||||
|
||||
client, s := oneShotProxy(proxy, t)
|
||||
defer s.Close()
|
||||
|
||||
resp, err = client.Get("http://localhost:10234/")
|
||||
panicOnErr(err, "client.Get")
|
||||
b, err = ioutil.ReadAll(resp.Body)
|
||||
panicOnErr(err, "readall proxy")
|
||||
if string(b) != strings.Replace(expected, "e", "E", -1) {
|
||||
t.Error("expected", expected, "w/ e->E. Got", string(b))
|
||||
}
|
||||
}
|
||||
|
||||
func TestGoproxyThroughProxy(t *testing.T) {
|
||||
proxy := goproxy.NewProxyHttpServer()
|
||||
proxy2 := goproxy.NewProxyHttpServer()
|
||||
doubleString := func(resp *http.Response, ctx *goproxy.ProxyCtx) *http.Response {
|
||||
b, err := ioutil.ReadAll(resp.Body)
|
||||
panicOnErr(err, "readAll resp")
|
||||
resp.Body = ioutil.NopCloser(bytes.NewBufferString(string(b) + " " + string(b)))
|
||||
return resp
|
||||
}
|
||||
proxy.OnRequest().HandleConnect(goproxy.AlwaysMitm)
|
||||
proxy.OnResponse().DoFunc(doubleString)
|
||||
|
||||
_, l := oneShotProxy(proxy, t)
|
||||
defer l.Close()
|
||||
|
||||
proxy2.ConnectDial = proxy2.NewConnectDialToProxy(l.URL)
|
||||
|
||||
client, l2 := oneShotProxy(proxy2, t)
|
||||
defer l2.Close()
|
||||
if r := string(getOrFail(https.URL+"/bobo", client, t)); r != "bobo bobo" {
|
||||
t.Error("Expected bobo doubled twice, got", r)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestGoproxyHijackConnect(t *testing.T) {
|
||||
proxy := goproxy.NewProxyHttpServer()
|
||||
proxy.OnRequest(goproxy.ReqHostIs(srv.Listener.Addr().String())).
|
||||
HijackConnect(func(req *http.Request, client net.Conn, ctx *goproxy.ProxyCtx) {
|
||||
t.Logf("URL %+#v\nSTR %s", req.URL, req.URL.String())
|
||||
resp, err := http.Get("http:" + req.URL.String() + "/bobo")
|
||||
panicOnErr(err, "http.Get(CONNECT url)")
|
||||
panicOnErr(resp.Write(client), "resp.Write(client)")
|
||||
resp.Body.Close()
|
||||
client.Close()
|
||||
})
|
||||
client, l := oneShotProxy(proxy, t)
|
||||
defer l.Close()
|
||||
proxyAddr := l.Listener.Addr().String()
|
||||
conn, err := net.Dial("tcp", proxyAddr)
|
||||
panicOnErr(err, "conn "+proxyAddr)
|
||||
buf := bufio.NewReader(conn)
|
||||
writeConnect(conn)
|
||||
readConnectResponse(buf)
|
||||
if txt := readResponse(buf); txt != "bobo" {
|
||||
t.Error("Expected bobo for CONNECT /foo, got", txt)
|
||||
}
|
||||
|
||||
if r := string(getOrFail(https.URL+"/bobo", client, t)); r != "bobo" {
|
||||
t.Error("Expected bobo would keep working with CONNECT", r)
|
||||
}
|
||||
}
|
||||
|
||||
func readResponse(buf *bufio.Reader) string {
|
||||
req, err := http.NewRequest("GET", srv.URL, nil)
|
||||
panicOnErr(err, "NewRequest")
|
||||
resp, err := http.ReadResponse(buf, req)
|
||||
panicOnErr(err, "resp.Read")
|
||||
defer resp.Body.Close()
|
||||
txt, err := ioutil.ReadAll(resp.Body)
|
||||
panicOnErr(err, "resp.Read")
|
||||
return string(txt)
|
||||
}
|
||||
|
||||
func writeConnect(w io.Writer) {
|
||||
req, err := http.NewRequest("CONNECT", srv.URL[len("http://"):], nil)
|
||||
panicOnErr(err, "NewRequest")
|
||||
req.Write(w)
|
||||
panicOnErr(err, "req(CONNECT).Write")
|
||||
}
|
||||
|
||||
func readConnectResponse(buf *bufio.Reader) {
|
||||
_, err := buf.ReadString('\n')
|
||||
panicOnErr(err, "resp.Read connect resp")
|
||||
_, err = buf.ReadString('\n')
|
||||
panicOnErr(err, "resp.Read connect resp")
|
||||
}
|
||||
|
||||
func TestCurlMinusP(t *testing.T) {
|
||||
proxy := goproxy.NewProxyHttpServer()
|
||||
proxy.OnRequest().HandleConnectFunc(func(host string, ctx *goproxy.ProxyCtx) (*goproxy.ConnectAction, string) {
|
||||
return goproxy.HTTPMitmConnect, host
|
||||
})
|
||||
called := false
|
||||
proxy.OnRequest().DoFunc(func(req *http.Request, ctx *goproxy.ProxyCtx) (*http.Request, *http.Response) {
|
||||
called = true
|
||||
return req, nil
|
||||
})
|
||||
_, l := oneShotProxy(proxy, t)
|
||||
defer l.Close()
|
||||
cmd := exec.Command("curl", "-p", "-sS", "--proxy", l.URL, srv.URL+"/bobo")
|
||||
output, err := cmd.CombinedOutput()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if string(output) != "bobo" {
|
||||
t.Error("Expected bobo, got", string(output))
|
||||
}
|
||||
if !called {
|
||||
t.Error("handler not called")
|
||||
}
|
||||
}
|
||||
|
||||
func TestSelfRequest(t *testing.T) {
|
||||
proxy := goproxy.NewProxyHttpServer()
|
||||
_, l := oneShotProxy(proxy, t)
|
||||
defer l.Close()
|
||||
if !strings.Contains(string(getOrFail(l.URL, http.DefaultClient, t)), "non-proxy") {
|
||||
t.Fatal("non proxy requests should fail")
|
||||
}
|
||||
}
|
||||
|
||||
func TestHasGoproxyCA(t *testing.T) {
|
||||
proxy := goproxy.NewProxyHttpServer()
|
||||
proxy.OnRequest().HandleConnect(goproxy.AlwaysMitm)
|
||||
s := httptest.NewServer(proxy)
|
||||
|
||||
proxyUrl, _ := url.Parse(s.URL)
|
||||
goproxyCA := x509.NewCertPool()
|
||||
goproxyCA.AddCert(goproxy.GoproxyCa.Leaf)
|
||||
|
||||
tr := &http.Transport{TLSClientConfig: &tls.Config{RootCAs: goproxyCA}, Proxy: http.ProxyURL(proxyUrl)}
|
||||
client := &http.Client{Transport: tr}
|
||||
|
||||
if resp := string(getOrFail(https.URL+"/bobo", client, t)); resp != "bobo" {
|
||||
t.Error("Wrong response when mitm", resp, "expected bobo")
|
||||
}
|
||||
}
|
||||
|
||||
func TestHttpsMitmURLRewrite(t *testing.T) {
|
||||
scheme := "https"
|
||||
|
||||
testCases := []struct {
|
||||
Host string
|
||||
RawPath string
|
||||
AddOpaque bool
|
||||
}{
|
||||
{
|
||||
Host: "example.com",
|
||||
RawPath: "/blah/v1/data/realtime",
|
||||
AddOpaque: true,
|
||||
},
|
||||
{
|
||||
Host: "example.com:443",
|
||||
RawPath: "/blah/v1/data/realtime?encodedURL=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.profile",
|
||||
},
|
||||
{
|
||||
Host: "example.com:443",
|
||||
RawPath: "/blah/v1/data/realtime?unencodedURL=https://www.googleapis.com/auth/userinfo.profile",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
proxy := goproxy.NewProxyHttpServer()
|
||||
proxy.OnRequest().HandleConnect(goproxy.AlwaysMitm)
|
||||
|
||||
proxy.OnRequest(goproxy.DstHostIs(tc.Host)).DoFunc(
|
||||
func(req *http.Request, ctx *goproxy.ProxyCtx) (*http.Request, *http.Response) {
|
||||
return nil, goproxy.TextResponse(req, "Dummy response")
|
||||
})
|
||||
|
||||
client, s := oneShotProxy(proxy, t)
|
||||
defer s.Close()
|
||||
|
||||
fullURL := scheme + "://" + tc.Host + tc.RawPath
|
||||
req, err := http.NewRequest("GET", fullURL, nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if tc.AddOpaque {
|
||||
req.URL.Scheme = scheme
|
||||
req.URL.Opaque = "//" + tc.Host + tc.RawPath
|
||||
}
|
||||
|
||||
resp, err := client.Do(req)
|
||||
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
b, err := ioutil.ReadAll(resp.Body)
|
||||
defer resp.Body.Close()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
body := string(b)
|
||||
if body != "Dummy response" {
|
||||
t.Errorf("Expected proxy to return dummy body content but got %s", body)
|
||||
}
|
||||
|
||||
if resp.StatusCode != http.StatusAccepted {
|
||||
t.Errorf("Expected status: %d, got: %d", http.StatusAccepted, resp.StatusCode)
|
||||
}
|
||||
}
|
||||
}
|
97
vendor/github.com/elazarl/goproxy/regretable/regretreader.go
generated
vendored
97
vendor/github.com/elazarl/goproxy/regretable/regretreader.go
generated
vendored
|
@ -1,97 +0,0 @@
|
|||
package regretable
|
||||
|
||||
import (
|
||||
"io"
|
||||
)
|
||||
|
||||
// A RegretableReader will allow you to read from a reader, and then
|
||||
// to "regret" reading it, and push back everything you've read.
|
||||
// For example,
|
||||
// rb := NewRegretableReader(bytes.NewBuffer([]byte{1,2,3}))
|
||||
// var b = make([]byte,1)
|
||||
// rb.Read(b) // b[0] = 1
|
||||
// rb.Regret()
|
||||
// ioutil.ReadAll(rb.Read) // returns []byte{1,2,3},nil
|
||||
type RegretableReader struct {
|
||||
reader io.Reader
|
||||
overflow bool
|
||||
r, w int
|
||||
buf []byte
|
||||
}
|
||||
|
||||
var defaultBufferSize = 500
|
||||
|
||||
// Same as RegretableReader, but allows closing the underlying reader
|
||||
type RegretableReaderCloser struct {
|
||||
RegretableReader
|
||||
c io.Closer
|
||||
}
|
||||
|
||||
// Closes the underlying readCloser, you cannot regret after closing the stream
|
||||
func (rbc *RegretableReaderCloser) Close() error {
|
||||
return rbc.c.Close()
|
||||
}
|
||||
|
||||
// initialize a RegretableReaderCloser with underlying readCloser rc
|
||||
func NewRegretableReaderCloser(rc io.ReadCloser) *RegretableReaderCloser {
|
||||
return &RegretableReaderCloser{*NewRegretableReader(rc), rc}
|
||||
}
|
||||
|
||||
// initialize a RegretableReaderCloser with underlying readCloser rc
|
||||
func NewRegretableReaderCloserSize(rc io.ReadCloser, size int) *RegretableReaderCloser {
|
||||
return &RegretableReaderCloser{*NewRegretableReaderSize(rc, size), rc}
|
||||
}
|
||||
|
||||
// The next read from the RegretableReader will be as if the underlying reader
|
||||
// was never read (or from the last point forget is called).
|
||||
func (rb *RegretableReader) Regret() {
|
||||
if rb.overflow {
|
||||
panic("regretting after overflow makes no sense")
|
||||
}
|
||||
rb.r = 0
|
||||
}
|
||||
|
||||
// Will "forget" everything read so far.
|
||||
// rb := NewRegretableReader(bytes.NewBuffer([]byte{1,2,3}))
|
||||
// var b = make([]byte,1)
|
||||
// rb.Read(b) // b[0] = 1
|
||||
// rb.Forget()
|
||||
// rb.Read(b) // b[0] = 2
|
||||
// rb.Regret()
|
||||
// ioutil.ReadAll(rb.Read) // returns []byte{2,3},nil
|
||||
func (rb *RegretableReader) Forget() {
|
||||
if rb.overflow {
|
||||
panic("forgetting after overflow makes no sense")
|
||||
}
|
||||
rb.r = 0
|
||||
rb.w = 0
|
||||
}
|
||||
|
||||
// initialize a RegretableReader with underlying reader r, whose buffer is size bytes long
|
||||
func NewRegretableReaderSize(r io.Reader, size int) *RegretableReader {
|
||||
return &RegretableReader{reader: r, buf: make([]byte, size) }
|
||||
}
|
||||
|
||||
// initialize a RegretableReader with underlying reader r
|
||||
func NewRegretableReader(r io.Reader) *RegretableReader {
|
||||
return NewRegretableReaderSize(r, defaultBufferSize)
|
||||
}
|
||||
|
||||
// reads from the underlying reader. Will buffer all input until Regret is called.
|
||||
func (rb *RegretableReader) Read(p []byte) (n int, err error) {
|
||||
if rb.overflow {
|
||||
return rb.reader.Read(p)
|
||||
}
|
||||
if rb.r < rb.w {
|
||||
n = copy(p, rb.buf[rb.r:rb.w])
|
||||
rb.r += n
|
||||
return
|
||||
}
|
||||
n, err = rb.reader.Read(p)
|
||||
bn := copy(rb.buf[rb.w:], p[:n])
|
||||
rb.w, rb.r = rb.w + bn, rb.w + n
|
||||
if bn < n {
|
||||
rb.overflow = true
|
||||
}
|
||||
return
|
||||
}
|
174
vendor/github.com/elazarl/goproxy/regretable/regretreader_test.go
generated
vendored
174
vendor/github.com/elazarl/goproxy/regretable/regretreader_test.go
generated
vendored
|
@ -1,174 +0,0 @@
|
|||
package regretable_test
|
||||
|
||||
import (
|
||||
. "github.com/elazarl/goproxy/regretable"
|
||||
"bytes"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestRegretableReader(t *testing.T) {
|
||||
buf := new(bytes.Buffer)
|
||||
mb := NewRegretableReader(buf)
|
||||
word := "12345678"
|
||||
buf.WriteString(word)
|
||||
|
||||
fivebytes := make([]byte, 5)
|
||||
mb.Read(fivebytes)
|
||||
mb.Regret()
|
||||
|
||||
s, _ := ioutil.ReadAll(mb)
|
||||
if string(s) != word {
|
||||
t.Errorf("Uncommited read is gone, [%d,%d] actual '%v' expected '%v'\n", len(s), len(word), string(s), word)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRegretableEmptyRead(t *testing.T) {
|
||||
buf := new(bytes.Buffer)
|
||||
mb := NewRegretableReader(buf)
|
||||
word := "12345678"
|
||||
buf.WriteString(word)
|
||||
|
||||
zero := make([]byte, 0)
|
||||
mb.Read(zero)
|
||||
mb.Regret()
|
||||
|
||||
s, err := ioutil.ReadAll(mb)
|
||||
if string(s) != word {
|
||||
t.Error("Uncommited read is gone, actual:", string(s), "expected:", word, "err:", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRegretableAlsoEmptyRead(t *testing.T) {
|
||||
buf := new(bytes.Buffer)
|
||||
mb := NewRegretableReader(buf)
|
||||
word := "12345678"
|
||||
buf.WriteString(word)
|
||||
|
||||
one := make([]byte, 1)
|
||||
zero := make([]byte, 0)
|
||||
five := make([]byte, 5)
|
||||
mb.Read(one)
|
||||
mb.Read(zero)
|
||||
mb.Read(five)
|
||||
mb.Regret()
|
||||
|
||||
s, _ := ioutil.ReadAll(mb)
|
||||
if string(s) != word {
|
||||
t.Error("Uncommited read is gone", string(s), "expected", word)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRegretableRegretBeforeRead(t *testing.T) {
|
||||
buf := new(bytes.Buffer)
|
||||
mb := NewRegretableReader(buf)
|
||||
word := "12345678"
|
||||
buf.WriteString(word)
|
||||
|
||||
five := make([]byte, 5)
|
||||
mb.Regret()
|
||||
mb.Read(five)
|
||||
|
||||
s, err := ioutil.ReadAll(mb)
|
||||
if string(s) != "678" {
|
||||
t.Error("Uncommited read is gone", string(s), len(string(s)), "expected", "678", len("678"), "err:", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRegretableFullRead(t *testing.T) {
|
||||
buf := new(bytes.Buffer)
|
||||
mb := NewRegretableReader(buf)
|
||||
word := "12345678"
|
||||
buf.WriteString(word)
|
||||
|
||||
twenty := make([]byte, 20)
|
||||
mb.Read(twenty)
|
||||
mb.Regret()
|
||||
|
||||
s, _ := ioutil.ReadAll(mb)
|
||||
if string(s) != word {
|
||||
t.Error("Uncommited read is gone", string(s), len(string(s)), "expected", word, len(word))
|
||||
}
|
||||
}
|
||||
|
||||
func assertEqual(t *testing.T, expected, actual string) {
|
||||
if expected!=actual {
|
||||
t.Fatal("Expected", expected, "actual", actual)
|
||||
}
|
||||
}
|
||||
|
||||
func assertReadAll(t *testing.T, r io.Reader) string {
|
||||
s, err := ioutil.ReadAll(r)
|
||||
if err!=nil {
|
||||
t.Fatal("error when reading", err)
|
||||
}
|
||||
return string(s)
|
||||
}
|
||||
|
||||
func TestRegretableRegretTwice(t *testing.T) {
|
||||
buf := new(bytes.Buffer)
|
||||
mb := NewRegretableReader(buf)
|
||||
word := "12345678"
|
||||
buf.WriteString(word)
|
||||
|
||||
assertEqual(t, word, assertReadAll(t, mb))
|
||||
mb.Regret()
|
||||
assertEqual(t, word, assertReadAll(t, mb))
|
||||
mb.Regret()
|
||||
assertEqual(t, word, assertReadAll(t, mb))
|
||||
}
|
||||
|
||||
type CloseCounter struct {
|
||||
r io.Reader
|
||||
closed int
|
||||
}
|
||||
|
||||
func (cc *CloseCounter) Read(b []byte) (int, error) {
|
||||
return cc.r.Read(b)
|
||||
}
|
||||
|
||||
func (cc *CloseCounter) Close() error {
|
||||
cc.closed++
|
||||
return nil
|
||||
}
|
||||
|
||||
func assert(t *testing.T, b bool, msg string) {
|
||||
if !b {
|
||||
t.Errorf("Assertion Error: %s", msg)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRegretableCloserSizeRegrets(t *testing.T) {
|
||||
defer func() {
|
||||
if r := recover(); r == nil || !strings.Contains(r.(string), "regret") {
|
||||
t.Error("Did not panic when regretting overread buffer:", r)
|
||||
}
|
||||
}()
|
||||
buf := new(bytes.Buffer)
|
||||
buf.WriteString("123456")
|
||||
mb := NewRegretableReaderCloserSize(ioutil.NopCloser(buf), 3)
|
||||
mb.Read(make([]byte, 4))
|
||||
mb.Regret()
|
||||
}
|
||||
|
||||
func TestRegretableCloserRegretsClose(t *testing.T) {
|
||||
buf := new(bytes.Buffer)
|
||||
cc := &CloseCounter{buf, 0}
|
||||
mb := NewRegretableReaderCloser(cc)
|
||||
word := "12345678"
|
||||
buf.WriteString(word)
|
||||
|
||||
mb.Read([]byte{0})
|
||||
mb.Close()
|
||||
if cc.closed != 1 {
|
||||
t.Error("RegretableReaderCloser ignores Close")
|
||||
}
|
||||
mb.Regret()
|
||||
mb.Close()
|
||||
if cc.closed != 2 {
|
||||
t.Error("RegretableReaderCloser does ignore Close after regret")
|
||||
}
|
||||
// TODO(elazar): return an error if client issues Close more than once after regret
|
||||
}
|
87
vendor/github.com/elazarl/goproxy/signer_test.go
generated
vendored
87
vendor/github.com/elazarl/goproxy/signer_test.go
generated
vendored
|
@ -1,87 +0,0 @@
|
|||
package goproxy
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"crypto/x509"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"os"
|
||||
"os/exec"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func orFatal(msg string, err error, t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatal(msg, err)
|
||||
}
|
||||
}
|
||||
|
||||
type ConstantHanlder string
|
||||
|
||||
func (h ConstantHanlder) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
w.Write([]byte(h))
|
||||
}
|
||||
|
||||
func getBrowser(args []string) string {
|
||||
for i, arg := range args {
|
||||
if arg == "-browser" && i+1 < len(arg) {
|
||||
return args[i+1]
|
||||
}
|
||||
if strings.HasPrefix(arg, "-browser=") {
|
||||
return arg[len("-browser="):]
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func TestSingerTls(t *testing.T) {
|
||||
cert, err := signHost(GoproxyCa, []string{"example.com", "1.1.1.1", "localhost"})
|
||||
orFatal("singHost", err, t)
|
||||
cert.Leaf, err = x509.ParseCertificate(cert.Certificate[0])
|
||||
orFatal("ParseCertificate", err, t)
|
||||
expected := "key verifies with Go"
|
||||
server := httptest.NewUnstartedServer(ConstantHanlder(expected))
|
||||
defer server.Close()
|
||||
server.TLS = &tls.Config{Certificates: []tls.Certificate{cert, GoproxyCa}}
|
||||
server.TLS.BuildNameToCertificate()
|
||||
server.StartTLS()
|
||||
certpool := x509.NewCertPool()
|
||||
certpool.AddCert(GoproxyCa.Leaf)
|
||||
tr := &http.Transport{
|
||||
TLSClientConfig: &tls.Config{RootCAs: certpool},
|
||||
}
|
||||
asLocalhost := strings.Replace(server.URL, "127.0.0.1", "localhost", -1)
|
||||
req, err := http.NewRequest("GET", asLocalhost, nil)
|
||||
orFatal("NewRequest", err, t)
|
||||
resp, err := tr.RoundTrip(req)
|
||||
orFatal("RoundTrip", err, t)
|
||||
txt, err := ioutil.ReadAll(resp.Body)
|
||||
orFatal("ioutil.ReadAll", err, t)
|
||||
if string(txt) != expected {
|
||||
t.Errorf("Expected '%s' got '%s'", expected, string(txt))
|
||||
}
|
||||
browser := getBrowser(os.Args)
|
||||
if browser != "" {
|
||||
exec.Command(browser, asLocalhost).Run()
|
||||
time.Sleep(10 * time.Second)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSingerX509(t *testing.T) {
|
||||
cert, err := signHost(GoproxyCa, []string{"example.com", "1.1.1.1", "localhost"})
|
||||
orFatal("singHost", err, t)
|
||||
cert.Leaf, err = x509.ParseCertificate(cert.Certificate[0])
|
||||
orFatal("ParseCertificate", err, t)
|
||||
certpool := x509.NewCertPool()
|
||||
certpool.AddCert(GoproxyCa.Leaf)
|
||||
orFatal("VerifyHostname", cert.Leaf.VerifyHostname("example.com"), t)
|
||||
orFatal("CheckSignatureFrom", cert.Leaf.CheckSignatureFrom(GoproxyCa.Leaf), t)
|
||||
_, err = cert.Leaf.Verify(x509.VerifyOptions{
|
||||
DNSName: "example.com",
|
||||
Roots: certpool,
|
||||
})
|
||||
orFatal("Verify", err, t)
|
||||
}
|
BIN
vendor/github.com/elazarl/goproxy/test_data/baby.jpg
generated
vendored
BIN
vendor/github.com/elazarl/goproxy/test_data/baby.jpg
generated
vendored
Binary file not shown.
Before Width: | Height: | Size: 2.5 KiB |
BIN
vendor/github.com/elazarl/goproxy/test_data/football.png
generated
vendored
BIN
vendor/github.com/elazarl/goproxy/test_data/football.png
generated
vendored
Binary file not shown.
Before Width: | Height: | Size: 3.6 KiB |
BIN
vendor/github.com/elazarl/goproxy/test_data/panda.png
generated
vendored
BIN
vendor/github.com/elazarl/goproxy/test_data/panda.png
generated
vendored
Binary file not shown.
Before Width: | Height: | Size: 11 KiB |
19
vendor/github.com/elazarl/goproxy/transport/roundtripper.go
generated
vendored
19
vendor/github.com/elazarl/goproxy/transport/roundtripper.go
generated
vendored
|
@ -1,19 +0,0 @@
|
|||
package transport
|
||||
import "net/http"
|
||||
type RoundTripper interface {
|
||||
// RoundTrip executes a single HTTP transaction, returning
|
||||
// the Response for the request req. RoundTrip should not
|
||||
// attempt to interpret the response. In particular,
|
||||
// RoundTrip must return err == nil if it obtained a response,
|
||||
// regardless of the response's HTTP status code. A non-nil
|
||||
// err should be reserved for failure to obtain a response.
|
||||
// Similarly, RoundTrip should not attempt to handle
|
||||
// higher-level protocol details such as redirects,
|
||||
// authentication, or cookies.
|
||||
//
|
||||
// RoundTrip should not modify the request, except for
|
||||
// consuming the Body. The request's URL and Header fields
|
||||
// are guaranteed to be initialized.
|
||||
RoundTrip(*http.Request) (*http.Response, error)
|
||||
DetailedRoundTrip(*http.Request) (*RoundTripDetails, *http.Response, error)
|
||||
}
|
789
vendor/github.com/elazarl/goproxy/transport/transport.go
generated
vendored
789
vendor/github.com/elazarl/goproxy/transport/transport.go
generated
vendored
|
@ -1,789 +0,0 @@
|
|||
// Copyright 2011 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// HTTP client implementation. See RFC 2616.
|
||||
//
|
||||
// This is the low-level Transport implementation of RoundTripper.
|
||||
// The high-level interface is in client.go.
|
||||
|
||||
// This file is DEPRECATED and keep solely for backward compatibility.
|
||||
|
||||
package transport
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"bufio"
|
||||
"compress/gzip"
|
||||
"crypto/tls"
|
||||
"encoding/base64"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net"
|
||||
"net/url"
|
||||
"os"
|
||||
"strings"
|
||||
"sync"
|
||||
)
|
||||
|
||||
// DefaultTransport is the default implementation of Transport and is
|
||||
// used by DefaultClient. It establishes a new network connection for
|
||||
// each call to Do and uses HTTP proxies as directed by the
|
||||
// $HTTP_PROXY and $NO_PROXY (or $http_proxy and $no_proxy)
|
||||
// environment variables.
|
||||
var DefaultTransport RoundTripper = &Transport{Proxy: ProxyFromEnvironment}
|
||||
|
||||
// DefaultMaxIdleConnsPerHost is the default value of Transport's
|
||||
// MaxIdleConnsPerHost.
|
||||
const DefaultMaxIdleConnsPerHost = 2
|
||||
|
||||
// Transport is an implementation of RoundTripper that supports http,
|
||||
// https, and http proxies (for either http or https with CONNECT).
|
||||
// Transport can also cache connections for future re-use.
|
||||
type Transport struct {
|
||||
lk sync.Mutex
|
||||
idleConn map[string][]*persistConn
|
||||
altProto map[string]RoundTripper // nil or map of URI scheme => RoundTripper
|
||||
|
||||
// TODO: tunable on global max cached connections
|
||||
// TODO: tunable on timeout on cached connections
|
||||
// TODO: optional pipelining
|
||||
|
||||
// Proxy specifies a function to return a proxy for a given
|
||||
// Request. If the function returns a non-nil error, the
|
||||
// request is aborted with the provided error.
|
||||
// If Proxy is nil or returns a nil *URL, no proxy is used.
|
||||
Proxy func(*http.Request) (*url.URL, error)
|
||||
|
||||
// Dial specifies the dial function for creating TCP
|
||||
// connections.
|
||||
// If Dial is nil, net.Dial is used.
|
||||
Dial func(net, addr string) (c net.Conn, err error)
|
||||
|
||||
// TLSClientConfig specifies the TLS configuration to use with
|
||||
// tls.Client. If nil, the default configuration is used.
|
||||
TLSClientConfig *tls.Config
|
||||
|
||||
DisableKeepAlives bool
|
||||
DisableCompression bool
|
||||
|
||||
// MaxIdleConnsPerHost, if non-zero, controls the maximum idle
|
||||
// (keep-alive) to keep to keep per-host. If zero,
|
||||
// DefaultMaxIdleConnsPerHost is used.
|
||||
MaxIdleConnsPerHost int
|
||||
}
|
||||
|
||||
// ProxyFromEnvironment returns the URL of the proxy to use for a
|
||||
// given request, as indicated by the environment variables
|
||||
// $HTTP_PROXY and $NO_PROXY (or $http_proxy and $no_proxy).
|
||||
// An error is returned if the proxy environment is invalid.
|
||||
// A nil URL and nil error are returned if no proxy is defined in the
|
||||
// environment, or a proxy should not be used for the given request.
|
||||
func ProxyFromEnvironment(req *http.Request) (*url.URL, error) {
|
||||
proxy := getenvEitherCase("HTTP_PROXY")
|
||||
if proxy == "" {
|
||||
return nil, nil
|
||||
}
|
||||
if !useProxy(canonicalAddr(req.URL)) {
|
||||
return nil, nil
|
||||
}
|
||||
proxyURL, err := url.Parse(proxy)
|
||||
if err != nil || proxyURL.Scheme == "" {
|
||||
if u, err := url.Parse("http://" + proxy); err == nil {
|
||||
proxyURL = u
|
||||
err = nil
|
||||
}
|
||||
}
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("invalid proxy address %q: %v", proxy, err)
|
||||
}
|
||||
return proxyURL, nil
|
||||
}
|
||||
|
||||
// ProxyURL returns a proxy function (for use in a Transport)
|
||||
// that always returns the same URL.
|
||||
func ProxyURL(fixedURL *url.URL) func(*http.Request) (*url.URL, error) {
|
||||
return func(*http.Request) (*url.URL, error) {
|
||||
return fixedURL, nil
|
||||
}
|
||||
}
|
||||
|
||||
// transportRequest is a wrapper around a *Request that adds
|
||||
// optional extra headers to write.
|
||||
type transportRequest struct {
|
||||
*http.Request // original request, not to be mutated
|
||||
extra http.Header // extra headers to write, or nil
|
||||
}
|
||||
|
||||
func (tr *transportRequest) extraHeaders() http.Header {
|
||||
if tr.extra == nil {
|
||||
tr.extra = make(http.Header)
|
||||
}
|
||||
return tr.extra
|
||||
}
|
||||
|
||||
type RoundTripDetails struct {
|
||||
Host string
|
||||
TCPAddr *net.TCPAddr
|
||||
IsProxy bool
|
||||
Error error
|
||||
}
|
||||
|
||||
func (t *Transport) DetailedRoundTrip(req *http.Request) (details *RoundTripDetails, resp *http.Response, err error) {
|
||||
if req.URL == nil {
|
||||
return nil, nil, errors.New("http: nil Request.URL")
|
||||
}
|
||||
if req.Header == nil {
|
||||
return nil, nil, errors.New("http: nil Request.Header")
|
||||
}
|
||||
if req.URL.Scheme != "http" && req.URL.Scheme != "https" {
|
||||
t.lk.Lock()
|
||||
var rt RoundTripper
|
||||
if t.altProto != nil {
|
||||
rt = t.altProto[req.URL.Scheme]
|
||||
}
|
||||
t.lk.Unlock()
|
||||
if rt == nil {
|
||||
return nil, nil, &badStringError{"unsupported protocol scheme", req.URL.Scheme}
|
||||
}
|
||||
return rt.DetailedRoundTrip(req)
|
||||
}
|
||||
treq := &transportRequest{Request: req}
|
||||
cm, err := t.connectMethodForRequest(treq)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
// Get the cached or newly-created connection to either the
|
||||
// host (for http or https), the http proxy, or the http proxy
|
||||
// pre-CONNECTed to https server. In any case, we'll be ready
|
||||
// to send it requests.
|
||||
pconn, err := t.getConn(cm)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
resp, err = pconn.roundTrip(treq)
|
||||
return &RoundTripDetails{pconn.host, pconn.ip, pconn.isProxy, err}, resp, err
|
||||
}
|
||||
|
||||
// RoundTrip implements the RoundTripper interface.
|
||||
func (t *Transport) RoundTrip(req *http.Request) (resp *http.Response, err error) {
|
||||
_, resp, err = t.DetailedRoundTrip(req)
|
||||
return
|
||||
}
|
||||
|
||||
// RegisterProtocol registers a new protocol with scheme.
|
||||
// The Transport will pass requests using the given scheme to rt.
|
||||
// It is rt's responsibility to simulate HTTP request semantics.
|
||||
//
|
||||
// RegisterProtocol can be used by other packages to provide
|
||||
// implementations of protocol schemes like "ftp" or "file".
|
||||
func (t *Transport) RegisterProtocol(scheme string, rt RoundTripper) {
|
||||
if scheme == "http" || scheme == "https" {
|
||||
panic("protocol " + scheme + " already registered")
|
||||
}
|
||||
t.lk.Lock()
|
||||
defer t.lk.Unlock()
|
||||
if t.altProto == nil {
|
||||
t.altProto = make(map[string]RoundTripper)
|
||||
}
|
||||
if _, exists := t.altProto[scheme]; exists {
|
||||
panic("protocol " + scheme + " already registered")
|
||||
}
|
||||
t.altProto[scheme] = rt
|
||||
}
|
||||
|
||||
// CloseIdleConnections closes any connections which were previously
|
||||
// connected from previous requests but are now sitting idle in
|
||||
// a "keep-alive" state. It does not interrupt any connections currently
|
||||
// in use.
|
||||
func (t *Transport) CloseIdleConnections() {
|
||||
t.lk.Lock()
|
||||
defer t.lk.Unlock()
|
||||
if t.idleConn == nil {
|
||||
return
|
||||
}
|
||||
for _, conns := range t.idleConn {
|
||||
for _, pconn := range conns {
|
||||
pconn.close()
|
||||
}
|
||||
}
|
||||
t.idleConn = make(map[string][]*persistConn)
|
||||
}
|
||||
|
||||
//
|
||||
// Private implementation past this point.
|
||||
//
|
||||
|
||||
func getenvEitherCase(k string) string {
|
||||
if v := os.Getenv(strings.ToUpper(k)); v != "" {
|
||||
return v
|
||||
}
|
||||
return os.Getenv(strings.ToLower(k))
|
||||
}
|
||||
|
||||
func (t *Transport) connectMethodForRequest(treq *transportRequest) (*connectMethod, error) {
|
||||
cm := &connectMethod{
|
||||
targetScheme: treq.URL.Scheme,
|
||||
targetAddr: canonicalAddr(treq.URL),
|
||||
}
|
||||
if t.Proxy != nil {
|
||||
var err error
|
||||
cm.proxyURL, err = t.Proxy(treq.Request)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return cm, nil
|
||||
}
|
||||
|
||||
// proxyAuth returns the Proxy-Authorization header to set
|
||||
// on requests, if applicable.
|
||||
func (cm *connectMethod) proxyAuth() string {
|
||||
if cm.proxyURL == nil {
|
||||
return ""
|
||||
}
|
||||
if u := cm.proxyURL.User; u != nil {
|
||||
return "Basic " + base64.URLEncoding.EncodeToString([]byte(u.String()))
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// putIdleConn adds pconn to the list of idle persistent connections awaiting
|
||||
// a new request.
|
||||
// If pconn is no longer needed or not in a good state, putIdleConn
|
||||
// returns false.
|
||||
func (t *Transport) putIdleConn(pconn *persistConn) bool {
|
||||
t.lk.Lock()
|
||||
defer t.lk.Unlock()
|
||||
if t.DisableKeepAlives || t.MaxIdleConnsPerHost < 0 {
|
||||
pconn.close()
|
||||
return false
|
||||
}
|
||||
if pconn.isBroken() {
|
||||
return false
|
||||
}
|
||||
key := pconn.cacheKey
|
||||
max := t.MaxIdleConnsPerHost
|
||||
if max == 0 {
|
||||
max = DefaultMaxIdleConnsPerHost
|
||||
}
|
||||
if len(t.idleConn[key]) >= max {
|
||||
pconn.close()
|
||||
return false
|
||||
}
|
||||
t.idleConn[key] = append(t.idleConn[key], pconn)
|
||||
return true
|
||||
}
|
||||
|
||||
func (t *Transport) getIdleConn(cm *connectMethod) (pconn *persistConn) {
|
||||
t.lk.Lock()
|
||||
defer t.lk.Unlock()
|
||||
if t.idleConn == nil {
|
||||
t.idleConn = make(map[string][]*persistConn)
|
||||
}
|
||||
key := cm.String()
|
||||
for {
|
||||
pconns, ok := t.idleConn[key]
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
if len(pconns) == 1 {
|
||||
pconn = pconns[0]
|
||||
delete(t.idleConn, key)
|
||||
} else {
|
||||
// 2 or more cached connections; pop last
|
||||
// TODO: queue?
|
||||
pconn = pconns[len(pconns)-1]
|
||||
t.idleConn[key] = pconns[0 : len(pconns)-1]
|
||||
}
|
||||
if !pconn.isBroken() {
|
||||
return
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (t *Transport) dial(network, addr string) (c net.Conn, raddr string, ip *net.TCPAddr, err error) {
|
||||
if t.Dial != nil {
|
||||
ip, err = net.ResolveTCPAddr("tcp", addr)
|
||||
if err!=nil {
|
||||
return
|
||||
}
|
||||
c, err = t.Dial(network, addr)
|
||||
raddr = addr
|
||||
return
|
||||
}
|
||||
addri, err := net.ResolveTCPAddr("tcp", addr)
|
||||
if err!=nil {
|
||||
return
|
||||
}
|
||||
c, err = net.DialTCP("tcp", nil, addri)
|
||||
raddr = addr
|
||||
ip = addri
|
||||
return
|
||||
}
|
||||
|
||||
// getConn dials and creates a new persistConn to the target as
|
||||
// specified in the connectMethod. This includes doing a proxy CONNECT
|
||||
// and/or setting up TLS. If this doesn't return an error, the persistConn
|
||||
// is ready to write requests to.
|
||||
func (t *Transport) getConn(cm *connectMethod) (*persistConn, error) {
|
||||
if pc := t.getIdleConn(cm); pc != nil {
|
||||
return pc, nil
|
||||
}
|
||||
|
||||
conn, raddr, ip, err := t.dial("tcp", cm.addr())
|
||||
if err != nil {
|
||||
if cm.proxyURL != nil {
|
||||
err = fmt.Errorf("http: error connecting to proxy %s: %v", cm.proxyURL, err)
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
|
||||
pa := cm.proxyAuth()
|
||||
|
||||
pconn := &persistConn{
|
||||
t: t,
|
||||
cacheKey: cm.String(),
|
||||
conn: conn,
|
||||
reqch: make(chan requestAndChan, 50),
|
||||
host: raddr,
|
||||
ip: ip,
|
||||
}
|
||||
|
||||
switch {
|
||||
case cm.proxyURL == nil:
|
||||
// Do nothing.
|
||||
case cm.targetScheme == "http":
|
||||
pconn.isProxy = true
|
||||
if pa != "" {
|
||||
pconn.mutateHeaderFunc = func(h http.Header) {
|
||||
h.Set("Proxy-Authorization", pa)
|
||||
}
|
||||
}
|
||||
case cm.targetScheme == "https":
|
||||
connectReq := &http.Request{
|
||||
Method: "CONNECT",
|
||||
URL: &url.URL{Opaque: cm.targetAddr},
|
||||
Host: cm.targetAddr,
|
||||
Header: make(http.Header),
|
||||
}
|
||||
if pa != "" {
|
||||
connectReq.Header.Set("Proxy-Authorization", pa)
|
||||
}
|
||||
connectReq.Write(conn)
|
||||
|
||||
// Read response.
|
||||
// Okay to use and discard buffered reader here, because
|
||||
// TLS server will not speak until spoken to.
|
||||
br := bufio.NewReader(conn)
|
||||
resp, err := http.ReadResponse(br, connectReq)
|
||||
if err != nil {
|
||||
conn.Close()
|
||||
return nil, err
|
||||
}
|
||||
if resp.StatusCode != 200 {
|
||||
f := strings.SplitN(resp.Status, " ", 2)
|
||||
conn.Close()
|
||||
return nil, errors.New(f[1])
|
||||
}
|
||||
}
|
||||
|
||||
if cm.targetScheme == "https" {
|
||||
// Initiate TLS and check remote host name against certificate.
|
||||
conn = tls.Client(conn, t.TLSClientConfig)
|
||||
if err = conn.(*tls.Conn).Handshake(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if t.TLSClientConfig == nil || !t.TLSClientConfig.InsecureSkipVerify {
|
||||
if err = conn.(*tls.Conn).VerifyHostname(cm.tlsHost()); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
pconn.conn = conn
|
||||
}
|
||||
|
||||
pconn.br = bufio.NewReader(pconn.conn)
|
||||
pconn.bw = bufio.NewWriter(pconn.conn)
|
||||
go pconn.readLoop()
|
||||
return pconn, nil
|
||||
}
|
||||
|
||||
// useProxy returns true if requests to addr should use a proxy,
|
||||
// according to the NO_PROXY or no_proxy environment variable.
|
||||
// addr is always a canonicalAddr with a host and port.
|
||||
func useProxy(addr string) bool {
|
||||
if len(addr) == 0 {
|
||||
return true
|
||||
}
|
||||
host, _, err := net.SplitHostPort(addr)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
if host == "localhost" {
|
||||
return false
|
||||
}
|
||||
if ip := net.ParseIP(host); ip != nil {
|
||||
if ip.IsLoopback() {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
no_proxy := getenvEitherCase("NO_PROXY")
|
||||
if no_proxy == "*" {
|
||||
return false
|
||||
}
|
||||
|
||||
addr = strings.ToLower(strings.TrimSpace(addr))
|
||||
if hasPort(addr) {
|
||||
addr = addr[:strings.LastIndex(addr, ":")]
|
||||
}
|
||||
|
||||
for _, p := range strings.Split(no_proxy, ",") {
|
||||
p = strings.ToLower(strings.TrimSpace(p))
|
||||
if len(p) == 0 {
|
||||
continue
|
||||
}
|
||||
if hasPort(p) {
|
||||
p = p[:strings.LastIndex(p, ":")]
|
||||
}
|
||||
if addr == p || (p[0] == '.' && (strings.HasSuffix(addr, p) || addr == p[1:])) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// connectMethod is the map key (in its String form) for keeping persistent
|
||||
// TCP connections alive for subsequent HTTP requests.
|
||||
//
|
||||
// A connect method may be of the following types:
|
||||
//
|
||||
// Cache key form Description
|
||||
// ----------------- -------------------------
|
||||
// ||http|foo.com http directly to server, no proxy
|
||||
// ||https|foo.com https directly to server, no proxy
|
||||
// http://proxy.com|https|foo.com http to proxy, then CONNECT to foo.com
|
||||
// http://proxy.com|http http to proxy, http to anywhere after that
|
||||
//
|
||||
// Note: no support to https to the proxy yet.
|
||||
//
|
||||
type connectMethod struct {
|
||||
proxyURL *url.URL // nil for no proxy, else full proxy URL
|
||||
targetScheme string // "http" or "https"
|
||||
targetAddr string // Not used if proxy + http targetScheme (4th example in table)
|
||||
}
|
||||
|
||||
func (ck *connectMethod) String() string {
|
||||
proxyStr := ""
|
||||
if ck.proxyURL != nil {
|
||||
proxyStr = ck.proxyURL.String()
|
||||
}
|
||||
return strings.Join([]string{proxyStr, ck.targetScheme, ck.targetAddr}, "|")
|
||||
}
|
||||
|
||||
// addr returns the first hop "host:port" to which we need to TCP connect.
|
||||
func (cm *connectMethod) addr() string {
|
||||
if cm.proxyURL != nil {
|
||||
return canonicalAddr(cm.proxyURL)
|
||||
}
|
||||
return cm.targetAddr
|
||||
}
|
||||
|
||||
// tlsHost returns the host name to match against the peer's
|
||||
// TLS certificate.
|
||||
func (cm *connectMethod) tlsHost() string {
|
||||
h := cm.targetAddr
|
||||
if hasPort(h) {
|
||||
h = h[:strings.LastIndex(h, ":")]
|
||||
}
|
||||
return h
|
||||
}
|
||||
|
||||
// persistConn wraps a connection, usually a persistent one
|
||||
// (but may be used for non-keep-alive requests as well)
|
||||
type persistConn struct {
|
||||
t *Transport
|
||||
cacheKey string // its connectMethod.String()
|
||||
conn net.Conn
|
||||
br *bufio.Reader // from conn
|
||||
bw *bufio.Writer // to conn
|
||||
reqch chan requestAndChan // written by roundTrip(); read by readLoop()
|
||||
isProxy bool
|
||||
|
||||
// mutateHeaderFunc is an optional func to modify extra
|
||||
// headers on each outbound request before it's written. (the
|
||||
// original Request given to RoundTrip is not modified)
|
||||
mutateHeaderFunc func(http.Header)
|
||||
|
||||
lk sync.Mutex // guards numExpectedResponses and broken
|
||||
numExpectedResponses int
|
||||
broken bool // an error has happened on this connection; marked broken so it's not reused.
|
||||
|
||||
host string
|
||||
ip *net.TCPAddr
|
||||
}
|
||||
|
||||
func (pc *persistConn) isBroken() bool {
|
||||
pc.lk.Lock()
|
||||
defer pc.lk.Unlock()
|
||||
return pc.broken
|
||||
}
|
||||
|
||||
var remoteSideClosedFunc func(error) bool // or nil to use default
|
||||
|
||||
func remoteSideClosed(err error) bool {
|
||||
if err == io.EOF {
|
||||
return true
|
||||
}
|
||||
if remoteSideClosedFunc != nil {
|
||||
return remoteSideClosedFunc(err)
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (pc *persistConn) readLoop() {
|
||||
alive := true
|
||||
var lastbody io.ReadCloser // last response body, if any, read on this connection
|
||||
|
||||
for alive {
|
||||
pb, err := pc.br.Peek(1)
|
||||
|
||||
pc.lk.Lock()
|
||||
if pc.numExpectedResponses == 0 {
|
||||
pc.closeLocked()
|
||||
pc.lk.Unlock()
|
||||
if len(pb) > 0 {
|
||||
log.Printf("Unsolicited response received on idle HTTP channel starting with %q; err=%v",
|
||||
string(pb), err)
|
||||
}
|
||||
return
|
||||
}
|
||||
pc.lk.Unlock()
|
||||
|
||||
rc := <-pc.reqch
|
||||
|
||||
// Advance past the previous response's body, if the
|
||||
// caller hasn't done so.
|
||||
if lastbody != nil {
|
||||
lastbody.Close() // assumed idempotent
|
||||
lastbody = nil
|
||||
}
|
||||
resp, err := http.ReadResponse(pc.br, rc.req)
|
||||
|
||||
if err != nil {
|
||||
pc.close()
|
||||
} else {
|
||||
hasBody := rc.req.Method != "HEAD" && resp.ContentLength != 0
|
||||
if rc.addedGzip && hasBody && resp.Header.Get("Content-Encoding") == "gzip" {
|
||||
resp.Header.Del("Content-Encoding")
|
||||
resp.Header.Del("Content-Length")
|
||||
resp.ContentLength = -1
|
||||
gzReader, zerr := gzip.NewReader(resp.Body)
|
||||
if zerr != nil {
|
||||
pc.close()
|
||||
err = zerr
|
||||
} else {
|
||||
resp.Body = &readFirstCloseBoth{&discardOnCloseReadCloser{gzReader}, resp.Body}
|
||||
}
|
||||
}
|
||||
resp.Body = &bodyEOFSignal{body: resp.Body}
|
||||
}
|
||||
|
||||
if err != nil || resp.Close || rc.req.Close {
|
||||
alive = false
|
||||
}
|
||||
|
||||
hasBody := resp != nil && resp.ContentLength != 0
|
||||
var waitForBodyRead chan bool
|
||||
if alive {
|
||||
if hasBody {
|
||||
lastbody = resp.Body
|
||||
waitForBodyRead = make(chan bool)
|
||||
resp.Body.(*bodyEOFSignal).fn = func() {
|
||||
if !pc.t.putIdleConn(pc) {
|
||||
alive = false
|
||||
}
|
||||
waitForBodyRead <- true
|
||||
}
|
||||
} else {
|
||||
// When there's no response body, we immediately
|
||||
// reuse the TCP connection (putIdleConn), but
|
||||
// we need to prevent ClientConn.Read from
|
||||
// closing the Response.Body on the next
|
||||
// loop, otherwise it might close the body
|
||||
// before the client code has had a chance to
|
||||
// read it (even though it'll just be 0, EOF).
|
||||
lastbody = nil
|
||||
|
||||
if !pc.t.putIdleConn(pc) {
|
||||
alive = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rc.ch <- responseAndError{resp, err}
|
||||
|
||||
// Wait for the just-returned response body to be fully consumed
|
||||
// before we race and peek on the underlying bufio reader.
|
||||
if waitForBodyRead != nil {
|
||||
<-waitForBodyRead
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type responseAndError struct {
|
||||
res *http.Response
|
||||
err error
|
||||
}
|
||||
|
||||
type requestAndChan struct {
|
||||
req *http.Request
|
||||
ch chan responseAndError
|
||||
|
||||
// did the Transport (as opposed to the client code) add an
|
||||
// Accept-Encoding gzip header? only if it we set it do
|
||||
// we transparently decode the gzip.
|
||||
addedGzip bool
|
||||
}
|
||||
|
||||
func (pc *persistConn) roundTrip(req *transportRequest) (resp *http.Response, err error) {
|
||||
if pc.mutateHeaderFunc != nil {
|
||||
panic("mutateHeaderFunc not supported in modified Transport")
|
||||
pc.mutateHeaderFunc(req.extraHeaders())
|
||||
}
|
||||
|
||||
// Ask for a compressed version if the caller didn't set their
|
||||
// own value for Accept-Encoding. We only attempted to
|
||||
// uncompress the gzip stream if we were the layer that
|
||||
// requested it.
|
||||
requestedGzip := false
|
||||
if !pc.t.DisableCompression && req.Header.Get("Accept-Encoding") == "" {
|
||||
// Request gzip only, not deflate. Deflate is ambiguous and
|
||||
// not as universally supported anyway.
|
||||
// See: http://www.gzip.org/zlib/zlib_faq.html#faq38
|
||||
requestedGzip = true
|
||||
req.extraHeaders().Set("Accept-Encoding", "gzip")
|
||||
}
|
||||
|
||||
pc.lk.Lock()
|
||||
pc.numExpectedResponses++
|
||||
pc.lk.Unlock()
|
||||
|
||||
// orig: err = req.Request.write(pc.bw, pc.isProxy, req.extra)
|
||||
if pc.isProxy {
|
||||
err = req.Request.WriteProxy(pc.bw)
|
||||
} else {
|
||||
err = req.Request.Write(pc.bw)
|
||||
}
|
||||
if err != nil {
|
||||
pc.close()
|
||||
return
|
||||
}
|
||||
pc.bw.Flush()
|
||||
|
||||
ch := make(chan responseAndError, 1)
|
||||
pc.reqch <- requestAndChan{req.Request, ch, requestedGzip}
|
||||
re := <-ch
|
||||
pc.lk.Lock()
|
||||
pc.numExpectedResponses--
|
||||
pc.lk.Unlock()
|
||||
|
||||
return re.res, re.err
|
||||
}
|
||||
|
||||
func (pc *persistConn) close() {
|
||||
pc.lk.Lock()
|
||||
defer pc.lk.Unlock()
|
||||
pc.closeLocked()
|
||||
}
|
||||
|
||||
func (pc *persistConn) closeLocked() {
|
||||
pc.broken = true
|
||||
pc.conn.Close()
|
||||
pc.mutateHeaderFunc = nil
|
||||
}
|
||||
|
||||
var portMap = map[string]string{
|
||||
"http": "80",
|
||||
"https": "443",
|
||||
}
|
||||
|
||||
// canonicalAddr returns url.Host but always with a ":port" suffix
|
||||
func canonicalAddr(url *url.URL) string {
|
||||
addr := url.Host
|
||||
if !hasPort(addr) {
|
||||
return addr + ":" + portMap[url.Scheme]
|
||||
}
|
||||
return addr
|
||||
}
|
||||
|
||||
func responseIsKeepAlive(res *http.Response) bool {
|
||||
// TODO: implement. for now just always shutting down the connection.
|
||||
return false
|
||||
}
|
||||
|
||||
// bodyEOFSignal wraps a ReadCloser but runs fn (if non-nil) at most
|
||||
// once, right before the final Read() or Close() call returns, but after
|
||||
// EOF has been seen.
|
||||
type bodyEOFSignal struct {
|
||||
body io.ReadCloser
|
||||
fn func()
|
||||
isClosed bool
|
||||
}
|
||||
|
||||
func (es *bodyEOFSignal) Read(p []byte) (n int, err error) {
|
||||
n, err = es.body.Read(p)
|
||||
if es.isClosed && n > 0 {
|
||||
panic("http: unexpected bodyEOFSignal Read after Close; see issue 1725")
|
||||
}
|
||||
if err == io.EOF && es.fn != nil {
|
||||
es.fn()
|
||||
es.fn = nil
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (es *bodyEOFSignal) Close() (err error) {
|
||||
if es.isClosed {
|
||||
return nil
|
||||
}
|
||||
es.isClosed = true
|
||||
err = es.body.Close()
|
||||
if err == nil && es.fn != nil {
|
||||
es.fn()
|
||||
es.fn = nil
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
type readFirstCloseBoth struct {
|
||||
io.ReadCloser
|
||||
io.Closer
|
||||
}
|
||||
|
||||
func (r *readFirstCloseBoth) Close() error {
|
||||
if err := r.ReadCloser.Close(); err != nil {
|
||||
r.Closer.Close()
|
||||
return err
|
||||
}
|
||||
if err := r.Closer.Close(); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// discardOnCloseReadCloser consumes all its input on Close.
|
||||
type discardOnCloseReadCloser struct {
|
||||
io.ReadCloser
|
||||
}
|
||||
|
||||
func (d *discardOnCloseReadCloser) Close() error {
|
||||
io.Copy(ioutil.Discard, d.ReadCloser) // ignore errors; likely invalid or already closed
|
||||
return d.ReadCloser.Close()
|
||||
}
|
15
vendor/github.com/elazarl/goproxy/transport/util.go
generated
vendored
15
vendor/github.com/elazarl/goproxy/transport/util.go
generated
vendored
|
@ -1,15 +0,0 @@
|
|||
package transport
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type badStringError struct {
|
||||
what string
|
||||
str string
|
||||
}
|
||||
|
||||
func (e *badStringError) Error() string { return fmt.Sprintf("%s %q", e.what, e.str) }
|
||||
|
||||
func hasPort(s string) bool { return strings.LastIndex(s, ":") > strings.LastIndex(s, "]") }
|
44
vendor/github.com/gobwas/glob/cmd/globdraw/main.go
generated
vendored
44
vendor/github.com/gobwas/glob/cmd/globdraw/main.go
generated
vendored
|
@ -1,44 +0,0 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"github.com/gobwas/glob"
|
||||
"github.com/gobwas/glob/match"
|
||||
"github.com/gobwas/glob/match/debug"
|
||||
"os"
|
||||
"strings"
|
||||
"unicode/utf8"
|
||||
)
|
||||
|
||||
func main() {
|
||||
pattern := flag.String("p", "", "pattern to draw")
|
||||
sep := flag.String("s", "", "comma separated list of separators characters")
|
||||
flag.Parse()
|
||||
|
||||
if *pattern == "" {
|
||||
flag.Usage()
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
var separators []rune
|
||||
if len(*sep) > 0 {
|
||||
for _, c := range strings.Split(*sep, ",") {
|
||||
if r, w := utf8.DecodeRuneInString(c); len(c) > w {
|
||||
fmt.Println("only single charactered separators are allowed")
|
||||
os.Exit(1)
|
||||
} else {
|
||||
separators = append(separators, r)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
glob, err := glob.Compile(*pattern, separators...)
|
||||
if err != nil {
|
||||
fmt.Println("could not compile pattern:", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
matcher := glob.(match.Matcher)
|
||||
fmt.Fprint(os.Stdout, debug.Graphviz(*pattern, matcher))
|
||||
}
|
82
vendor/github.com/gobwas/glob/cmd/globtest/main.go
generated
vendored
82
vendor/github.com/gobwas/glob/cmd/globtest/main.go
generated
vendored
|
@ -1,82 +0,0 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"github.com/gobwas/glob"
|
||||
"os"
|
||||
"strings"
|
||||
"testing"
|
||||
"unicode/utf8"
|
||||
)
|
||||
|
||||
func benchString(r testing.BenchmarkResult) string {
|
||||
nsop := r.NsPerOp()
|
||||
ns := fmt.Sprintf("%10d ns/op", nsop)
|
||||
allocs := "0"
|
||||
if r.N > 0 {
|
||||
if nsop < 100 {
|
||||
// The format specifiers here make sure that
|
||||
// the ones digits line up for all three possible formats.
|
||||
if nsop < 10 {
|
||||
ns = fmt.Sprintf("%13.2f ns/op", float64(r.T.Nanoseconds())/float64(r.N))
|
||||
} else {
|
||||
ns = fmt.Sprintf("%12.1f ns/op", float64(r.T.Nanoseconds())/float64(r.N))
|
||||
}
|
||||
}
|
||||
|
||||
allocs = fmt.Sprintf("%d", r.MemAllocs/uint64(r.N))
|
||||
}
|
||||
|
||||
return fmt.Sprintf("%8d\t%s\t%s allocs", r.N, ns, allocs)
|
||||
}
|
||||
|
||||
func main() {
|
||||
pattern := flag.String("p", "", "pattern to draw")
|
||||
sep := flag.String("s", "", "comma separated list of separators")
|
||||
fixture := flag.String("f", "", "fixture")
|
||||
verbose := flag.Bool("v", false, "verbose")
|
||||
flag.Parse()
|
||||
|
||||
if *pattern == "" {
|
||||
flag.Usage()
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
var separators []rune
|
||||
for _, c := range strings.Split(*sep, ",") {
|
||||
if r, w := utf8.DecodeRuneInString(c); len(c) > w {
|
||||
fmt.Println("only single charactered separators are allowed")
|
||||
os.Exit(1)
|
||||
} else {
|
||||
separators = append(separators, r)
|
||||
}
|
||||
}
|
||||
|
||||
g, err := glob.Compile(*pattern, separators...)
|
||||
if err != nil {
|
||||
fmt.Println("could not compile pattern:", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
if !*verbose {
|
||||
fmt.Println(g.Match(*fixture))
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Printf("result: %t\n", g.Match(*fixture))
|
||||
|
||||
cb := testing.Benchmark(func(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
glob.Compile(*pattern, separators...)
|
||||
}
|
||||
})
|
||||
fmt.Println("compile:", benchString(cb))
|
||||
|
||||
mb := testing.Benchmark(func(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
g.Match(*fixture)
|
||||
}
|
||||
})
|
||||
fmt.Println("match: ", benchString(mb))
|
||||
}
|
624
vendor/github.com/gobwas/glob/compiler/compiler_test.go
generated
vendored
624
vendor/github.com/gobwas/glob/compiler/compiler_test.go
generated
vendored
|
@ -1,624 +0,0 @@
|
|||
package compiler
|
||||
|
||||
import (
|
||||
"github.com/gobwas/glob/match"
|
||||
"github.com/gobwas/glob/match/debug"
|
||||
"github.com/gobwas/glob/syntax/ast"
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
|
||||
var separators = []rune{'.'}
|
||||
|
||||
func TestCommonChildren(t *testing.T) {
|
||||
for i, test := range []struct {
|
||||
nodes []*ast.Node
|
||||
left []*ast.Node
|
||||
right []*ast.Node
|
||||
}{
|
||||
{
|
||||
nodes: []*ast.Node{
|
||||
ast.NewNode(ast.KindNothing, nil,
|
||||
ast.NewNode(ast.KindText, ast.Text{"a"}),
|
||||
ast.NewNode(ast.KindText, ast.Text{"z"}),
|
||||
ast.NewNode(ast.KindText, ast.Text{"c"}),
|
||||
),
|
||||
},
|
||||
},
|
||||
{
|
||||
nodes: []*ast.Node{
|
||||
ast.NewNode(ast.KindNothing, nil,
|
||||
ast.NewNode(ast.KindText, ast.Text{"a"}),
|
||||
ast.NewNode(ast.KindText, ast.Text{"z"}),
|
||||
ast.NewNode(ast.KindText, ast.Text{"c"}),
|
||||
),
|
||||
ast.NewNode(ast.KindNothing, nil,
|
||||
ast.NewNode(ast.KindText, ast.Text{"a"}),
|
||||
ast.NewNode(ast.KindText, ast.Text{"b"}),
|
||||
ast.NewNode(ast.KindText, ast.Text{"c"}),
|
||||
),
|
||||
},
|
||||
left: []*ast.Node{
|
||||
ast.NewNode(ast.KindText, ast.Text{"a"}),
|
||||
},
|
||||
right: []*ast.Node{
|
||||
ast.NewNode(ast.KindText, ast.Text{"c"}),
|
||||
},
|
||||
},
|
||||
{
|
||||
nodes: []*ast.Node{
|
||||
ast.NewNode(ast.KindNothing, nil,
|
||||
ast.NewNode(ast.KindText, ast.Text{"a"}),
|
||||
ast.NewNode(ast.KindText, ast.Text{"b"}),
|
||||
ast.NewNode(ast.KindText, ast.Text{"c"}),
|
||||
ast.NewNode(ast.KindText, ast.Text{"d"}),
|
||||
),
|
||||
ast.NewNode(ast.KindNothing, nil,
|
||||
ast.NewNode(ast.KindText, ast.Text{"a"}),
|
||||
ast.NewNode(ast.KindText, ast.Text{"b"}),
|
||||
ast.NewNode(ast.KindText, ast.Text{"c"}),
|
||||
ast.NewNode(ast.KindText, ast.Text{"c"}),
|
||||
ast.NewNode(ast.KindText, ast.Text{"d"}),
|
||||
),
|
||||
},
|
||||
left: []*ast.Node{
|
||||
ast.NewNode(ast.KindText, ast.Text{"a"}),
|
||||
ast.NewNode(ast.KindText, ast.Text{"b"}),
|
||||
},
|
||||
right: []*ast.Node{
|
||||
ast.NewNode(ast.KindText, ast.Text{"c"}),
|
||||
ast.NewNode(ast.KindText, ast.Text{"d"}),
|
||||
},
|
||||
},
|
||||
{
|
||||
nodes: []*ast.Node{
|
||||
ast.NewNode(ast.KindNothing, nil,
|
||||
ast.NewNode(ast.KindText, ast.Text{"a"}),
|
||||
ast.NewNode(ast.KindText, ast.Text{"b"}),
|
||||
ast.NewNode(ast.KindText, ast.Text{"c"}),
|
||||
),
|
||||
ast.NewNode(ast.KindNothing, nil,
|
||||
ast.NewNode(ast.KindText, ast.Text{"a"}),
|
||||
ast.NewNode(ast.KindText, ast.Text{"b"}),
|
||||
ast.NewNode(ast.KindText, ast.Text{"b"}),
|
||||
ast.NewNode(ast.KindText, ast.Text{"c"}),
|
||||
),
|
||||
},
|
||||
left: []*ast.Node{
|
||||
ast.NewNode(ast.KindText, ast.Text{"a"}),
|
||||
ast.NewNode(ast.KindText, ast.Text{"b"}),
|
||||
},
|
||||
right: []*ast.Node{
|
||||
ast.NewNode(ast.KindText, ast.Text{"c"}),
|
||||
},
|
||||
},
|
||||
{
|
||||
nodes: []*ast.Node{
|
||||
ast.NewNode(ast.KindNothing, nil,
|
||||
ast.NewNode(ast.KindText, ast.Text{"a"}),
|
||||
ast.NewNode(ast.KindText, ast.Text{"d"}),
|
||||
),
|
||||
ast.NewNode(ast.KindNothing, nil,
|
||||
ast.NewNode(ast.KindText, ast.Text{"a"}),
|
||||
ast.NewNode(ast.KindText, ast.Text{"d"}),
|
||||
),
|
||||
ast.NewNode(ast.KindNothing, nil,
|
||||
ast.NewNode(ast.KindText, ast.Text{"a"}),
|
||||
ast.NewNode(ast.KindText, ast.Text{"e"}),
|
||||
),
|
||||
},
|
||||
left: []*ast.Node{
|
||||
ast.NewNode(ast.KindText, ast.Text{"a"}),
|
||||
},
|
||||
right: []*ast.Node{},
|
||||
},
|
||||
} {
|
||||
left, right := commonChildren(test.nodes)
|
||||
if !nodesEqual(left, test.left) {
|
||||
t.Errorf("[%d] left, right := commonChildren(); left = %v; want %v", i, left, test.left)
|
||||
}
|
||||
if !nodesEqual(right, test.right) {
|
||||
t.Errorf("[%d] left, right := commonChildren(); right = %v; want %v", i, right, test.right)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func nodesEqual(a, b []*ast.Node) bool {
|
||||
if len(a) != len(b) {
|
||||
return false
|
||||
}
|
||||
for i, av := range a {
|
||||
if !av.Equal(b[i]) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func TestGlueMatchers(t *testing.T) {
|
||||
for id, test := range []struct {
|
||||
in []match.Matcher
|
||||
exp match.Matcher
|
||||
}{
|
||||
{
|
||||
[]match.Matcher{
|
||||
match.NewSuper(),
|
||||
match.NewSingle(nil),
|
||||
},
|
||||
match.NewMin(1),
|
||||
},
|
||||
{
|
||||
[]match.Matcher{
|
||||
match.NewAny(separators),
|
||||
match.NewSingle(separators),
|
||||
},
|
||||
match.EveryOf{match.Matchers{
|
||||
match.NewMin(1),
|
||||
match.NewContains(string(separators), true),
|
||||
}},
|
||||
},
|
||||
{
|
||||
[]match.Matcher{
|
||||
match.NewSingle(nil),
|
||||
match.NewSingle(nil),
|
||||
match.NewSingle(nil),
|
||||
},
|
||||
match.EveryOf{match.Matchers{
|
||||
match.NewMin(3),
|
||||
match.NewMax(3),
|
||||
}},
|
||||
},
|
||||
{
|
||||
[]match.Matcher{
|
||||
match.NewList([]rune{'a'}, true),
|
||||
match.NewAny([]rune{'a'}),
|
||||
},
|
||||
match.EveryOf{match.Matchers{
|
||||
match.NewMin(1),
|
||||
match.NewContains("a", true),
|
||||
}},
|
||||
},
|
||||
} {
|
||||
act, err := compileMatchers(test.in)
|
||||
if err != nil {
|
||||
t.Errorf("#%d convert matchers error: %s", id, err)
|
||||
continue
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(act, test.exp) {
|
||||
t.Errorf("#%d unexpected convert matchers result:\nact: %#v;\nexp: %#v", id, act, test.exp)
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestCompileMatchers(t *testing.T) {
|
||||
for id, test := range []struct {
|
||||
in []match.Matcher
|
||||
exp match.Matcher
|
||||
}{
|
||||
{
|
||||
[]match.Matcher{
|
||||
match.NewSuper(),
|
||||
match.NewSingle(separators),
|
||||
match.NewText("c"),
|
||||
},
|
||||
match.NewBTree(
|
||||
match.NewText("c"),
|
||||
match.NewBTree(
|
||||
match.NewSingle(separators),
|
||||
match.NewSuper(),
|
||||
nil,
|
||||
),
|
||||
nil,
|
||||
),
|
||||
},
|
||||
{
|
||||
[]match.Matcher{
|
||||
match.NewAny(nil),
|
||||
match.NewText("c"),
|
||||
match.NewAny(nil),
|
||||
},
|
||||
match.NewBTree(
|
||||
match.NewText("c"),
|
||||
match.NewAny(nil),
|
||||
match.NewAny(nil),
|
||||
),
|
||||
},
|
||||
{
|
||||
[]match.Matcher{
|
||||
match.NewRange('a', 'c', true),
|
||||
match.NewList([]rune{'z', 't', 'e'}, false),
|
||||
match.NewText("c"),
|
||||
match.NewSingle(nil),
|
||||
},
|
||||
match.NewRow(
|
||||
4,
|
||||
match.Matchers{
|
||||
match.NewRange('a', 'c', true),
|
||||
match.NewList([]rune{'z', 't', 'e'}, false),
|
||||
match.NewText("c"),
|
||||
match.NewSingle(nil),
|
||||
}...,
|
||||
),
|
||||
},
|
||||
} {
|
||||
act, err := compileMatchers(test.in)
|
||||
if err != nil {
|
||||
t.Errorf("#%d convert matchers error: %s", id, err)
|
||||
continue
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(act, test.exp) {
|
||||
t.Errorf("#%d unexpected convert matchers result:\nact: %#v\nexp: %#v", id, act, test.exp)
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestConvertMatchers(t *testing.T) {
|
||||
for id, test := range []struct {
|
||||
in, exp []match.Matcher
|
||||
}{
|
||||
{
|
||||
[]match.Matcher{
|
||||
match.NewRange('a', 'c', true),
|
||||
match.NewList([]rune{'z', 't', 'e'}, false),
|
||||
match.NewText("c"),
|
||||
match.NewSingle(nil),
|
||||
match.NewAny(nil),
|
||||
},
|
||||
[]match.Matcher{
|
||||
match.NewRow(
|
||||
4,
|
||||
[]match.Matcher{
|
||||
match.NewRange('a', 'c', true),
|
||||
match.NewList([]rune{'z', 't', 'e'}, false),
|
||||
match.NewText("c"),
|
||||
match.NewSingle(nil),
|
||||
}...,
|
||||
),
|
||||
match.NewAny(nil),
|
||||
},
|
||||
},
|
||||
{
|
||||
[]match.Matcher{
|
||||
match.NewRange('a', 'c', true),
|
||||
match.NewList([]rune{'z', 't', 'e'}, false),
|
||||
match.NewText("c"),
|
||||
match.NewSingle(nil),
|
||||
match.NewAny(nil),
|
||||
match.NewSingle(nil),
|
||||
match.NewSingle(nil),
|
||||
match.NewAny(nil),
|
||||
},
|
||||
[]match.Matcher{
|
||||
match.NewRow(
|
||||
3,
|
||||
match.Matchers{
|
||||
match.NewRange('a', 'c', true),
|
||||
match.NewList([]rune{'z', 't', 'e'}, false),
|
||||
match.NewText("c"),
|
||||
}...,
|
||||
),
|
||||
match.NewMin(3),
|
||||
},
|
||||
},
|
||||
} {
|
||||
act := minimizeMatchers(test.in)
|
||||
if !reflect.DeepEqual(act, test.exp) {
|
||||
t.Errorf("#%d unexpected convert matchers 2 result:\nact: %#v\nexp: %#v", id, act, test.exp)
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestCompiler(t *testing.T) {
|
||||
for id, test := range []struct {
|
||||
ast *ast.Node
|
||||
result match.Matcher
|
||||
sep []rune
|
||||
}{
|
||||
{
|
||||
ast: ast.NewNode(ast.KindPattern, nil,
|
||||
ast.NewNode(ast.KindText, ast.Text{"abc"}),
|
||||
),
|
||||
result: match.NewText("abc"),
|
||||
},
|
||||
{
|
||||
ast: ast.NewNode(ast.KindPattern, nil,
|
||||
ast.NewNode(ast.KindAny, nil),
|
||||
),
|
||||
sep: separators,
|
||||
result: match.NewAny(separators),
|
||||
},
|
||||
{
|
||||
ast: ast.NewNode(ast.KindPattern, nil,
|
||||
ast.NewNode(ast.KindAny, nil),
|
||||
),
|
||||
result: match.NewSuper(),
|
||||
},
|
||||
{
|
||||
ast: ast.NewNode(ast.KindPattern, nil,
|
||||
ast.NewNode(ast.KindSuper, nil),
|
||||
),
|
||||
result: match.NewSuper(),
|
||||
},
|
||||
{
|
||||
ast: ast.NewNode(ast.KindPattern, nil,
|
||||
ast.NewNode(ast.KindSingle, nil),
|
||||
),
|
||||
sep: separators,
|
||||
result: match.NewSingle(separators),
|
||||
},
|
||||
{
|
||||
ast: ast.NewNode(ast.KindPattern, nil,
|
||||
ast.NewNode(ast.KindRange, ast.Range{
|
||||
Lo: 'a',
|
||||
Hi: 'z',
|
||||
Not: true,
|
||||
}),
|
||||
),
|
||||
result: match.NewRange('a', 'z', true),
|
||||
},
|
||||
{
|
||||
ast: ast.NewNode(ast.KindPattern, nil,
|
||||
ast.NewNode(ast.KindList, ast.List{
|
||||
Chars: "abc",
|
||||
Not: true,
|
||||
}),
|
||||
),
|
||||
result: match.NewList([]rune{'a', 'b', 'c'}, true),
|
||||
},
|
||||
{
|
||||
ast: ast.NewNode(ast.KindPattern, nil,
|
||||
ast.NewNode(ast.KindAny, nil),
|
||||
ast.NewNode(ast.KindSingle, nil),
|
||||
ast.NewNode(ast.KindSingle, nil),
|
||||
ast.NewNode(ast.KindSingle, nil),
|
||||
),
|
||||
sep: separators,
|
||||
result: match.EveryOf{Matchers: match.Matchers{
|
||||
match.NewMin(3),
|
||||
match.NewContains(string(separators), true),
|
||||
}},
|
||||
},
|
||||
{
|
||||
ast: ast.NewNode(ast.KindPattern, nil,
|
||||
ast.NewNode(ast.KindAny, nil),
|
||||
ast.NewNode(ast.KindSingle, nil),
|
||||
ast.NewNode(ast.KindSingle, nil),
|
||||
ast.NewNode(ast.KindSingle, nil),
|
||||
),
|
||||
result: match.NewMin(3),
|
||||
},
|
||||
{
|
||||
ast: ast.NewNode(ast.KindPattern, nil,
|
||||
ast.NewNode(ast.KindAny, nil),
|
||||
ast.NewNode(ast.KindText, ast.Text{"abc"}),
|
||||
ast.NewNode(ast.KindSingle, nil),
|
||||
),
|
||||
sep: separators,
|
||||
result: match.NewBTree(
|
||||
match.NewRow(
|
||||
4,
|
||||
match.Matchers{
|
||||
match.NewText("abc"),
|
||||
match.NewSingle(separators),
|
||||
}...,
|
||||
),
|
||||
match.NewAny(separators),
|
||||
nil,
|
||||
),
|
||||
},
|
||||
{
|
||||
ast: ast.NewNode(ast.KindPattern, nil,
|
||||
ast.NewNode(ast.KindText, ast.Text{"/"}),
|
||||
ast.NewNode(ast.KindAnyOf, nil,
|
||||
ast.NewNode(ast.KindText, ast.Text{"z"}),
|
||||
ast.NewNode(ast.KindText, ast.Text{"ab"}),
|
||||
),
|
||||
ast.NewNode(ast.KindSuper, nil),
|
||||
),
|
||||
sep: separators,
|
||||
result: match.NewBTree(
|
||||
match.NewText("/"),
|
||||
nil,
|
||||
match.NewBTree(
|
||||
match.NewAnyOf(match.NewText("z"), match.NewText("ab")),
|
||||
nil,
|
||||
match.NewSuper(),
|
||||
),
|
||||
),
|
||||
},
|
||||
{
|
||||
ast: ast.NewNode(ast.KindPattern, nil,
|
||||
ast.NewNode(ast.KindSuper, nil),
|
||||
ast.NewNode(ast.KindSingle, nil),
|
||||
ast.NewNode(ast.KindText, ast.Text{"abc"}),
|
||||
ast.NewNode(ast.KindSingle, nil),
|
||||
),
|
||||
sep: separators,
|
||||
result: match.NewBTree(
|
||||
match.NewRow(
|
||||
5,
|
||||
match.Matchers{
|
||||
match.NewSingle(separators),
|
||||
match.NewText("abc"),
|
||||
match.NewSingle(separators),
|
||||
}...,
|
||||
),
|
||||
match.NewSuper(),
|
||||
nil,
|
||||
),
|
||||
},
|
||||
{
|
||||
ast: ast.NewNode(ast.KindPattern, nil,
|
||||
ast.NewNode(ast.KindAny, nil),
|
||||
ast.NewNode(ast.KindText, ast.Text{"abc"}),
|
||||
),
|
||||
result: match.NewSuffix("abc"),
|
||||
},
|
||||
{
|
||||
ast: ast.NewNode(ast.KindPattern, nil,
|
||||
ast.NewNode(ast.KindText, ast.Text{"abc"}),
|
||||
ast.NewNode(ast.KindAny, nil),
|
||||
),
|
||||
result: match.NewPrefix("abc"),
|
||||
},
|
||||
{
|
||||
ast: ast.NewNode(ast.KindPattern, nil,
|
||||
ast.NewNode(ast.KindText, ast.Text{"abc"}),
|
||||
ast.NewNode(ast.KindAny, nil),
|
||||
ast.NewNode(ast.KindText, ast.Text{"def"}),
|
||||
),
|
||||
result: match.NewPrefixSuffix("abc", "def"),
|
||||
},
|
||||
{
|
||||
ast: ast.NewNode(ast.KindPattern, nil,
|
||||
ast.NewNode(ast.KindAny, nil),
|
||||
ast.NewNode(ast.KindAny, nil),
|
||||
ast.NewNode(ast.KindAny, nil),
|
||||
ast.NewNode(ast.KindText, ast.Text{"abc"}),
|
||||
ast.NewNode(ast.KindAny, nil),
|
||||
ast.NewNode(ast.KindAny, nil),
|
||||
),
|
||||
result: match.NewContains("abc", false),
|
||||
},
|
||||
{
|
||||
ast: ast.NewNode(ast.KindPattern, nil,
|
||||
ast.NewNode(ast.KindAny, nil),
|
||||
ast.NewNode(ast.KindAny, nil),
|
||||
ast.NewNode(ast.KindAny, nil),
|
||||
ast.NewNode(ast.KindText, ast.Text{"abc"}),
|
||||
ast.NewNode(ast.KindAny, nil),
|
||||
ast.NewNode(ast.KindAny, nil),
|
||||
),
|
||||
sep: separators,
|
||||
result: match.NewBTree(
|
||||
match.NewText("abc"),
|
||||
match.NewAny(separators),
|
||||
match.NewAny(separators),
|
||||
),
|
||||
},
|
||||
{
|
||||
ast: ast.NewNode(ast.KindPattern, nil,
|
||||
ast.NewNode(ast.KindSuper, nil),
|
||||
ast.NewNode(ast.KindSingle, nil),
|
||||
ast.NewNode(ast.KindText, ast.Text{"abc"}),
|
||||
ast.NewNode(ast.KindSuper, nil),
|
||||
ast.NewNode(ast.KindSingle, nil),
|
||||
),
|
||||
result: match.NewBTree(
|
||||
match.NewText("abc"),
|
||||
match.NewMin(1),
|
||||
match.NewMin(1),
|
||||
),
|
||||
},
|
||||
{
|
||||
ast: ast.NewNode(ast.KindPattern, nil,
|
||||
ast.NewNode(ast.KindText, ast.Text{"abc"}),
|
||||
),
|
||||
result: match.NewText("abc"),
|
||||
},
|
||||
{
|
||||
ast: ast.NewNode(ast.KindPattern, nil,
|
||||
ast.NewNode(ast.KindAnyOf, nil,
|
||||
ast.NewNode(ast.KindPattern, nil,
|
||||
ast.NewNode(ast.KindAnyOf, nil,
|
||||
ast.NewNode(ast.KindPattern, nil,
|
||||
ast.NewNode(ast.KindText, ast.Text{"abc"}),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
result: match.NewText("abc"),
|
||||
},
|
||||
{
|
||||
ast: ast.NewNode(ast.KindPattern, nil,
|
||||
ast.NewNode(ast.KindAnyOf, nil,
|
||||
ast.NewNode(ast.KindPattern, nil,
|
||||
ast.NewNode(ast.KindText, ast.Text{"abc"}),
|
||||
ast.NewNode(ast.KindSingle, nil),
|
||||
),
|
||||
ast.NewNode(ast.KindPattern, nil,
|
||||
ast.NewNode(ast.KindText, ast.Text{"abc"}),
|
||||
ast.NewNode(ast.KindList, ast.List{Chars: "def"}),
|
||||
),
|
||||
ast.NewNode(ast.KindPattern, nil,
|
||||
ast.NewNode(ast.KindText, ast.Text{"abc"}),
|
||||
),
|
||||
ast.NewNode(ast.KindPattern, nil,
|
||||
ast.NewNode(ast.KindText, ast.Text{"abc"}),
|
||||
),
|
||||
),
|
||||
),
|
||||
result: match.NewBTree(
|
||||
match.NewText("abc"),
|
||||
nil,
|
||||
match.AnyOf{Matchers: match.Matchers{
|
||||
match.NewSingle(nil),
|
||||
match.NewList([]rune{'d', 'e', 'f'}, false),
|
||||
match.NewNothing(),
|
||||
}},
|
||||
),
|
||||
},
|
||||
{
|
||||
ast: ast.NewNode(ast.KindPattern, nil,
|
||||
ast.NewNode(ast.KindRange, ast.Range{Lo: 'a', Hi: 'z'}),
|
||||
ast.NewNode(ast.KindRange, ast.Range{Lo: 'a', Hi: 'x', Not: true}),
|
||||
ast.NewNode(ast.KindAny, nil),
|
||||
),
|
||||
result: match.NewBTree(
|
||||
match.NewRow(
|
||||
2,
|
||||
match.Matchers{
|
||||
match.NewRange('a', 'z', false),
|
||||
match.NewRange('a', 'x', true),
|
||||
}...,
|
||||
),
|
||||
nil,
|
||||
match.NewSuper(),
|
||||
),
|
||||
},
|
||||
{
|
||||
ast: ast.NewNode(ast.KindPattern, nil,
|
||||
ast.NewNode(ast.KindAnyOf, nil,
|
||||
ast.NewNode(ast.KindPattern, nil,
|
||||
ast.NewNode(ast.KindText, ast.Text{"abc"}),
|
||||
ast.NewNode(ast.KindList, ast.List{Chars: "abc"}),
|
||||
ast.NewNode(ast.KindText, ast.Text{"ghi"}),
|
||||
),
|
||||
ast.NewNode(ast.KindPattern, nil,
|
||||
ast.NewNode(ast.KindText, ast.Text{"abc"}),
|
||||
ast.NewNode(ast.KindList, ast.List{Chars: "def"}),
|
||||
ast.NewNode(ast.KindText, ast.Text{"ghi"}),
|
||||
),
|
||||
),
|
||||
),
|
||||
result: match.NewRow(
|
||||
7,
|
||||
match.Matchers{
|
||||
match.NewText("abc"),
|
||||
match.AnyOf{Matchers: match.Matchers{
|
||||
match.NewList([]rune{'a', 'b', 'c'}, false),
|
||||
match.NewList([]rune{'d', 'e', 'f'}, false),
|
||||
}},
|
||||
match.NewText("ghi"),
|
||||
}...,
|
||||
),
|
||||
},
|
||||
} {
|
||||
m, err := Compile(test.ast, test.sep)
|
||||
if err != nil {
|
||||
t.Errorf("compilation error: %s", err)
|
||||
continue
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(m, test.result) {
|
||||
t.Errorf("[%d] Compile():\nexp: %#v\nact: %#v\n\ngraphviz:\nexp:\n%s\nact:\n%s\n", id, test.result, m, debug.Graphviz("", test.result.(match.Matcher)), debug.Graphviz("", m.(match.Matcher)))
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
531
vendor/github.com/gobwas/glob/glob_test.go
generated
vendored
531
vendor/github.com/gobwas/glob/glob_test.go
generated
vendored
|
@ -1,531 +0,0 @@
|
|||
package glob
|
||||
|
||||
import (
|
||||
"regexp"
|
||||
"testing"
|
||||
)
|
||||
|
||||
const (
|
||||
pattern_all = "[a-z][!a-x]*cat*[h][!b]*eyes*"
|
||||
regexp_all = `^[a-z][^a-x].*cat.*[h][^b].*eyes.*$`
|
||||
fixture_all_match = "my cat has very bright eyes"
|
||||
fixture_all_mismatch = "my dog has very bright eyes"
|
||||
|
||||
pattern_plain = "google.com"
|
||||
regexp_plain = `^google\.com$`
|
||||
fixture_plain_match = "google.com"
|
||||
fixture_plain_mismatch = "gobwas.com"
|
||||
|
||||
pattern_multiple = "https://*.google.*"
|
||||
regexp_multiple = `^https:\/\/.*\.google\..*$`
|
||||
fixture_multiple_match = "https://account.google.com"
|
||||
fixture_multiple_mismatch = "https://google.com"
|
||||
|
||||
pattern_alternatives = "{https://*.google.*,*yandex.*,*yahoo.*,*mail.ru}"
|
||||
regexp_alternatives = `^(https:\/\/.*\.google\..*|.*yandex\..*|.*yahoo\..*|.*mail\.ru)$`
|
||||
fixture_alternatives_match = "http://yahoo.com"
|
||||
fixture_alternatives_mismatch = "http://google.com"
|
||||
|
||||
pattern_alternatives_suffix = "{https://*gobwas.com,http://exclude.gobwas.com}"
|
||||
regexp_alternatives_suffix = `^(https:\/\/.*gobwas\.com|http://exclude.gobwas.com)$`
|
||||
fixture_alternatives_suffix_first_match = "https://safe.gobwas.com"
|
||||
fixture_alternatives_suffix_first_mismatch = "http://safe.gobwas.com"
|
||||
fixture_alternatives_suffix_second = "http://exclude.gobwas.com"
|
||||
|
||||
pattern_prefix = "abc*"
|
||||
regexp_prefix = `^abc.*$`
|
||||
pattern_suffix = "*def"
|
||||
regexp_suffix = `^.*def$`
|
||||
pattern_prefix_suffix = "ab*ef"
|
||||
regexp_prefix_suffix = `^ab.*ef$`
|
||||
fixture_prefix_suffix_match = "abcdef"
|
||||
fixture_prefix_suffix_mismatch = "af"
|
||||
|
||||
pattern_alternatives_combine_lite = "{abc*def,abc?def,abc[zte]def}"
|
||||
regexp_alternatives_combine_lite = `^(abc.*def|abc.def|abc[zte]def)$`
|
||||
fixture_alternatives_combine_lite = "abczdef"
|
||||
|
||||
pattern_alternatives_combine_hard = "{abc*[a-c]def,abc?[d-g]def,abc[zte]?def}"
|
||||
regexp_alternatives_combine_hard = `^(abc.*[a-c]def|abc.[d-g]def|abc[zte].def)$`
|
||||
fixture_alternatives_combine_hard = "abczqdef"
|
||||
)
|
||||
|
||||
type test struct {
|
||||
pattern, match string
|
||||
should bool
|
||||
delimiters []rune
|
||||
}
|
||||
|
||||
func glob(s bool, p, m string, d ...rune) test {
|
||||
return test{p, m, s, d}
|
||||
}
|
||||
|
||||
func TestGlob(t *testing.T) {
|
||||
for _, test := range []test{
|
||||
glob(true, "* ?at * eyes", "my cat has very bright eyes"),
|
||||
|
||||
glob(true, "", ""),
|
||||
glob(false, "", "b"),
|
||||
|
||||
glob(true, "*ä", "åä"),
|
||||
glob(true, "abc", "abc"),
|
||||
glob(true, "a*c", "abc"),
|
||||
glob(true, "a*c", "a12345c"),
|
||||
glob(true, "a?c", "a1c"),
|
||||
glob(true, "a.b", "a.b", '.'),
|
||||
glob(true, "a.*", "a.b", '.'),
|
||||
glob(true, "a.**", "a.b.c", '.'),
|
||||
glob(true, "a.?.c", "a.b.c", '.'),
|
||||
glob(true, "a.?.?", "a.b.c", '.'),
|
||||
glob(true, "?at", "cat"),
|
||||
glob(true, "?at", "fat"),
|
||||
glob(true, "*", "abc"),
|
||||
glob(true, `\*`, "*"),
|
||||
glob(true, "**", "a.b.c", '.'),
|
||||
|
||||
glob(false, "?at", "at"),
|
||||
glob(false, "?at", "fat", 'f'),
|
||||
glob(false, "a.*", "a.b.c", '.'),
|
||||
glob(false, "a.?.c", "a.bb.c", '.'),
|
||||
glob(false, "*", "a.b.c", '.'),
|
||||
|
||||
glob(true, "*test", "this is a test"),
|
||||
glob(true, "this*", "this is a test"),
|
||||
glob(true, "*is *", "this is a test"),
|
||||
glob(true, "*is*a*", "this is a test"),
|
||||
glob(true, "**test**", "this is a test"),
|
||||
glob(true, "**is**a***test*", "this is a test"),
|
||||
|
||||
glob(false, "*is", "this is a test"),
|
||||
glob(false, "*no*", "this is a test"),
|
||||
glob(true, "[!a]*", "this is a test3"),
|
||||
|
||||
glob(true, "*abc", "abcabc"),
|
||||
glob(true, "**abc", "abcabc"),
|
||||
glob(true, "???", "abc"),
|
||||
glob(true, "?*?", "abc"),
|
||||
glob(true, "?*?", "ac"),
|
||||
glob(false, "sta", "stagnation"),
|
||||
glob(true, "sta*", "stagnation"),
|
||||
glob(false, "sta?", "stagnation"),
|
||||
glob(false, "sta?n", "stagnation"),
|
||||
|
||||
glob(true, "{abc,def}ghi", "defghi"),
|
||||
glob(true, "{abc,abcd}a", "abcda"),
|
||||
glob(true, "{a,ab}{bc,f}", "abc"),
|
||||
glob(true, "{*,**}{a,b}", "ab"),
|
||||
glob(false, "{*,**}{a,b}", "ac"),
|
||||
|
||||
glob(true, "/{rate,[a-z][a-z][a-z]}*", "/rate"),
|
||||
glob(true, "/{rate,[0-9][0-9][0-9]}*", "/rate"),
|
||||
glob(true, "/{rate,[a-z][a-z][a-z]}*", "/usd"),
|
||||
|
||||
glob(true, "{*.google.*,*.yandex.*}", "www.google.com", '.'),
|
||||
glob(true, "{*.google.*,*.yandex.*}", "www.yandex.com", '.'),
|
||||
glob(false, "{*.google.*,*.yandex.*}", "yandex.com", '.'),
|
||||
glob(false, "{*.google.*,*.yandex.*}", "google.com", '.'),
|
||||
|
||||
glob(true, "{*.google.*,yandex.*}", "www.google.com", '.'),
|
||||
glob(true, "{*.google.*,yandex.*}", "yandex.com", '.'),
|
||||
glob(false, "{*.google.*,yandex.*}", "www.yandex.com", '.'),
|
||||
glob(false, "{*.google.*,yandex.*}", "google.com", '.'),
|
||||
|
||||
glob(true, "*//{,*.}example.com", "https://www.example.com"),
|
||||
glob(true, "*//{,*.}example.com", "http://example.com"),
|
||||
glob(false, "*//{,*.}example.com", "http://example.com.net"),
|
||||
|
||||
glob(true, pattern_all, fixture_all_match),
|
||||
glob(false, pattern_all, fixture_all_mismatch),
|
||||
|
||||
glob(true, pattern_plain, fixture_plain_match),
|
||||
glob(false, pattern_plain, fixture_plain_mismatch),
|
||||
|
||||
glob(true, pattern_multiple, fixture_multiple_match),
|
||||
glob(false, pattern_multiple, fixture_multiple_mismatch),
|
||||
|
||||
glob(true, pattern_alternatives, fixture_alternatives_match),
|
||||
glob(false, pattern_alternatives, fixture_alternatives_mismatch),
|
||||
|
||||
glob(true, pattern_alternatives_suffix, fixture_alternatives_suffix_first_match),
|
||||
glob(false, pattern_alternatives_suffix, fixture_alternatives_suffix_first_mismatch),
|
||||
glob(true, pattern_alternatives_suffix, fixture_alternatives_suffix_second),
|
||||
|
||||
glob(true, pattern_alternatives_combine_hard, fixture_alternatives_combine_hard),
|
||||
|
||||
glob(true, pattern_alternatives_combine_lite, fixture_alternatives_combine_lite),
|
||||
|
||||
glob(true, pattern_prefix, fixture_prefix_suffix_match),
|
||||
glob(false, pattern_prefix, fixture_prefix_suffix_mismatch),
|
||||
|
||||
glob(true, pattern_suffix, fixture_prefix_suffix_match),
|
||||
glob(false, pattern_suffix, fixture_prefix_suffix_mismatch),
|
||||
|
||||
glob(true, pattern_prefix_suffix, fixture_prefix_suffix_match),
|
||||
glob(false, pattern_prefix_suffix, fixture_prefix_suffix_mismatch),
|
||||
} {
|
||||
t.Run("", func(t *testing.T) {
|
||||
g := MustCompile(test.pattern, test.delimiters...)
|
||||
result := g.Match(test.match)
|
||||
if result != test.should {
|
||||
t.Errorf(
|
||||
"pattern %q matching %q should be %v but got %v\n%s",
|
||||
test.pattern, test.match, test.should, result, g,
|
||||
)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestQuoteMeta(t *testing.T) {
|
||||
for id, test := range []struct {
|
||||
in, out string
|
||||
}{
|
||||
{
|
||||
in: `[foo*]`,
|
||||
out: `\[foo\*\]`,
|
||||
},
|
||||
{
|
||||
in: `{foo*}`,
|
||||
out: `\{foo\*\}`,
|
||||
},
|
||||
{
|
||||
in: `*?\[]{}`,
|
||||
out: `\*\?\\\[\]\{\}`,
|
||||
},
|
||||
{
|
||||
in: `some text and *?\[]{}`,
|
||||
out: `some text and \*\?\\\[\]\{\}`,
|
||||
},
|
||||
} {
|
||||
act := QuoteMeta(test.in)
|
||||
if act != test.out {
|
||||
t.Errorf("#%d QuoteMeta(%q) = %q; want %q", id, test.in, act, test.out)
|
||||
}
|
||||
if _, err := Compile(act); err != nil {
|
||||
t.Errorf("#%d _, err := Compile(QuoteMeta(%q) = %q); err = %q", id, test.in, act, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkParseGlob(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
Compile(pattern_all)
|
||||
}
|
||||
}
|
||||
func BenchmarkParseRegexp(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
regexp.MustCompile(regexp_all)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkAllGlobMatch(b *testing.B) {
|
||||
m, _ := Compile(pattern_all)
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
_ = m.Match(fixture_all_match)
|
||||
}
|
||||
}
|
||||
func BenchmarkAllGlobMatchParallel(b *testing.B) {
|
||||
m, _ := Compile(pattern_all)
|
||||
|
||||
b.RunParallel(func(pb *testing.PB) {
|
||||
for pb.Next() {
|
||||
_ = m.Match(fixture_all_match)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func BenchmarkAllRegexpMatch(b *testing.B) {
|
||||
m := regexp.MustCompile(regexp_all)
|
||||
f := []byte(fixture_all_match)
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
_ = m.Match(f)
|
||||
}
|
||||
}
|
||||
func BenchmarkAllGlobMismatch(b *testing.B) {
|
||||
m, _ := Compile(pattern_all)
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
_ = m.Match(fixture_all_mismatch)
|
||||
}
|
||||
}
|
||||
func BenchmarkAllGlobMismatchParallel(b *testing.B) {
|
||||
m, _ := Compile(pattern_all)
|
||||
|
||||
b.RunParallel(func(pb *testing.PB) {
|
||||
for pb.Next() {
|
||||
_ = m.Match(fixture_all_mismatch)
|
||||
}
|
||||
})
|
||||
}
|
||||
func BenchmarkAllRegexpMismatch(b *testing.B) {
|
||||
m := regexp.MustCompile(regexp_all)
|
||||
f := []byte(fixture_all_mismatch)
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
_ = m.Match(f)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkMultipleGlobMatch(b *testing.B) {
|
||||
m, _ := Compile(pattern_multiple)
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
_ = m.Match(fixture_multiple_match)
|
||||
}
|
||||
}
|
||||
func BenchmarkMultipleRegexpMatch(b *testing.B) {
|
||||
m := regexp.MustCompile(regexp_multiple)
|
||||
f := []byte(fixture_multiple_match)
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
_ = m.Match(f)
|
||||
}
|
||||
}
|
||||
func BenchmarkMultipleGlobMismatch(b *testing.B) {
|
||||
m, _ := Compile(pattern_multiple)
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
_ = m.Match(fixture_multiple_mismatch)
|
||||
}
|
||||
}
|
||||
func BenchmarkMultipleRegexpMismatch(b *testing.B) {
|
||||
m := regexp.MustCompile(regexp_multiple)
|
||||
f := []byte(fixture_multiple_mismatch)
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
_ = m.Match(f)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkAlternativesGlobMatch(b *testing.B) {
|
||||
m, _ := Compile(pattern_alternatives)
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
_ = m.Match(fixture_alternatives_match)
|
||||
}
|
||||
}
|
||||
func BenchmarkAlternativesGlobMismatch(b *testing.B) {
|
||||
m, _ := Compile(pattern_alternatives)
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
_ = m.Match(fixture_alternatives_mismatch)
|
||||
}
|
||||
}
|
||||
func BenchmarkAlternativesRegexpMatch(b *testing.B) {
|
||||
m := regexp.MustCompile(regexp_alternatives)
|
||||
f := []byte(fixture_alternatives_match)
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
_ = m.Match(f)
|
||||
}
|
||||
}
|
||||
func BenchmarkAlternativesRegexpMismatch(b *testing.B) {
|
||||
m := regexp.MustCompile(regexp_alternatives)
|
||||
f := []byte(fixture_alternatives_mismatch)
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
_ = m.Match(f)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkAlternativesSuffixFirstGlobMatch(b *testing.B) {
|
||||
m, _ := Compile(pattern_alternatives_suffix)
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
_ = m.Match(fixture_alternatives_suffix_first_match)
|
||||
}
|
||||
}
|
||||
func BenchmarkAlternativesSuffixFirstGlobMismatch(b *testing.B) {
|
||||
m, _ := Compile(pattern_alternatives_suffix)
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
_ = m.Match(fixture_alternatives_suffix_first_mismatch)
|
||||
}
|
||||
}
|
||||
func BenchmarkAlternativesSuffixSecondGlobMatch(b *testing.B) {
|
||||
m, _ := Compile(pattern_alternatives_suffix)
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
_ = m.Match(fixture_alternatives_suffix_second)
|
||||
}
|
||||
}
|
||||
func BenchmarkAlternativesCombineLiteGlobMatch(b *testing.B) {
|
||||
m, _ := Compile(pattern_alternatives_combine_lite)
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
_ = m.Match(fixture_alternatives_combine_lite)
|
||||
}
|
||||
}
|
||||
func BenchmarkAlternativesCombineHardGlobMatch(b *testing.B) {
|
||||
m, _ := Compile(pattern_alternatives_combine_hard)
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
_ = m.Match(fixture_alternatives_combine_hard)
|
||||
}
|
||||
}
|
||||
func BenchmarkAlternativesSuffixFirstRegexpMatch(b *testing.B) {
|
||||
m := regexp.MustCompile(regexp_alternatives_suffix)
|
||||
f := []byte(fixture_alternatives_suffix_first_match)
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
_ = m.Match(f)
|
||||
}
|
||||
}
|
||||
func BenchmarkAlternativesSuffixFirstRegexpMismatch(b *testing.B) {
|
||||
m := regexp.MustCompile(regexp_alternatives_suffix)
|
||||
f := []byte(fixture_alternatives_suffix_first_mismatch)
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
_ = m.Match(f)
|
||||
}
|
||||
}
|
||||
func BenchmarkAlternativesSuffixSecondRegexpMatch(b *testing.B) {
|
||||
m := regexp.MustCompile(regexp_alternatives_suffix)
|
||||
f := []byte(fixture_alternatives_suffix_second)
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
_ = m.Match(f)
|
||||
}
|
||||
}
|
||||
func BenchmarkAlternativesCombineLiteRegexpMatch(b *testing.B) {
|
||||
m := regexp.MustCompile(regexp_alternatives_combine_lite)
|
||||
f := []byte(fixture_alternatives_combine_lite)
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
_ = m.Match(f)
|
||||
}
|
||||
}
|
||||
func BenchmarkAlternativesCombineHardRegexpMatch(b *testing.B) {
|
||||
m := regexp.MustCompile(regexp_alternatives_combine_hard)
|
||||
f := []byte(fixture_alternatives_combine_hard)
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
_ = m.Match(f)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkPlainGlobMatch(b *testing.B) {
|
||||
m, _ := Compile(pattern_plain)
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
_ = m.Match(fixture_plain_match)
|
||||
}
|
||||
}
|
||||
func BenchmarkPlainRegexpMatch(b *testing.B) {
|
||||
m := regexp.MustCompile(regexp_plain)
|
||||
f := []byte(fixture_plain_match)
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
_ = m.Match(f)
|
||||
}
|
||||
}
|
||||
func BenchmarkPlainGlobMismatch(b *testing.B) {
|
||||
m, _ := Compile(pattern_plain)
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
_ = m.Match(fixture_plain_mismatch)
|
||||
}
|
||||
}
|
||||
func BenchmarkPlainRegexpMismatch(b *testing.B) {
|
||||
m := regexp.MustCompile(regexp_plain)
|
||||
f := []byte(fixture_plain_mismatch)
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
_ = m.Match(f)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkPrefixGlobMatch(b *testing.B) {
|
||||
m, _ := Compile(pattern_prefix)
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
_ = m.Match(fixture_prefix_suffix_match)
|
||||
}
|
||||
}
|
||||
func BenchmarkPrefixRegexpMatch(b *testing.B) {
|
||||
m := regexp.MustCompile(regexp_prefix)
|
||||
f := []byte(fixture_prefix_suffix_match)
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
_ = m.Match(f)
|
||||
}
|
||||
}
|
||||
func BenchmarkPrefixGlobMismatch(b *testing.B) {
|
||||
m, _ := Compile(pattern_prefix)
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
_ = m.Match(fixture_prefix_suffix_mismatch)
|
||||
}
|
||||
}
|
||||
func BenchmarkPrefixRegexpMismatch(b *testing.B) {
|
||||
m := regexp.MustCompile(regexp_prefix)
|
||||
f := []byte(fixture_prefix_suffix_mismatch)
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
_ = m.Match(f)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkSuffixGlobMatch(b *testing.B) {
|
||||
m, _ := Compile(pattern_suffix)
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
_ = m.Match(fixture_prefix_suffix_match)
|
||||
}
|
||||
}
|
||||
func BenchmarkSuffixRegexpMatch(b *testing.B) {
|
||||
m := regexp.MustCompile(regexp_suffix)
|
||||
f := []byte(fixture_prefix_suffix_match)
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
_ = m.Match(f)
|
||||
}
|
||||
}
|
||||
func BenchmarkSuffixGlobMismatch(b *testing.B) {
|
||||
m, _ := Compile(pattern_suffix)
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
_ = m.Match(fixture_prefix_suffix_mismatch)
|
||||
}
|
||||
}
|
||||
func BenchmarkSuffixRegexpMismatch(b *testing.B) {
|
||||
m := regexp.MustCompile(regexp_suffix)
|
||||
f := []byte(fixture_prefix_suffix_mismatch)
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
_ = m.Match(f)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkPrefixSuffixGlobMatch(b *testing.B) {
|
||||
m, _ := Compile(pattern_prefix_suffix)
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
_ = m.Match(fixture_prefix_suffix_match)
|
||||
}
|
||||
}
|
||||
func BenchmarkPrefixSuffixRegexpMatch(b *testing.B) {
|
||||
m := regexp.MustCompile(regexp_prefix_suffix)
|
||||
f := []byte(fixture_prefix_suffix_match)
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
_ = m.Match(f)
|
||||
}
|
||||
}
|
||||
func BenchmarkPrefixSuffixGlobMismatch(b *testing.B) {
|
||||
m, _ := Compile(pattern_prefix_suffix)
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
_ = m.Match(fixture_prefix_suffix_mismatch)
|
||||
}
|
||||
}
|
||||
func BenchmarkPrefixSuffixRegexpMismatch(b *testing.B) {
|
||||
m := regexp.MustCompile(regexp_prefix_suffix)
|
||||
f := []byte(fixture_prefix_suffix_mismatch)
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
_ = m.Match(f)
|
||||
}
|
||||
}
|
53
vendor/github.com/gobwas/glob/match/any_of_test.go
generated
vendored
53
vendor/github.com/gobwas/glob/match/any_of_test.go
generated
vendored
|
@ -1,53 +0,0 @@
|
|||
package match
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestAnyOfIndex(t *testing.T) {
|
||||
for id, test := range []struct {
|
||||
matchers Matchers
|
||||
fixture string
|
||||
index int
|
||||
segments []int
|
||||
}{
|
||||
{
|
||||
Matchers{
|
||||
NewAny(nil),
|
||||
NewText("b"),
|
||||
NewText("c"),
|
||||
},
|
||||
"abc",
|
||||
0,
|
||||
[]int{0, 1, 2, 3},
|
||||
},
|
||||
{
|
||||
Matchers{
|
||||
NewPrefix("b"),
|
||||
NewSuffix("c"),
|
||||
},
|
||||
"abc",
|
||||
0,
|
||||
[]int{3},
|
||||
},
|
||||
{
|
||||
Matchers{
|
||||
NewList([]rune("[def]"), false),
|
||||
NewList([]rune("[abc]"), false),
|
||||
},
|
||||
"abcdef",
|
||||
0,
|
||||
[]int{1},
|
||||
},
|
||||
} {
|
||||
everyOf := NewAnyOf(test.matchers...)
|
||||
index, segments := everyOf.Index(test.fixture)
|
||||
if index != test.index {
|
||||
t.Errorf("#%d unexpected index: exp: %d, act: %d", id, test.index, index)
|
||||
}
|
||||
if !reflect.DeepEqual(segments, test.segments) {
|
||||
t.Errorf("#%d unexpected segments: exp: %v, act: %v", id, test.segments, segments)
|
||||
}
|
||||
}
|
||||
}
|
57
vendor/github.com/gobwas/glob/match/any_test.go
generated
vendored
57
vendor/github.com/gobwas/glob/match/any_test.go
generated
vendored
|
@ -1,57 +0,0 @@
|
|||
package match
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestAnyIndex(t *testing.T) {
|
||||
for id, test := range []struct {
|
||||
sep []rune
|
||||
fixture string
|
||||
index int
|
||||
segments []int
|
||||
}{
|
||||
{
|
||||
[]rune{'.'},
|
||||
"abc",
|
||||
0,
|
||||
[]int{0, 1, 2, 3},
|
||||
},
|
||||
{
|
||||
[]rune{'.'},
|
||||
"abc.def",
|
||||
0,
|
||||
[]int{0, 1, 2, 3},
|
||||
},
|
||||
} {
|
||||
p := NewAny(test.sep)
|
||||
index, segments := p.Index(test.fixture)
|
||||
if index != test.index {
|
||||
t.Errorf("#%d unexpected index: exp: %d, act: %d", id, test.index, index)
|
||||
}
|
||||
if !reflect.DeepEqual(segments, test.segments) {
|
||||
t.Errorf("#%d unexpected segments: exp: %v, act: %v", id, test.segments, segments)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkIndexAny(b *testing.B) {
|
||||
m := NewAny(bench_separators)
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
_, s := m.Index(bench_pattern)
|
||||
releaseSegments(s)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkIndexAnyParallel(b *testing.B) {
|
||||
m := NewAny(bench_separators)
|
||||
|
||||
b.RunParallel(func(pb *testing.PB) {
|
||||
for pb.Next() {
|
||||
_, s := m.Index(bench_pattern)
|
||||
releaseSegments(s)
|
||||
}
|
||||
})
|
||||
}
|
90
vendor/github.com/gobwas/glob/match/btree_test.go
generated
vendored
90
vendor/github.com/gobwas/glob/match/btree_test.go
generated
vendored
|
@ -1,90 +0,0 @@
|
|||
package match
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestBTree(t *testing.T) {
|
||||
for id, test := range []struct {
|
||||
tree BTree
|
||||
str string
|
||||
exp bool
|
||||
}{
|
||||
{
|
||||
NewBTree(NewText("abc"), NewSuper(), NewSuper()),
|
||||
"abc",
|
||||
true,
|
||||
},
|
||||
{
|
||||
NewBTree(NewText("a"), NewSingle(nil), NewSingle(nil)),
|
||||
"aaa",
|
||||
true,
|
||||
},
|
||||
{
|
||||
NewBTree(NewText("b"), NewSingle(nil), nil),
|
||||
"bbb",
|
||||
false,
|
||||
},
|
||||
{
|
||||
NewBTree(
|
||||
NewText("c"),
|
||||
NewBTree(
|
||||
NewSingle(nil),
|
||||
NewSuper(),
|
||||
nil,
|
||||
),
|
||||
nil,
|
||||
),
|
||||
"abc",
|
||||
true,
|
||||
},
|
||||
} {
|
||||
act := test.tree.Match(test.str)
|
||||
if act != test.exp {
|
||||
t.Errorf("#%d match %q error: act: %t; exp: %t", id, test.str, act, test.exp)
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type fakeMatcher struct {
|
||||
len int
|
||||
name string
|
||||
}
|
||||
|
||||
func (f *fakeMatcher) Match(string) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
var i = 3
|
||||
|
||||
func (f *fakeMatcher) Index(s string) (int, []int) {
|
||||
seg := make([]int, 0, i)
|
||||
for x := 0; x < i; x++ {
|
||||
seg = append(seg, x)
|
||||
}
|
||||
return 0, seg
|
||||
}
|
||||
func (f *fakeMatcher) Len() int {
|
||||
return f.len
|
||||
}
|
||||
func (f *fakeMatcher) String() string {
|
||||
return f.name
|
||||
}
|
||||
|
||||
func BenchmarkMatchBTree(b *testing.B) {
|
||||
l := &fakeMatcher{4, "left_fake"}
|
||||
r := &fakeMatcher{4, "right_fake"}
|
||||
v := &fakeMatcher{2, "value_fake"}
|
||||
|
||||
// must be <= len(l + r + v)
|
||||
fixture := "abcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghij"
|
||||
|
||||
bt := NewBTree(v, l, r)
|
||||
|
||||
b.RunParallel(func(pb *testing.PB) {
|
||||
for pb.Next() {
|
||||
bt.Match(fixture)
|
||||
}
|
||||
})
|
||||
}
|
74
vendor/github.com/gobwas/glob/match/contains_test.go
generated
vendored
74
vendor/github.com/gobwas/glob/match/contains_test.go
generated
vendored
|
@ -1,74 +0,0 @@
|
|||
package match
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestContainsIndex(t *testing.T) {
|
||||
for id, test := range []struct {
|
||||
prefix string
|
||||
not bool
|
||||
fixture string
|
||||
index int
|
||||
segments []int
|
||||
}{
|
||||
{
|
||||
"ab",
|
||||
false,
|
||||
"abc",
|
||||
0,
|
||||
[]int{2, 3},
|
||||
},
|
||||
{
|
||||
"ab",
|
||||
false,
|
||||
"fffabfff",
|
||||
0,
|
||||
[]int{5, 6, 7, 8},
|
||||
},
|
||||
{
|
||||
"ab",
|
||||
true,
|
||||
"abc",
|
||||
0,
|
||||
[]int{0},
|
||||
},
|
||||
{
|
||||
"ab",
|
||||
true,
|
||||
"fffabfff",
|
||||
0,
|
||||
[]int{0, 1, 2, 3},
|
||||
},
|
||||
} {
|
||||
p := NewContains(test.prefix, test.not)
|
||||
index, segments := p.Index(test.fixture)
|
||||
if index != test.index {
|
||||
t.Errorf("#%d unexpected index: exp: %d, act: %d", id, test.index, index)
|
||||
}
|
||||
if !reflect.DeepEqual(segments, test.segments) {
|
||||
t.Errorf("#%d unexpected segments: exp: %v, act: %v", id, test.segments, segments)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkIndexContains(b *testing.B) {
|
||||
m := NewContains(string(bench_separators), true)
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
_, s := m.Index(bench_pattern)
|
||||
releaseSegments(s)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkIndexContainsParallel(b *testing.B) {
|
||||
m := NewContains(string(bench_separators), true)
|
||||
|
||||
b.RunParallel(func(pb *testing.PB) {
|
||||
for pb.Next() {
|
||||
_, s := m.Index(bench_pattern)
|
||||
releaseSegments(s)
|
||||
}
|
||||
})
|
||||
}
|
55
vendor/github.com/gobwas/glob/match/debug/debug.go
generated
vendored
55
vendor/github.com/gobwas/glob/match/debug/debug.go
generated
vendored
|
@ -1,55 +0,0 @@
|
|||
package debug
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"github.com/gobwas/glob/match"
|
||||
"math/rand"
|
||||
)
|
||||
|
||||
func Graphviz(pattern string, m match.Matcher) string {
|
||||
return fmt.Sprintf(`digraph G {graph[label="%s"];%s}`, pattern, graphviz_internal(m, fmt.Sprintf("%x", rand.Int63())))
|
||||
}
|
||||
|
||||
func graphviz_internal(m match.Matcher, id string) string {
|
||||
buf := &bytes.Buffer{}
|
||||
|
||||
switch matcher := m.(type) {
|
||||
case match.BTree:
|
||||
fmt.Fprintf(buf, `"%s"[label="%s"];`, id, matcher.Value.String())
|
||||
for _, m := range []match.Matcher{matcher.Left, matcher.Right} {
|
||||
switch n := m.(type) {
|
||||
case nil:
|
||||
rnd := rand.Int63()
|
||||
fmt.Fprintf(buf, `"%x"[label="<nil>"];`, rnd)
|
||||
fmt.Fprintf(buf, `"%s"->"%x";`, id, rnd)
|
||||
|
||||
default:
|
||||
sub := fmt.Sprintf("%x", rand.Int63())
|
||||
fmt.Fprintf(buf, `"%s"->"%s";`, id, sub)
|
||||
fmt.Fprintf(buf, graphviz_internal(n, sub))
|
||||
}
|
||||
}
|
||||
|
||||
case match.AnyOf:
|
||||
fmt.Fprintf(buf, `"%s"[label="AnyOf"];`, id)
|
||||
for _, m := range matcher.Matchers {
|
||||
rnd := rand.Int63()
|
||||
fmt.Fprintf(buf, graphviz_internal(m, fmt.Sprintf("%x", rnd)))
|
||||
fmt.Fprintf(buf, `"%s"->"%x";`, id, rnd)
|
||||
}
|
||||
|
||||
case match.EveryOf:
|
||||
fmt.Fprintf(buf, `"%s"[label="EveryOf"];`, id)
|
||||
for _, m := range matcher.Matchers {
|
||||
rnd := rand.Int63()
|
||||
fmt.Fprintf(buf, graphviz_internal(m, fmt.Sprintf("%x", rnd)))
|
||||
fmt.Fprintf(buf, `"%s"->"%x";`, id, rnd)
|
||||
}
|
||||
|
||||
default:
|
||||
fmt.Fprintf(buf, `"%s"[label="%s"];`, id, m.String())
|
||||
}
|
||||
|
||||
return buf.String()
|
||||
}
|
45
vendor/github.com/gobwas/glob/match/every_of_test.go
generated
vendored
45
vendor/github.com/gobwas/glob/match/every_of_test.go
generated
vendored
|
@ -1,45 +0,0 @@
|
|||
package match
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestEveryOfIndex(t *testing.T) {
|
||||
for id, test := range []struct {
|
||||
matchers Matchers
|
||||
fixture string
|
||||
index int
|
||||
segments []int
|
||||
}{
|
||||
{
|
||||
Matchers{
|
||||
NewAny(nil),
|
||||
NewText("b"),
|
||||
NewText("c"),
|
||||
},
|
||||
"dbc",
|
||||
-1,
|
||||
nil,
|
||||
},
|
||||
{
|
||||
Matchers{
|
||||
NewAny(nil),
|
||||
NewPrefix("b"),
|
||||
NewSuffix("c"),
|
||||
},
|
||||
"abc",
|
||||
1,
|
||||
[]int{2},
|
||||
},
|
||||
} {
|
||||
everyOf := NewEveryOf(test.matchers...)
|
||||
index, segments := everyOf.Index(test.fixture)
|
||||
if index != test.index {
|
||||
t.Errorf("#%d unexpected index: exp: %d, act: %d", id, test.index, index)
|
||||
}
|
||||
if !reflect.DeepEqual(segments, test.segments) {
|
||||
t.Errorf("#%d unexpected segments: exp: %v, act: %v", id, test.segments, segments)
|
||||
}
|
||||
}
|
||||
}
|
58
vendor/github.com/gobwas/glob/match/list_test.go
generated
vendored
58
vendor/github.com/gobwas/glob/match/list_test.go
generated
vendored
|
@ -1,58 +0,0 @@
|
|||
package match
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestListIndex(t *testing.T) {
|
||||
for id, test := range []struct {
|
||||
list []rune
|
||||
not bool
|
||||
fixture string
|
||||
index int
|
||||
segments []int
|
||||
}{
|
||||
{
|
||||
[]rune("ab"),
|
||||
false,
|
||||
"abc",
|
||||
0,
|
||||
[]int{1},
|
||||
},
|
||||
{
|
||||
[]rune("ab"),
|
||||
true,
|
||||
"fffabfff",
|
||||
0,
|
||||
[]int{1},
|
||||
},
|
||||
} {
|
||||
p := NewList(test.list, test.not)
|
||||
index, segments := p.Index(test.fixture)
|
||||
if index != test.index {
|
||||
t.Errorf("#%d unexpected index: exp: %d, act: %d", id, test.index, index)
|
||||
}
|
||||
if !reflect.DeepEqual(segments, test.segments) {
|
||||
t.Errorf("#%d unexpected segments: exp: %v, act: %v", id, test.segments, segments)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkIndexList(b *testing.B) {
|
||||
m := NewList([]rune("def"), false)
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
m.Index(bench_pattern)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkIndexListParallel(b *testing.B) {
|
||||
m := NewList([]rune("def"), false)
|
||||
|
||||
b.RunParallel(func(pb *testing.PB) {
|
||||
for pb.Next() {
|
||||
m.Index(bench_pattern)
|
||||
}
|
||||
})
|
||||
}
|
90
vendor/github.com/gobwas/glob/match/match_test.go
generated
vendored
90
vendor/github.com/gobwas/glob/match/match_test.go
generated
vendored
|
@ -1,90 +0,0 @@
|
|||
package match
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
"unicode/utf8"
|
||||
)
|
||||
|
||||
var bench_separators = []rune{'.'}
|
||||
|
||||
const bench_pattern = "abcdefghijklmnopqrstuvwxyz0123456789"
|
||||
|
||||
func TestAppendMerge(t *testing.T) {
|
||||
for id, test := range []struct {
|
||||
segments [2][]int
|
||||
exp []int
|
||||
}{
|
||||
{
|
||||
[2][]int{
|
||||
{0, 6, 7},
|
||||
{0, 1, 3},
|
||||
},
|
||||
[]int{0, 1, 3, 6, 7},
|
||||
},
|
||||
{
|
||||
[2][]int{
|
||||
{0, 1, 3, 6, 7},
|
||||
{0, 1, 10},
|
||||
},
|
||||
[]int{0, 1, 3, 6, 7, 10},
|
||||
},
|
||||
} {
|
||||
act := appendMerge(test.segments[0], test.segments[1])
|
||||
if !reflect.DeepEqual(act, test.exp) {
|
||||
t.Errorf("#%d merge sort segments unexpected:\nact: %v\nexp:%v", id, act, test.exp)
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkAppendMerge(b *testing.B) {
|
||||
s1 := []int{0, 1, 3, 6, 7}
|
||||
s2 := []int{0, 1, 3}
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
appendMerge(s1, s2)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkAppendMergeParallel(b *testing.B) {
|
||||
s1 := []int{0, 1, 3, 6, 7}
|
||||
s2 := []int{0, 1, 3}
|
||||
|
||||
b.RunParallel(func(pb *testing.PB) {
|
||||
for pb.Next() {
|
||||
appendMerge(s1, s2)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func BenchmarkReverse(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
reverseSegments([]int{1, 2, 3, 4})
|
||||
}
|
||||
}
|
||||
|
||||
func getTable() []int {
|
||||
table := make([]int, utf8.MaxRune+1)
|
||||
for i := 0; i <= utf8.MaxRune; i++ {
|
||||
table[i] = utf8.RuneLen(rune(i))
|
||||
}
|
||||
|
||||
return table
|
||||
}
|
||||
|
||||
var table = getTable()
|
||||
|
||||
const runeToLen = 'q'
|
||||
|
||||
func BenchmarkRuneLenFromTable(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
_ = table[runeToLen]
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkRuneLenFromUTF8(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
_ = utf8.RuneLen(runeToLen)
|
||||
}
|
||||
}
|
57
vendor/github.com/gobwas/glob/match/max_test.go
generated
vendored
57
vendor/github.com/gobwas/glob/match/max_test.go
generated
vendored
|
@ -1,57 +0,0 @@
|
|||
package match
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestMaxIndex(t *testing.T) {
|
||||
for id, test := range []struct {
|
||||
limit int
|
||||
fixture string
|
||||
index int
|
||||
segments []int
|
||||
}{
|
||||
{
|
||||
3,
|
||||
"abc",
|
||||
0,
|
||||
[]int{0, 1, 2, 3},
|
||||
},
|
||||
{
|
||||
3,
|
||||
"abcdef",
|
||||
0,
|
||||
[]int{0, 1, 2, 3},
|
||||
},
|
||||
} {
|
||||
p := NewMax(test.limit)
|
||||
index, segments := p.Index(test.fixture)
|
||||
if index != test.index {
|
||||
t.Errorf("#%d unexpected index: exp: %d, act: %d", id, test.index, index)
|
||||
}
|
||||
if !reflect.DeepEqual(segments, test.segments) {
|
||||
t.Errorf("#%d unexpected segments: exp: %v, act: %v", id, test.segments, segments)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkIndexMax(b *testing.B) {
|
||||
m := NewMax(10)
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
_, s := m.Index(bench_pattern)
|
||||
releaseSegments(s)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkIndexMaxParallel(b *testing.B) {
|
||||
m := NewMax(10)
|
||||
|
||||
b.RunParallel(func(pb *testing.PB) {
|
||||
for pb.Next() {
|
||||
_, s := m.Index(bench_pattern)
|
||||
releaseSegments(s)
|
||||
}
|
||||
})
|
||||
}
|
57
vendor/github.com/gobwas/glob/match/min_test.go
generated
vendored
57
vendor/github.com/gobwas/glob/match/min_test.go
generated
vendored
|
@ -1,57 +0,0 @@
|
|||
package match
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestMinIndex(t *testing.T) {
|
||||
for id, test := range []struct {
|
||||
limit int
|
||||
fixture string
|
||||
index int
|
||||
segments []int
|
||||
}{
|
||||
{
|
||||
1,
|
||||
"abc",
|
||||
0,
|
||||
[]int{1, 2, 3},
|
||||
},
|
||||
{
|
||||
3,
|
||||
"abcd",
|
||||
0,
|
||||
[]int{3, 4},
|
||||
},
|
||||
} {
|
||||
p := NewMin(test.limit)
|
||||
index, segments := p.Index(test.fixture)
|
||||
if index != test.index {
|
||||
t.Errorf("#%d unexpected index: exp: %d, act: %d", id, test.index, index)
|
||||
}
|
||||
if !reflect.DeepEqual(segments, test.segments) {
|
||||
t.Errorf("#%d unexpected segments: exp: %v, act: %v", id, test.segments, segments)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkIndexMin(b *testing.B) {
|
||||
m := NewMin(10)
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
_, s := m.Index(bench_pattern)
|
||||
releaseSegments(s)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkIndexMinParallel(b *testing.B) {
|
||||
m := NewMin(10)
|
||||
|
||||
b.RunParallel(func(pb *testing.PB) {
|
||||
for pb.Next() {
|
||||
_, s := m.Index(bench_pattern)
|
||||
releaseSegments(s)
|
||||
}
|
||||
})
|
||||
}
|
54
vendor/github.com/gobwas/glob/match/nothing_test.go
generated
vendored
54
vendor/github.com/gobwas/glob/match/nothing_test.go
generated
vendored
|
@ -1,54 +0,0 @@
|
|||
package match
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestNothingIndex(t *testing.T) {
|
||||
for id, test := range []struct {
|
||||
fixture string
|
||||
index int
|
||||
segments []int
|
||||
}{
|
||||
{
|
||||
"abc",
|
||||
0,
|
||||
[]int{0},
|
||||
},
|
||||
{
|
||||
"",
|
||||
0,
|
||||
[]int{0},
|
||||
},
|
||||
} {
|
||||
p := NewNothing()
|
||||
index, segments := p.Index(test.fixture)
|
||||
if index != test.index {
|
||||
t.Errorf("#%d unexpected index: exp: %d, act: %d", id, test.index, index)
|
||||
}
|
||||
if !reflect.DeepEqual(segments, test.segments) {
|
||||
t.Errorf("#%d unexpected segments: exp: %v, act: %v", id, test.segments, segments)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkIndexNothing(b *testing.B) {
|
||||
m := NewNothing()
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
_, s := m.Index(bench_pattern)
|
||||
releaseSegments(s)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkIndexNothingParallel(b *testing.B) {
|
||||
m := NewNothing()
|
||||
|
||||
b.RunParallel(func(pb *testing.PB) {
|
||||
for pb.Next() {
|
||||
_, s := m.Index(bench_pattern)
|
||||
releaseSegments(s)
|
||||
}
|
||||
})
|
||||
}
|
47
vendor/github.com/gobwas/glob/match/prefix_any_test.go
generated
vendored
47
vendor/github.com/gobwas/glob/match/prefix_any_test.go
generated
vendored
|
@ -1,47 +0,0 @@
|
|||
package match
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestPrefixAnyIndex(t *testing.T) {
|
||||
for id, test := range []struct {
|
||||
prefix string
|
||||
separators []rune
|
||||
fixture string
|
||||
index int
|
||||
segments []int
|
||||
}{
|
||||
{
|
||||
"ab",
|
||||
[]rune{'.'},
|
||||
"ab",
|
||||
0,
|
||||
[]int{2},
|
||||
},
|
||||
{
|
||||
"ab",
|
||||
[]rune{'.'},
|
||||
"abc",
|
||||
0,
|
||||
[]int{2, 3},
|
||||
},
|
||||
{
|
||||
"ab",
|
||||
[]rune{'.'},
|
||||
"qw.abcd.efg",
|
||||
3,
|
||||
[]int{2, 3, 4},
|
||||
},
|
||||
} {
|
||||
p := NewPrefixAny(test.prefix, test.separators)
|
||||
index, segments := p.Index(test.fixture)
|
||||
if index != test.index {
|
||||
t.Errorf("#%d unexpected index: exp: %d, act: %d", id, test.index, index)
|
||||
}
|
||||
if !reflect.DeepEqual(segments, test.segments) {
|
||||
t.Errorf("#%d unexpected segments: exp: %v, act: %v", id, test.segments, segments)
|
||||
}
|
||||
}
|
||||
}
|
67
vendor/github.com/gobwas/glob/match/prefix_suffix_test.go
generated
vendored
67
vendor/github.com/gobwas/glob/match/prefix_suffix_test.go
generated
vendored
|
@ -1,67 +0,0 @@
|
|||
package match
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestPrefixSuffixIndex(t *testing.T) {
|
||||
for id, test := range []struct {
|
||||
prefix string
|
||||
suffix string
|
||||
fixture string
|
||||
index int
|
||||
segments []int
|
||||
}{
|
||||
{
|
||||
"a",
|
||||
"c",
|
||||
"abc",
|
||||
0,
|
||||
[]int{3},
|
||||
},
|
||||
{
|
||||
"f",
|
||||
"f",
|
||||
"fffabfff",
|
||||
0,
|
||||
[]int{1, 2, 3, 6, 7, 8},
|
||||
},
|
||||
{
|
||||
"ab",
|
||||
"bc",
|
||||
"abc",
|
||||
0,
|
||||
[]int{3},
|
||||
},
|
||||
} {
|
||||
p := NewPrefixSuffix(test.prefix, test.suffix)
|
||||
index, segments := p.Index(test.fixture)
|
||||
if index != test.index {
|
||||
t.Errorf("#%d unexpected index: exp: %d, act: %d", id, test.index, index)
|
||||
}
|
||||
if !reflect.DeepEqual(segments, test.segments) {
|
||||
t.Errorf("#%d unexpected segments: exp: %v, act: %v", id, test.segments, segments)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkIndexPrefixSuffix(b *testing.B) {
|
||||
m := NewPrefixSuffix("qew", "sqw")
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
_, s := m.Index(bench_pattern)
|
||||
releaseSegments(s)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkIndexPrefixSuffixParallel(b *testing.B) {
|
||||
m := NewPrefixSuffix("qew", "sqw")
|
||||
|
||||
b.RunParallel(func(pb *testing.PB) {
|
||||
for pb.Next() {
|
||||
_, s := m.Index(bench_pattern)
|
||||
releaseSegments(s)
|
||||
}
|
||||
})
|
||||
}
|
57
vendor/github.com/gobwas/glob/match/prefix_test.go
generated
vendored
57
vendor/github.com/gobwas/glob/match/prefix_test.go
generated
vendored
|
@ -1,57 +0,0 @@
|
|||
package match
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestPrefixIndex(t *testing.T) {
|
||||
for id, test := range []struct {
|
||||
prefix string
|
||||
fixture string
|
||||
index int
|
||||
segments []int
|
||||
}{
|
||||
{
|
||||
"ab",
|
||||
"abc",
|
||||
0,
|
||||
[]int{2, 3},
|
||||
},
|
||||
{
|
||||
"ab",
|
||||
"fffabfff",
|
||||
3,
|
||||
[]int{2, 3, 4, 5},
|
||||
},
|
||||
} {
|
||||
p := NewPrefix(test.prefix)
|
||||
index, segments := p.Index(test.fixture)
|
||||
if index != test.index {
|
||||
t.Errorf("#%d unexpected index: exp: %d, act: %d", id, test.index, index)
|
||||
}
|
||||
if !reflect.DeepEqual(segments, test.segments) {
|
||||
t.Errorf("#%d unexpected segments: exp: %v, act: %v", id, test.segments, segments)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkIndexPrefix(b *testing.B) {
|
||||
m := NewPrefix("qew")
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
_, s := m.Index(bench_pattern)
|
||||
releaseSegments(s)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkIndexPrefixParallel(b *testing.B) {
|
||||
m := NewPrefix("qew")
|
||||
|
||||
b.RunParallel(func(pb *testing.PB) {
|
||||
for pb.Next() {
|
||||
_, s := m.Index(bench_pattern)
|
||||
releaseSegments(s)
|
||||
}
|
||||
})
|
||||
}
|
67
vendor/github.com/gobwas/glob/match/range_test.go
generated
vendored
67
vendor/github.com/gobwas/glob/match/range_test.go
generated
vendored
|
@ -1,67 +0,0 @@
|
|||
package match
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestRangeIndex(t *testing.T) {
|
||||
for id, test := range []struct {
|
||||
lo, hi rune
|
||||
not bool
|
||||
fixture string
|
||||
index int
|
||||
segments []int
|
||||
}{
|
||||
{
|
||||
'a', 'z',
|
||||
false,
|
||||
"abc",
|
||||
0,
|
||||
[]int{1},
|
||||
},
|
||||
{
|
||||
'a', 'c',
|
||||
false,
|
||||
"abcd",
|
||||
0,
|
||||
[]int{1},
|
||||
},
|
||||
{
|
||||
'a', 'c',
|
||||
true,
|
||||
"abcd",
|
||||
3,
|
||||
[]int{1},
|
||||
},
|
||||
} {
|
||||
m := NewRange(test.lo, test.hi, test.not)
|
||||
index, segments := m.Index(test.fixture)
|
||||
if index != test.index {
|
||||
t.Errorf("#%d unexpected index: exp: %d, act: %d", id, test.index, index)
|
||||
}
|
||||
if !reflect.DeepEqual(segments, test.segments) {
|
||||
t.Errorf("#%d unexpected segments: exp: %v, act: %v", id, test.segments, segments)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkIndexRange(b *testing.B) {
|
||||
m := NewRange('0', '9', false)
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
_, s := m.Index(bench_pattern)
|
||||
releaseSegments(s)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkIndexRangeParallel(b *testing.B) {
|
||||
m := NewRange('0', '9', false)
|
||||
|
||||
b.RunParallel(func(pb *testing.PB) {
|
||||
for pb.Next() {
|
||||
_, s := m.Index(bench_pattern)
|
||||
releaseSegments(s)
|
||||
}
|
||||
})
|
||||
}
|
82
vendor/github.com/gobwas/glob/match/row_test.go
generated
vendored
82
vendor/github.com/gobwas/glob/match/row_test.go
generated
vendored
|
@ -1,82 +0,0 @@
|
|||
package match
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestRowIndex(t *testing.T) {
|
||||
for id, test := range []struct {
|
||||
matchers Matchers
|
||||
length int
|
||||
fixture string
|
||||
index int
|
||||
segments []int
|
||||
}{
|
||||
{
|
||||
Matchers{
|
||||
NewText("abc"),
|
||||
NewText("def"),
|
||||
NewSingle(nil),
|
||||
},
|
||||
7,
|
||||
"qweabcdefghij",
|
||||
3,
|
||||
[]int{7},
|
||||
},
|
||||
{
|
||||
Matchers{
|
||||
NewText("abc"),
|
||||
NewText("def"),
|
||||
NewSingle(nil),
|
||||
},
|
||||
7,
|
||||
"abcd",
|
||||
-1,
|
||||
nil,
|
||||
},
|
||||
} {
|
||||
p := NewRow(test.length, test.matchers...)
|
||||
index, segments := p.Index(test.fixture)
|
||||
if index != test.index {
|
||||
t.Errorf("#%d unexpected index: exp: %d, act: %d", id, test.index, index)
|
||||
}
|
||||
if !reflect.DeepEqual(segments, test.segments) {
|
||||
t.Errorf("#%d unexpected segments: exp: %v, act: %v", id, test.segments, segments)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkRowIndex(b *testing.B) {
|
||||
m := NewRow(
|
||||
7,
|
||||
Matchers{
|
||||
NewText("abc"),
|
||||
NewText("def"),
|
||||
NewSingle(nil),
|
||||
}...,
|
||||
)
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
_, s := m.Index(bench_pattern)
|
||||
releaseSegments(s)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkIndexRowParallel(b *testing.B) {
|
||||
m := NewRow(
|
||||
7,
|
||||
Matchers{
|
||||
NewText("abc"),
|
||||
NewText("def"),
|
||||
NewSingle(nil),
|
||||
}...,
|
||||
)
|
||||
|
||||
b.RunParallel(func(pb *testing.PB) {
|
||||
for pb.Next() {
|
||||
_, s := m.Index(bench_pattern)
|
||||
releaseSegments(s)
|
||||
}
|
||||
})
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue