mirror of
https://github.com/grafana/grafana.git
synced 2026-01-07 01:44:00 +08:00
Compare commits
2686 Commits
v2.1.2
...
v3.0-beta1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2bf305b177 | ||
|
|
d3a4b7a799 | ||
|
|
b85b5e00d4 | ||
|
|
45b90972dc | ||
|
|
7180d6aa07 | ||
|
|
9d6445d4ce | ||
|
|
953f9da3b5 | ||
|
|
97b304abc9 | ||
|
|
49a1d4417d | ||
|
|
8451de8752 | ||
|
|
32bed83a17 | ||
|
|
92edce8fa1 | ||
|
|
545d3208c8 | ||
|
|
b745726462 | ||
|
|
3dbfd49414 | ||
|
|
2ee9376df2 | ||
|
|
aa62c2eff6 | ||
|
|
04d142cd62 | ||
|
|
2f3627e74b | ||
|
|
d545902acc | ||
|
|
4871a8f43e | ||
|
|
32c8f495ab | ||
|
|
0c21d2c047 | ||
|
|
0964a06ab5 | ||
|
|
3e50ee6193 | ||
|
|
da98f47502 | ||
|
|
036f407d6a | ||
|
|
2c60dbd4fb | ||
|
|
b12ca1da88 | ||
|
|
d4ada51fad | ||
|
|
f0ae6a0bb1 | ||
|
|
1e44ee9e9b | ||
|
|
b3bda2aa64 | ||
|
|
82ad5a632d | ||
|
|
21213a2587 | ||
|
|
776af45c09 | ||
|
|
70b66382eb | ||
|
|
14326b626e | ||
|
|
1dabd68327 | ||
|
|
f27ce7e1e4 | ||
|
|
91c5515d5b | ||
|
|
6ab1937ff5 | ||
|
|
576a490435 | ||
|
|
0afa545b06 | ||
|
|
937cefe824 | ||
|
|
896605f838 | ||
|
|
250e98837f | ||
|
|
2cb3505dce | ||
|
|
73f11fae2e | ||
|
|
4ced5bbbc0 | ||
|
|
4421fda877 | ||
|
|
5407052e0c | ||
|
|
90c7943242 | ||
|
|
70d536c6c4 | ||
|
|
319b934967 | ||
|
|
61017fc204 | ||
|
|
1ff90b713f | ||
|
|
7045d06221 | ||
|
|
05cc370c55 | ||
|
|
963e202745 | ||
|
|
82b1a11820 | ||
|
|
694c6e8fd2 | ||
|
|
45186255cf | ||
|
|
a531a1709e | ||
|
|
f85a3ad44d | ||
|
|
ee7afcbe9e | ||
|
|
b3b63f836a | ||
|
|
c2ef2ef287 | ||
|
|
e65fd45c65 | ||
|
|
32a1d1445c | ||
|
|
35c853e906 | ||
|
|
481139772b | ||
|
|
5dfac9a765 | ||
|
|
ee92fee212 | ||
|
|
b06d809364 | ||
|
|
f8fb97d912 | ||
|
|
5f2f4a0897 | ||
|
|
b7d198793f | ||
|
|
991b6eafca | ||
|
|
5b75eea8cf | ||
|
|
ba48f40d21 | ||
|
|
6fafc8dba1 | ||
|
|
53312852e9 | ||
|
|
2d59112c1b | ||
|
|
637db29fad | ||
|
|
87aca5bf1b | ||
|
|
585503f9fb | ||
|
|
19e07a610a | ||
|
|
4058c85e2a | ||
|
|
b3c073ab6c | ||
|
|
6a42b95d39 | ||
|
|
30b2a7169f | ||
|
|
cb49e11eca | ||
|
|
5b5cf9f006 | ||
|
|
2bf94d8db4 | ||
|
|
7366cef1fe | ||
|
|
1854381456 | ||
|
|
8dee54bf5d | ||
|
|
bbc4c361bb | ||
|
|
83b7397398 | ||
|
|
04a887dafa | ||
|
|
4c5291f941 | ||
|
|
b73d196c6b | ||
|
|
d0564933a2 | ||
|
|
03f91e8d85 | ||
|
|
c711fb67c8 | ||
|
|
7e6314dcac | ||
|
|
10df9dc8c3 | ||
|
|
4110c7ffb0 | ||
|
|
7f79024e6a | ||
|
|
f6cbbe1e64 | ||
|
|
64312ceded | ||
|
|
98206ab49f | ||
|
|
56622ee2c6 | ||
|
|
65c0937741 | ||
|
|
8498bfd2c2 | ||
|
|
7403b94b9d | ||
|
|
d40cc32393 | ||
|
|
fc983f9751 | ||
|
|
ae255a7adf | ||
|
|
90c6b04361 | ||
|
|
86a274a7ee | ||
|
|
530b6a5088 | ||
|
|
5e52aaac6f | ||
|
|
3ea441d1a0 | ||
|
|
14df3c6249 | ||
|
|
7f8643efde | ||
|
|
273311eed2 | ||
|
|
06468d6f43 | ||
|
|
4377e95c99 | ||
|
|
f4feb38089 | ||
|
|
82232e2530 | ||
|
|
9c2809a1a4 | ||
|
|
dd5b4a25d1 | ||
|
|
73e5c70d80 | ||
|
|
6d36641080 | ||
|
|
662dbaf8b2 | ||
|
|
e63ff1c762 | ||
|
|
084ad69c53 | ||
|
|
1ccde201be | ||
|
|
48a721e259 | ||
|
|
4c7f638f3c | ||
|
|
35e53ee511 | ||
|
|
b1881e5f54 | ||
|
|
3c39a935f8 | ||
|
|
2b0499c968 | ||
|
|
504d800a0d | ||
|
|
9d4fa87914 | ||
|
|
6016033b8b | ||
|
|
5af54c57ba | ||
|
|
9ddf22ea93 | ||
|
|
b2fe7e518f | ||
|
|
6bf05a8154 | ||
|
|
a08809f8fe | ||
|
|
57ecb276c8 | ||
|
|
79a803ea8f | ||
|
|
0f6579801d | ||
|
|
fcaf2bfdba | ||
|
|
4144f71e23 | ||
|
|
852ecd71f7 | ||
|
|
aadc6e0bbd | ||
|
|
a738945a88 | ||
|
|
9d3cbfe896 | ||
|
|
1a11f1e8c6 | ||
|
|
a12f5376b5 | ||
|
|
fd531e84fc | ||
|
|
d26d7162a5 | ||
|
|
a9cdf580a7 | ||
|
|
990acb3fd3 | ||
|
|
3486bf92eb | ||
|
|
ed1864e076 | ||
|
|
0998ce81f3 | ||
|
|
99e068643b | ||
|
|
0d7eb18d7b | ||
|
|
81c11ebb53 | ||
|
|
2e73c58338 | ||
|
|
381a48f21d | ||
|
|
e4c0c39fbf | ||
|
|
1abdd170d3 | ||
|
|
dddd155afa | ||
|
|
c411714546 | ||
|
|
cba7c1726f | ||
|
|
be8ec24106 | ||
|
|
0b3ccaff27 | ||
|
|
b273cd1339 | ||
|
|
82eb32a71e | ||
|
|
e905c2c6b5 | ||
|
|
13376d89cc | ||
|
|
2e1f26096f | ||
|
|
8f97e8d5ed | ||
|
|
92f20b9b7d | ||
|
|
3d5251d9a5 | ||
|
|
195be2742c | ||
|
|
2adc4d12be | ||
|
|
8d7b7009c3 | ||
|
|
ca5a34ad1e | ||
|
|
fbd94fc6ce | ||
|
|
953a07252a | ||
|
|
f77bd59e1d | ||
|
|
5b6754ce6c | ||
|
|
4aba3bc62b | ||
|
|
fc6ad2059a | ||
|
|
69c8bb1eb3 | ||
|
|
c504abb84d | ||
|
|
2527289e3e | ||
|
|
581ffb862c | ||
|
|
8e70e9c1c3 | ||
|
|
4a3c19c666 | ||
|
|
d575a5ce12 | ||
|
|
53dc145ce7 | ||
|
|
0398face05 | ||
|
|
ef7d8ab90b | ||
|
|
28f4f3a8c8 | ||
|
|
3fb0b71822 | ||
|
|
40b2f00dc5 | ||
|
|
749da42ffc | ||
|
|
1f9f439acb | ||
|
|
c5a817194a | ||
|
|
c1e4d0590c | ||
|
|
85466c7ee1 | ||
|
|
740478344b | ||
|
|
5094c1db2a | ||
|
|
f5bb2b11e5 | ||
|
|
8da702c2e7 | ||
|
|
d2b0bad1cf | ||
|
|
ece8a925a6 | ||
|
|
fc54c01f01 | ||
|
|
3fd420c901 | ||
|
|
01788e86e5 | ||
|
|
4f52bc138f | ||
|
|
2de439bd1e | ||
|
|
b989e2ce37 | ||
|
|
25f08ddd39 | ||
|
|
a16c799da9 | ||
|
|
0052e9d136 | ||
|
|
b72cf90ed4 | ||
|
|
69013ef8ad | ||
|
|
16132e86a3 | ||
|
|
047191abf0 | ||
|
|
11372ac9ff | ||
|
|
336c1b7b6e | ||
|
|
2c5abed2f1 | ||
|
|
8c6890c95f | ||
|
|
60adcedebe | ||
|
|
95de5f6fe1 | ||
|
|
788aafff3c | ||
|
|
c09d506245 | ||
|
|
18c5e90076 | ||
|
|
fee0745e98 | ||
|
|
43073da7eb | ||
|
|
0b6fee138a | ||
|
|
78b9c3004a | ||
|
|
c99aa74140 | ||
|
|
4fbff99186 | ||
|
|
8afd56575c | ||
|
|
1951f3856f | ||
|
|
8357cdf591 | ||
|
|
499bad5f53 | ||
|
|
df2a23d1a7 | ||
|
|
d6ecf74db4 | ||
|
|
6670e6cd29 | ||
|
|
d8b11adfd5 | ||
|
|
4a5b753fd8 | ||
|
|
d9231eb805 | ||
|
|
bb1e7f62a0 | ||
|
|
e5ffb2bfd2 | ||
|
|
6fff0b3e2a | ||
|
|
f0d1853a66 | ||
|
|
7224728ab8 | ||
|
|
ca7c3cc27d | ||
|
|
ac439d83fe | ||
|
|
c0b92eb5d0 | ||
|
|
5599bdf1bc | ||
|
|
de41536046 | ||
|
|
30d321998c | ||
|
|
59a02ce76a | ||
|
|
2c396d4922 | ||
|
|
3191678b14 | ||
|
|
7ecf057901 | ||
|
|
091726b374 | ||
|
|
dfaa6d8eb9 | ||
|
|
aff4bf8f6c | ||
|
|
ba1e1532ac | ||
|
|
ae3bda81c5 | ||
|
|
0ec747630d | ||
|
|
945131ccab | ||
|
|
f11b4cb481 | ||
|
|
92c6025390 | ||
|
|
138c738db9 | ||
|
|
4fae1958fa | ||
|
|
fb450385d7 | ||
|
|
7b1d827460 | ||
|
|
74ebc2d3b0 | ||
|
|
95f3e52064 | ||
|
|
da2b65cd7c | ||
|
|
2fcb8b849e | ||
|
|
d7a72e30c0 | ||
|
|
f397d0ddd7 | ||
|
|
db98632078 | ||
|
|
1509b4cb6e | ||
|
|
f20f4d130b | ||
|
|
3af4b1ff98 | ||
|
|
f80c2406a8 | ||
|
|
17006b4539 | ||
|
|
e5d400ebb9 | ||
|
|
f824004e4f | ||
|
|
453eebbac8 | ||
|
|
1a39d93b4e | ||
|
|
6fac471415 | ||
|
|
252568c91b | ||
|
|
8e11f8dc21 | ||
|
|
2475ca8f9a | ||
|
|
2a18430a45 | ||
|
|
dc4743a392 | ||
|
|
0cb57f52de | ||
|
|
d2aaa2211e | ||
|
|
f4666df7da | ||
|
|
4cd4ce504d | ||
|
|
fadfa7cc42 | ||
|
|
b912edbbef | ||
|
|
a6c6b00d7e | ||
|
|
2a557f67d2 | ||
|
|
1a6af064b0 | ||
|
|
7ef62d28a5 | ||
|
|
b8fb8cdce6 | ||
|
|
135679096b | ||
|
|
1ff428087e | ||
|
|
f6c5242a93 | ||
|
|
3d2d8f2d86 | ||
|
|
aef8dab4d9 | ||
|
|
bcb7eff6fa | ||
|
|
e16f45e494 | ||
|
|
435d0f22f5 | ||
|
|
dc2738afad | ||
|
|
08a45e9a3b | ||
|
|
00c70307ad | ||
|
|
883435336c | ||
|
|
2c8e35a933 | ||
|
|
7df18678a4 | ||
|
|
260c731f6b | ||
|
|
00b1908f3c | ||
|
|
e73e7aea56 | ||
|
|
a72d73294c | ||
|
|
0f546a4692 | ||
|
|
dd7e215e78 | ||
|
|
fcd75422d5 | ||
|
|
ad6837ee47 | ||
|
|
01d5bc73cc | ||
|
|
f3b915c43a | ||
|
|
73a49c463d | ||
|
|
d86cb92a94 | ||
|
|
09c29cdda5 | ||
|
|
67dec6a665 | ||
|
|
b673bc1386 | ||
|
|
4b08f3909d | ||
|
|
35fc5007c8 | ||
|
|
ac499b3aff | ||
|
|
31c317f5f7 | ||
|
|
a6623357ad | ||
|
|
c6a1076e3a | ||
|
|
d318c84434 | ||
|
|
c21a210198 | ||
|
|
fc877ae0f4 | ||
|
|
1049824014 | ||
|
|
1d8222ef6a | ||
|
|
ee635be441 | ||
|
|
01d3282838 | ||
|
|
35a502f309 | ||
|
|
662579e9a9 | ||
|
|
00dd0e8a9d | ||
|
|
430c312263 | ||
|
|
8ed8bfb8bc | ||
|
|
0939371e2e | ||
|
|
f2dabd0731 | ||
|
|
e7ef79e0d3 | ||
|
|
ffda5bc0f7 | ||
|
|
737896695c | ||
|
|
ae69244ac7 | ||
|
|
8232552152 | ||
|
|
f7b481fc28 | ||
|
|
8bc1af9d1a | ||
|
|
fd1a0edf7f | ||
|
|
4c83dba183 | ||
|
|
b641720575 | ||
|
|
950455bd93 | ||
|
|
eb79436ab7 | ||
|
|
10db47bf4c | ||
|
|
4d454f8914 | ||
|
|
eb4a46b40f | ||
|
|
7df326083d | ||
|
|
48f5a61564 | ||
|
|
19f0f7535f | ||
|
|
e3e0b72b43 | ||
|
|
3435df8b9c | ||
|
|
7e12460303 | ||
|
|
9d3d0912e5 | ||
|
|
1ed4f64e60 | ||
|
|
8b64b2113e | ||
|
|
5bf2b6c382 | ||
|
|
fa0b06ac60 | ||
|
|
ef22a87fcf | ||
|
|
bfce379471 | ||
|
|
4872f6d2dc | ||
|
|
3c30870dc2 | ||
|
|
4317e4c4a2 | ||
|
|
7da57e0aa5 | ||
|
|
0da4168836 | ||
|
|
df67d57bca | ||
|
|
82e7f1a212 | ||
|
|
289521b4b7 | ||
|
|
d557beb5f1 | ||
|
|
2cf1193b56 | ||
|
|
57315f1e27 | ||
|
|
56bef637bd | ||
|
|
d1bac6cde0 | ||
|
|
23a136d9ef | ||
|
|
d8f7bce9d4 | ||
|
|
39354249e9 | ||
|
|
98e756e278 | ||
|
|
91ca5b6f2a | ||
|
|
b6ac0860c6 | ||
|
|
00dc078311 | ||
|
|
2d9a2506b4 | ||
|
|
fa73b1ce80 | ||
|
|
f4b97979c4 | ||
|
|
62b21c586d | ||
|
|
606c75162f | ||
|
|
a8c10dbc08 | ||
|
|
c6768a93c8 | ||
|
|
74949d306f | ||
|
|
77f93886da | ||
|
|
8f5a7f1764 | ||
|
|
f78f7d6b37 | ||
|
|
75541b9cf0 | ||
|
|
922b7c44ce | ||
|
|
8bc63e9029 | ||
|
|
2647f59df1 | ||
|
|
77f6449db9 | ||
|
|
f3ad71d751 | ||
|
|
2db62a211a | ||
|
|
4e6c1335d5 | ||
|
|
f185528f1c | ||
|
|
2b668e628a | ||
|
|
0688d7ca9f | ||
|
|
0135dff001 | ||
|
|
efe25db40f | ||
|
|
773a5631c5 | ||
|
|
5d5f5cd9a6 | ||
|
|
ad9b2ab617 | ||
|
|
cb8b038795 | ||
|
|
078e69d06d | ||
|
|
df8e56ddf8 | ||
|
|
f44d6e063c | ||
|
|
113509a4e9 | ||
|
|
839c675cb9 | ||
|
|
854c360def | ||
|
|
0cbb95ed1e | ||
|
|
d8929b1d3e | ||
|
|
fa99a6745d | ||
|
|
b79217be1e | ||
|
|
d27a0f5b0c | ||
|
|
97c27668bc | ||
|
|
e5970e83ff | ||
|
|
d3c022f89e | ||
|
|
3624587f08 | ||
|
|
56c080417a | ||
|
|
da4e3784e9 | ||
|
|
35f7a71f9a | ||
|
|
bf22b4cbfe | ||
|
|
4741152f05 | ||
|
|
fb33cf4576 | ||
|
|
1fb38abf6b | ||
|
|
4299feee37 | ||
|
|
86b1906798 | ||
|
|
18a0a85df6 | ||
|
|
05ba32b552 | ||
|
|
c30c12d369 | ||
|
|
09dfaf9875 | ||
|
|
ae604b6289 | ||
|
|
fc8146b53d | ||
|
|
641845519d | ||
|
|
b32809d03f | ||
|
|
02b2c7482a | ||
|
|
6fd0d5e267 | ||
|
|
a4ecacb9b5 | ||
|
|
b9e0fcdf85 | ||
|
|
4ef79d250d | ||
|
|
18c57ea230 | ||
|
|
a883424d25 | ||
|
|
7fa170cee9 | ||
|
|
8925329950 | ||
|
|
4aa5dab62d | ||
|
|
936dd2eaaa | ||
|
|
09e80f0390 | ||
|
|
63dfa303e5 | ||
|
|
599b1eb689 | ||
|
|
4a636b6da7 | ||
|
|
d92172f50c | ||
|
|
2623240635 | ||
|
|
908e8577bb | ||
|
|
f90fda8e6f | ||
|
|
f4037667fa | ||
|
|
a1fd12ef42 | ||
|
|
517721eaa4 | ||
|
|
b56a2c14bb | ||
|
|
62d703fdf7 | ||
|
|
f29899e566 | ||
|
|
9cebcc45c1 | ||
|
|
3125177e5c | ||
|
|
7810413699 | ||
|
|
261db14c4b | ||
|
|
16783bff16 | ||
|
|
352cdc137d | ||
|
|
bd2e1ef67e | ||
|
|
7f970bbc7b | ||
|
|
35609fe3d1 | ||
|
|
4fcca7c61b | ||
|
|
d55dc92502 | ||
|
|
c148d89004 | ||
|
|
8e7a127792 | ||
|
|
6afe2c4e9f | ||
|
|
be69e2c02c | ||
|
|
e3be9f7fe9 | ||
|
|
ca3cb07fcb | ||
|
|
b98e5690eb | ||
|
|
45e6187c1a | ||
|
|
c521182ceb | ||
|
|
83662b5195 | ||
|
|
8db7cf49a6 | ||
|
|
30f3b55baf | ||
|
|
8750ba94c8 | ||
|
|
b5beac879e | ||
|
|
e8b6995cc7 | ||
|
|
7ca8db15d9 | ||
|
|
9d96382ecc | ||
|
|
b86b8965f1 | ||
|
|
f6c49daaa6 | ||
|
|
a129a6192a | ||
|
|
22ae259cf5 | ||
|
|
e627820d3d | ||
|
|
65711f4bfe | ||
|
|
4531f39c30 | ||
|
|
3db1188444 | ||
|
|
be3d38ac92 | ||
|
|
b490bdfe33 | ||
|
|
95725e407e | ||
|
|
f6457a2023 | ||
|
|
7dcb85010a | ||
|
|
0525bf5d4e | ||
|
|
7207068181 | ||
|
|
59d2fe8aa4 | ||
|
|
be92c8bde1 | ||
|
|
a3e22091be | ||
|
|
17b7dfb27b | ||
|
|
06173b9194 | ||
|
|
2a45e879bb | ||
|
|
ce6c67f9bc | ||
|
|
87cb0c2aec | ||
|
|
d0b191af18 | ||
|
|
b607adadcf | ||
|
|
e7828c1e5e | ||
|
|
c051cb8be1 | ||
|
|
6f51fc34c3 | ||
|
|
02b02c51e8 | ||
|
|
a414dd028c | ||
|
|
c2439b04c9 | ||
|
|
ed550a894f | ||
|
|
8b51f58fe7 | ||
|
|
310b0e888d | ||
|
|
c189c20164 | ||
|
|
0811338370 | ||
|
|
ecc22757b8 | ||
|
|
5e553e40fa | ||
|
|
26c5029256 | ||
|
|
75454b02c0 | ||
|
|
bbc079e57b | ||
|
|
83bbffd491 | ||
|
|
fc5e1d97af | ||
|
|
85041d297c | ||
|
|
17c7ce9b40 | ||
|
|
6506161107 | ||
|
|
590da0cab3 | ||
|
|
44b6a3a054 | ||
|
|
a11396c901 | ||
|
|
cd52c24e87 | ||
|
|
2e52008542 | ||
|
|
a6a5f393cc | ||
|
|
b3f2f0fa1e | ||
|
|
f788c8cb37 | ||
|
|
deaeec0bc7 | ||
|
|
16656af847 | ||
|
|
3b279983e6 | ||
|
|
55d4392d90 | ||
|
|
acfc119409 | ||
|
|
18fcb23371 | ||
|
|
1ae2fc648d | ||
|
|
2215095be8 | ||
|
|
28d2966819 | ||
|
|
92efd17952 | ||
|
|
3a7ec2a26e | ||
|
|
56a05d78bd | ||
|
|
fa5cf602f5 | ||
|
|
c94659f552 | ||
|
|
1164510004 | ||
|
|
f24867029c | ||
|
|
680ff95b8e | ||
|
|
31ea5f550f | ||
|
|
fc62af6b3a | ||
|
|
f8533e6641 | ||
|
|
87fec9d434 | ||
|
|
b1e9327a2b | ||
|
|
0aa4b47d59 | ||
|
|
b9d50fa144 | ||
|
|
3231d767d5 | ||
|
|
3f05b4bb1e | ||
|
|
9eabd956b7 | ||
|
|
eb58414600 | ||
|
|
cb83c237f4 | ||
|
|
773a13dc26 | ||
|
|
8c2f7ac083 | ||
|
|
f375c3000d | ||
|
|
ea4ce0ce1f | ||
|
|
c9fe2bab60 | ||
|
|
6c617ba28c | ||
|
|
b98c826e95 | ||
|
|
2034d4b971 | ||
|
|
f225bb0032 | ||
|
|
69b87fdb9a | ||
|
|
6f70445654 | ||
|
|
145c14ed57 | ||
|
|
b9843fe6d1 | ||
|
|
ab9757082e | ||
|
|
d6e4fb46cf | ||
|
|
a93fe5b2b2 | ||
|
|
8f9c3c8381 | ||
|
|
363f36dfae | ||
|
|
7328f4d3fd | ||
|
|
8f3b6a23f6 | ||
|
|
cc4fdd6d0c | ||
|
|
3781a099dd | ||
|
|
e4d52b2851 | ||
|
|
ac45ccbad7 | ||
|
|
1a412378db | ||
|
|
17904a6e8b | ||
|
|
9c47fdeb2f | ||
|
|
808ac2cefc | ||
|
|
aaf6dd2cd6 | ||
|
|
08f7ccff38 | ||
|
|
13720759a5 | ||
|
|
a2731da987 | ||
|
|
a8e1572955 | ||
|
|
3ca8e8a6d2 | ||
|
|
bf4a00b663 | ||
|
|
4ab041f79e | ||
|
|
f3fe1a5320 | ||
|
|
f808baafa7 | ||
|
|
1f28ff6890 | ||
|
|
640c9a49d8 | ||
|
|
5d51b439d2 | ||
|
|
9ae050f0e5 | ||
|
|
c77f91213c | ||
|
|
0f7d6a780a | ||
|
|
ab4957684f | ||
|
|
1dbaabffbc | ||
|
|
d42bfc2570 | ||
|
|
9ed45ba761 | ||
|
|
9d893eec01 | ||
|
|
52241b8e0b | ||
|
|
701a2fdcf3 | ||
|
|
995f17493e | ||
|
|
eb787adccd | ||
|
|
57e6e0092d | ||
|
|
a685e46fb6 | ||
|
|
1144988443 | ||
|
|
27dc32e2e8 | ||
|
|
6721cec73f | ||
|
|
18bbefee1c | ||
|
|
bd0357b637 | ||
|
|
49507ea377 | ||
|
|
2c0b191ef5 | ||
|
|
02ac7a4001 | ||
|
|
fbe422008a | ||
|
|
d0d21ba9a6 | ||
|
|
c78669353f | ||
|
|
afb62638a8 | ||
|
|
4a062b6d00 | ||
|
|
6590e6fae8 | ||
|
|
ab7bbd5a44 | ||
|
|
317f2d043f | ||
|
|
c21b353042 | ||
|
|
a73ef353f0 | ||
|
|
d769f6c084 | ||
|
|
ed58474c37 | ||
|
|
4c3048964d | ||
|
|
cacf14a41e | ||
|
|
e24e34619a | ||
|
|
ac1648c946 | ||
|
|
65f9cc986a | ||
|
|
252cd4901b | ||
|
|
a2b69e96b9 | ||
|
|
3a0a8810d1 | ||
|
|
b9c60125e8 | ||
|
|
cae975cb39 | ||
|
|
2f2326006d | ||
|
|
d183c11e69 | ||
|
|
653d4b1d6a | ||
|
|
d1f6bbf32f | ||
|
|
22fac87473 | ||
|
|
3003a8cb6e | ||
|
|
f4908b6315 | ||
|
|
63ca9f6f5a | ||
|
|
b9059181fd | ||
|
|
25ca751ab8 | ||
|
|
08c1def8b7 | ||
|
|
71210dd624 | ||
|
|
fee9df4c2b | ||
|
|
5d7d165be5 | ||
|
|
b5d4a678d4 | ||
|
|
8193d50da7 | ||
|
|
ffc9a8322b | ||
|
|
f28eec8be3 | ||
|
|
807c052fea | ||
|
|
45e232ef62 | ||
|
|
9accb962aa | ||
|
|
4ab3542c88 | ||
|
|
5a67ca255f | ||
|
|
c97dbf390e | ||
|
|
008a031493 | ||
|
|
b05939ec9a | ||
|
|
84e50f9003 | ||
|
|
7c917156ee | ||
|
|
6a7e9134a5 | ||
|
|
86ef33f84f | ||
|
|
6f794b7d11 | ||
|
|
febad7b1d7 | ||
|
|
48c5e26acd | ||
|
|
3f0679896b | ||
|
|
96e98f6d4c | ||
|
|
b067317595 | ||
|
|
1febd578a4 | ||
|
|
4131d8b57a | ||
|
|
36f4f1d0f3 | ||
|
|
1cd3985913 | ||
|
|
058c905432 | ||
|
|
41b775561a | ||
|
|
0ee7ac2c5e | ||
|
|
3fd6ae597d | ||
|
|
14312d225c | ||
|
|
262a03667e | ||
|
|
422decde3b | ||
|
|
6fc2b69697 | ||
|
|
594ab0e2b5 | ||
|
|
ea9ac0d2d2 | ||
|
|
9045be0c12 | ||
|
|
bc4c71a7c6 | ||
|
|
18079aaced | ||
|
|
47644f2755 | ||
|
|
43b91ea0d6 | ||
|
|
83bf63641c | ||
|
|
1e891f434d | ||
|
|
746257710b | ||
|
|
30ddfc7a28 | ||
|
|
5447bd007a | ||
|
|
f8e233e400 | ||
|
|
9c50b89d64 | ||
|
|
063b54aefe | ||
|
|
c961d6218d | ||
|
|
1176b68c6a | ||
|
|
5adac86b43 | ||
|
|
580cd510d5 | ||
|
|
d59beec354 | ||
|
|
c11322a016 | ||
|
|
fe4cdc59be | ||
|
|
35a1a04f50 | ||
|
|
6e7813f2f8 | ||
|
|
7c9728df47 | ||
|
|
da8782a9d0 | ||
|
|
d523d45124 | ||
|
|
c4d6051477 | ||
|
|
cd060c64d5 | ||
|
|
f881ada45c | ||
|
|
b9b3b75c0c | ||
|
|
37b031afcf | ||
|
|
fcc3a7f6e4 | ||
|
|
5836a6ec4b | ||
|
|
9e0ed7bc8e | ||
|
|
50c79df70f | ||
|
|
f888716d81 | ||
|
|
5274f93db7 | ||
|
|
e32ee9f02e | ||
|
|
48c936e9a9 | ||
|
|
b77bce1961 | ||
|
|
f3d277cbab | ||
|
|
afa4ee9a28 | ||
|
|
92f4442356 | ||
|
|
47b6f01c8b | ||
|
|
68225d64aa | ||
|
|
fa06040ed2 | ||
|
|
eae4bb74dd | ||
|
|
caa765ec32 | ||
|
|
e00f9611f4 | ||
|
|
1004515bda | ||
|
|
7d75e0e53c | ||
|
|
f7e3297a0f | ||
|
|
14952de2ee | ||
|
|
f98dbd249e | ||
|
|
b369b7e495 | ||
|
|
23167a0bb3 | ||
|
|
8c1195b277 | ||
|
|
6cdc1e4d37 | ||
|
|
e7a202fe4d | ||
|
|
b5dc1727d2 | ||
|
|
53f5cb6553 | ||
|
|
f797b19825 | ||
|
|
814ca99e3d | ||
|
|
c483b2ff98 | ||
|
|
2496202417 | ||
|
|
3c6fadb6f8 | ||
|
|
055e5aff2a | ||
|
|
692878b0c0 | ||
|
|
a6061ce555 | ||
|
|
2ea548850e | ||
|
|
87fc83678c | ||
|
|
d8b43a3d76 | ||
|
|
6189208fa5 | ||
|
|
daf8db71a8 | ||
|
|
c186d8b2be | ||
|
|
cd40362d47 | ||
|
|
81ad469533 | ||
|
|
bb77070aab | ||
|
|
c051ff3eac | ||
|
|
ff913333a2 | ||
|
|
ac5f7ecdea | ||
|
|
4e33e80957 | ||
|
|
bf1b60564e | ||
|
|
50ddf7913a | ||
|
|
39bb9ce118 | ||
|
|
2d8180fc9c | ||
|
|
fac51d92c5 | ||
|
|
c3fc340c09 | ||
|
|
581fb8ebfd | ||
|
|
0fa0b3b256 | ||
|
|
3b21e9fcf0 | ||
|
|
4c35c83b84 | ||
|
|
37c6a1ddf0 | ||
|
|
9c0b89b9b0 | ||
|
|
ae39ec8585 | ||
|
|
e37817285a | ||
|
|
dfe0e258cd | ||
|
|
eda23252e1 | ||
|
|
257b824d4f | ||
|
|
b469904c7f | ||
|
|
509b37eb91 | ||
|
|
9dac382fbf | ||
|
|
ddbdb54c04 | ||
|
|
181a671bfb | ||
|
|
1ce34ed907 | ||
|
|
f9e7b14f2c | ||
|
|
dad394523f | ||
|
|
1c50eb345c | ||
|
|
5c7689388d | ||
|
|
baff9b0267 | ||
|
|
fe2e6b8a80 | ||
|
|
fb74ebb4ea | ||
|
|
8784be9a14 | ||
|
|
fba3d7cb0f | ||
|
|
f953033ba7 | ||
|
|
72415be2db | ||
|
|
9653f43466 | ||
|
|
1acbd5b7d8 | ||
|
|
f0ecbd3878 | ||
|
|
9dcfe6dc39 | ||
|
|
397e4e4766 | ||
|
|
5b9ed82d29 | ||
|
|
0def04ad34 | ||
|
|
e9982bb27e | ||
|
|
18eb9d6076 | ||
|
|
e7ff018487 | ||
|
|
6ba5471bd4 | ||
|
|
ddb1d0c684 | ||
|
|
7d89cf228c | ||
|
|
5775c0a341 | ||
|
|
d750908e36 | ||
|
|
b1a648608b | ||
|
|
b7147a8bd2 | ||
|
|
82d5d1b003 | ||
|
|
f4e90df406 | ||
|
|
2cce057df1 | ||
|
|
dea2234b14 | ||
|
|
99a053bbdd | ||
|
|
b7fd6bcf7d | ||
|
|
a3b6efdbfa | ||
|
|
3a1dff6636 | ||
|
|
cf92011fb9 | ||
|
|
0106033293 | ||
|
|
4a43cc1df6 | ||
|
|
0f52b4397f | ||
|
|
9c0da733e8 | ||
|
|
de90ad8967 | ||
|
|
2f3d1ec2ef | ||
|
|
73bed3880f | ||
|
|
edebdb166e | ||
|
|
7f83be3d0d | ||
|
|
50920b1423 | ||
|
|
42b1c8c80d | ||
|
|
a5d1e9ee43 | ||
|
|
ff4dbea19d | ||
|
|
1bd58bc1c0 | ||
|
|
21b0945d08 | ||
|
|
89ef019b7c | ||
|
|
801129530e | ||
|
|
23fa5fa1c7 | ||
|
|
020277c045 | ||
|
|
f8b3c0a64c | ||
|
|
d03ae3bfe5 | ||
|
|
6f9896c2fe | ||
|
|
853cd16336 | ||
|
|
0fab210ad2 | ||
|
|
9fc0a83b83 | ||
|
|
aa8bd044c5 | ||
|
|
0201b9769c | ||
|
|
4ff6748eb4 | ||
|
|
59cb429d2d | ||
|
|
454ccb451b | ||
|
|
273fbaac68 | ||
|
|
8ff997594f | ||
|
|
616a6bec38 | ||
|
|
a6c736b8a2 | ||
|
|
5b02d63c89 | ||
|
|
c1fc8995ce | ||
|
|
34f261588f | ||
|
|
f188900379 | ||
|
|
f80d5f8c03 | ||
|
|
fcc960e9a2 | ||
|
|
db27bbb162 | ||
|
|
1bce8f6669 | ||
|
|
15fb56e607 | ||
|
|
714129c8e3 | ||
|
|
59a384b453 | ||
|
|
b5a5b7b912 | ||
|
|
a167eb4fa1 | ||
|
|
660ce3a61d | ||
|
|
edf5868c38 | ||
|
|
5588e7597c | ||
|
|
68a5fb66ff | ||
|
|
33dc9fdd76 | ||
|
|
316e1aac67 | ||
|
|
2ed3cd7f1a | ||
|
|
14cc771cbe | ||
|
|
2a8b96b680 | ||
|
|
6f923ecd17 | ||
|
|
501f21b16c | ||
|
|
f4ad673b6d | ||
|
|
37ff432f9d | ||
|
|
20283a46f9 | ||
|
|
634699c8e2 | ||
|
|
7d97f381cf | ||
|
|
7a1326ff14 | ||
|
|
ee84d4371b | ||
|
|
f8b05e0f42 | ||
|
|
a4e5b7ea37 | ||
|
|
a20443b577 | ||
|
|
e96d72d669 | ||
|
|
defb15bea1 | ||
|
|
10016d9d38 | ||
|
|
73ec486434 | ||
|
|
ccb063df06 | ||
|
|
b90a078be0 | ||
|
|
80e15dd754 | ||
|
|
de394311e0 | ||
|
|
908765e0e7 | ||
|
|
c465e594d7 | ||
|
|
0da733de9c | ||
|
|
2fc8da7a87 | ||
|
|
0bea6aba63 | ||
|
|
fe2c096166 | ||
|
|
c90619c665 | ||
|
|
952e4dab3e | ||
|
|
eecf844ca2 | ||
|
|
8952c7c9d1 | ||
|
|
c6ab63ec47 | ||
|
|
05dfccbb74 | ||
|
|
fc829b32d9 | ||
|
|
f2700822e9 | ||
|
|
21f6c07686 | ||
|
|
4bafb88720 | ||
|
|
7c61ed99ae | ||
|
|
356f7b9db6 | ||
|
|
822c8f1575 | ||
|
|
efdd4a6682 | ||
|
|
eaaf9246b7 | ||
|
|
00a6efa15e | ||
|
|
c5377fb429 | ||
|
|
0583ec0f93 | ||
|
|
12f487e223 | ||
|
|
30a8a434a1 | ||
|
|
79db997e8c | ||
|
|
137ef1f781 | ||
|
|
338afc80d5 | ||
|
|
78598df96e | ||
|
|
e737dab5ca | ||
|
|
84609a4a3b | ||
|
|
0b25a29a9c | ||
|
|
b1bfd35968 | ||
|
|
a053552fee | ||
|
|
6886faa944 | ||
|
|
c843637a6a | ||
|
|
2f78584cdb | ||
|
|
6b7491e111 | ||
|
|
2e20c680cb | ||
|
|
f33de8e911 | ||
|
|
fbc90e038c | ||
|
|
bf943ddba3 | ||
|
|
3f945e886b | ||
|
|
931d7cd039 | ||
|
|
3f5b33b060 | ||
|
|
fa63d26485 | ||
|
|
d617d029d2 | ||
|
|
98082a940c | ||
|
|
12460af0ec | ||
|
|
34eb5acee7 | ||
|
|
9ec3216ab0 | ||
|
|
92c2f8d556 | ||
|
|
eef506d8c4 | ||
|
|
7f15e2c167 | ||
|
|
03aea09ce9 | ||
|
|
2897f618a6 | ||
|
|
5f2aba6c5b | ||
|
|
21632d22ab | ||
|
|
f59f6a5486 | ||
|
|
32989f4cca | ||
|
|
b5ef793ae4 | ||
|
|
d405176367 | ||
|
|
74cb4b6590 | ||
|
|
15087251fb | ||
|
|
73d6b95339 | ||
|
|
c3032f7ba3 | ||
|
|
339e73ee3d | ||
|
|
a2c00f1cc5 | ||
|
|
6da3f87736 | ||
|
|
6ae464f33a | ||
|
|
74decb4bdc | ||
|
|
2e9272c778 | ||
|
|
6fe850e2c1 | ||
|
|
bb3360e92a | ||
|
|
f46eee96a9 | ||
|
|
3ed8870362 | ||
|
|
605f0fa24a | ||
|
|
5a4e48fa99 | ||
|
|
79e7ae4424 | ||
|
|
35071649e0 | ||
|
|
d27bb4d3fb | ||
|
|
64a18874e1 | ||
|
|
05e8c576a2 | ||
|
|
ea7c2e73ad | ||
|
|
b6f276265d | ||
|
|
3c3d3c9ec6 | ||
|
|
d66932a8a2 | ||
|
|
34141363ae | ||
|
|
3ccf7c8006 | ||
|
|
56c76f380b | ||
|
|
f36ade2959 | ||
|
|
85ad5f1d37 | ||
|
|
64fa9a6394 | ||
|
|
a00231a1c2 | ||
|
|
9914714eeb | ||
|
|
600ffa727e | ||
|
|
a7de2ceae4 | ||
|
|
972ac99b7c | ||
|
|
9bd3b417c4 | ||
|
|
a985f21d44 | ||
|
|
7c005e8f0b | ||
|
|
6e886735a3 | ||
|
|
b30dcce4bc | ||
|
|
58121d89fc | ||
|
|
6a1192172d | ||
|
|
8bd07287f8 | ||
|
|
753fd164d7 | ||
|
|
307c86fc28 | ||
|
|
72a64388b5 | ||
|
|
1210fca8e5 | ||
|
|
97ac81aa9c | ||
|
|
c8727db03b | ||
|
|
57d22fb93f | ||
|
|
f0f7da9ff0 | ||
|
|
6c4791b48d | ||
|
|
9c1217cd2c | ||
|
|
448437c342 | ||
|
|
251bf7a2b4 | ||
|
|
f1efce56aa | ||
|
|
34b82caaa8 | ||
|
|
a1b5aae958 | ||
|
|
70c42ddcff | ||
|
|
75ab2e026d | ||
|
|
f43e1ab2ff | ||
|
|
12dfee544f | ||
|
|
0ea651f1df | ||
|
|
8ed9e2e5cc | ||
|
|
a352af5b9f | ||
|
|
51a32a2bfa | ||
|
|
e6013353d2 | ||
|
|
aac190eaa9 | ||
|
|
ebba7a0327 | ||
|
|
13d993a836 | ||
|
|
f384538959 | ||
|
|
269583a6a1 | ||
|
|
0b05d39804 | ||
|
|
2ca7da06a3 | ||
|
|
4b59cee17a | ||
|
|
bf817281a5 | ||
|
|
98982b7a74 | ||
|
|
2114cbcf0b | ||
|
|
979807feee | ||
|
|
add7078f66 | ||
|
|
ab4d020212 | ||
|
|
aa251fc9ce | ||
|
|
c105a07bab | ||
|
|
09de46e5ac | ||
|
|
cc375f48c7 | ||
|
|
e59b0c0694 | ||
|
|
07fee0a810 | ||
|
|
29185eeef7 | ||
|
|
53dc21c69b | ||
|
|
b0dd79cbfd | ||
|
|
442db7fee1 | ||
|
|
be2e2577b8 | ||
|
|
c8c337cead | ||
|
|
92cba94031 | ||
|
|
c30b1b126d | ||
|
|
52403ca17e | ||
|
|
05868bc1df | ||
|
|
092bb69c41 | ||
|
|
40d946a6e3 | ||
|
|
5f1fe13530 | ||
|
|
d8bb7c3094 | ||
|
|
9c6698e87b | ||
|
|
1cac6ecedb | ||
|
|
40088cd4fe | ||
|
|
b939a27a8d | ||
|
|
73af4df96d | ||
|
|
70cd9265bf | ||
|
|
cd1b2e2841 | ||
|
|
b0a24ae4aa | ||
|
|
11e35f7b68 | ||
|
|
8f4cf6c797 | ||
|
|
2190392e05 | ||
|
|
a621c0d273 | ||
|
|
4c12703e0c | ||
|
|
da67afa51e | ||
|
|
3e14f8a0e5 | ||
|
|
a950ff9795 | ||
|
|
4132cf12e3 | ||
|
|
4f7fb40d9b | ||
|
|
c7fae5386d | ||
|
|
42802ac710 | ||
|
|
a85bda13db | ||
|
|
ecdc730de7 | ||
|
|
8927042421 | ||
|
|
32f78d465b | ||
|
|
ab3b586838 | ||
|
|
94a7e9b185 | ||
|
|
1a708da155 | ||
|
|
f94599cd29 | ||
|
|
d9d4e6c82f | ||
|
|
0796b2c0e3 | ||
|
|
bbfdbaf952 | ||
|
|
7b4fe824ec | ||
|
|
28fabadeae | ||
|
|
37495dd1c6 | ||
|
|
e5e8e2021f | ||
|
|
dfd4fbc566 | ||
|
|
08f02397b6 | ||
|
|
d3f90dcfcc | ||
|
|
ba65b89bbb | ||
|
|
3d353c7d6d | ||
|
|
bc05cc4977 | ||
|
|
cbb5811d8b | ||
|
|
6461981aa4 | ||
|
|
c260c319ee | ||
|
|
d13957cb72 | ||
|
|
4a8f82ca9b | ||
|
|
cdcc7a7172 | ||
|
|
f2ce8f266b | ||
|
|
dcde1422b7 | ||
|
|
423eca6e7d | ||
|
|
fd52320460 | ||
|
|
462608517b | ||
|
|
9586493632 | ||
|
|
b150452db3 | ||
|
|
1bca28ad12 | ||
|
|
9e121ef0c8 | ||
|
|
5f5fcc0e04 | ||
|
|
a854f0c4d4 | ||
|
|
1979143e7c | ||
|
|
32ffedccda | ||
|
|
4f7f03a28c | ||
|
|
d0074b25db | ||
|
|
8dd118bd86 | ||
|
|
fb82425d3e | ||
|
|
aa1d28835d | ||
|
|
f30df8bb57 | ||
|
|
281ec60085 | ||
|
|
09f5e6f4dc | ||
|
|
e26cd21048 | ||
|
|
1c5be92259 | ||
|
|
6e99eed417 | ||
|
|
92a085550e | ||
|
|
c4a0ec844c | ||
|
|
3e3b996963 | ||
|
|
36e99ac531 | ||
|
|
7a26d309b1 | ||
|
|
ca55d1f315 | ||
|
|
41fd0ed467 | ||
|
|
bcb44b7b31 | ||
|
|
1ab1154010 | ||
|
|
6b85a6fd78 | ||
|
|
8f067a5ed2 | ||
|
|
db1ba30df7 | ||
|
|
1952ebf7c4 | ||
|
|
70481953fd | ||
|
|
870775e863 | ||
|
|
54383a9a0c | ||
|
|
510a21195a | ||
|
|
3b5a583903 | ||
|
|
a9e05c77d1 | ||
|
|
3418db1dcd | ||
|
|
d94896cf10 | ||
|
|
eb8871a4bd | ||
|
|
389dd12ab4 | ||
|
|
4a54edd8bb | ||
|
|
1d4803cff0 | ||
|
|
6fc972ab1e | ||
|
|
66eebd1ac3 | ||
|
|
568832c5af | ||
|
|
4ff7b0f49b | ||
|
|
c12aa0e8ce | ||
|
|
61a655f199 | ||
|
|
88e9161e57 | ||
|
|
10adc57b3f | ||
|
|
62ae02bdd1 | ||
|
|
dca503bcbd | ||
|
|
bc21862661 | ||
|
|
1e06f3f5f4 | ||
|
|
00802d035a | ||
|
|
edcef7d078 | ||
|
|
899a44a735 | ||
|
|
6a95963c89 | ||
|
|
a35bf497be | ||
|
|
9b42b33648 | ||
|
|
053868f593 | ||
|
|
1adb7b286c | ||
|
|
30c19d525e | ||
|
|
8161a0943d | ||
|
|
a8e3f731b7 | ||
|
|
0cb68b86fc | ||
|
|
723be4f612 | ||
|
|
070af40487 | ||
|
|
0a58404584 | ||
|
|
c201f4c63e | ||
|
|
317b5e6d86 | ||
|
|
38ddc88b20 | ||
|
|
7ad72ba905 | ||
|
|
36e8af05a2 | ||
|
|
2bfded3c5f | ||
|
|
842a59535d | ||
|
|
d4e1a715eb | ||
|
|
954c0e9fae | ||
|
|
f6a3b53fb5 | ||
|
|
01d47fb280 | ||
|
|
dfcb82d233 | ||
|
|
83346a29aa | ||
|
|
317c5ba88d | ||
|
|
caa26f594e | ||
|
|
aa9a92d2e0 | ||
|
|
4f227ae92e | ||
|
|
cd0256d40d | ||
|
|
2ccc19185c | ||
|
|
b4d595e561 | ||
|
|
88a132b878 | ||
|
|
b5726a8d5a | ||
|
|
b7f4a5c198 | ||
|
|
1d9ad9be33 | ||
|
|
2b7a26dabd | ||
|
|
a233570777 | ||
|
|
6fae264222 | ||
|
|
8699d49f93 | ||
|
|
c4ce3293a2 | ||
|
|
dbafc8c9db | ||
|
|
6c6c3a5081 | ||
|
|
d420cb38d1 | ||
|
|
b55f8215ec | ||
|
|
08caf4bbde | ||
|
|
59c928acc2 | ||
|
|
e38e8c740f | ||
|
|
4ceab4abc7 | ||
|
|
8ff48c126a | ||
|
|
6da3af5e89 | ||
|
|
77c362af8d | ||
|
|
2cf0dc2cb2 | ||
|
|
bdb67d4909 | ||
|
|
4fe72ebf69 | ||
|
|
49fdf8427a | ||
|
|
534bc83173 | ||
|
|
87f6d7da11 | ||
|
|
cdd341af64 | ||
|
|
f70252f013 | ||
|
|
ed989ecc8d | ||
|
|
a147015e96 | ||
|
|
8cf7fb7f80 | ||
|
|
c317149a08 | ||
|
|
ff8b25a50a | ||
|
|
afa539368f | ||
|
|
dc427d5a2c | ||
|
|
a87b5f757d | ||
|
|
4db57cc0bb | ||
|
|
44f0242157 | ||
|
|
e5b3f27a30 | ||
|
|
a15984b663 | ||
|
|
f7fecdc6de | ||
|
|
cabefa4fff | ||
|
|
1ec97e5199 | ||
|
|
458d15063d | ||
|
|
e8786b0747 | ||
|
|
d0bcd1d87c | ||
|
|
c8bd9fd6cc | ||
|
|
4c59e48cc2 | ||
|
|
85a463faab | ||
|
|
feca2871eb | ||
|
|
144c703c7b | ||
|
|
ae6cae0771 | ||
|
|
2b99b64ec5 | ||
|
|
ffe1407217 | ||
|
|
7d8519f5f0 | ||
|
|
b79f04493d | ||
|
|
7e7d9457ea | ||
|
|
07fdf6491c | ||
|
|
fb4bb7f53e | ||
|
|
1da1849de6 | ||
|
|
98dccb8641 | ||
|
|
8a38991270 | ||
|
|
2fe58461d5 | ||
|
|
16cd27282f | ||
|
|
e081a5c5a0 | ||
|
|
0ea01f24a8 | ||
|
|
882980ada7 | ||
|
|
66f7a2be15 | ||
|
|
908b2d151f | ||
|
|
d3bc52278d | ||
|
|
012d1378d4 | ||
|
|
4da31291d2 | ||
|
|
c1e94e61d0 | ||
|
|
ab79348af5 | ||
|
|
d83e24572a | ||
|
|
1ffcea1952 | ||
|
|
35f40b7312 | ||
|
|
b76449d151 | ||
|
|
15546dd84e | ||
|
|
ca3405afc5 | ||
|
|
36ebfc747a | ||
|
|
bc328cbed7 | ||
|
|
7ae81a2195 | ||
|
|
cf98a16db0 | ||
|
|
f813b4c58f | ||
|
|
c5635f9c89 | ||
|
|
d932653c7f | ||
|
|
39aca0f038 | ||
|
|
9943b9a226 | ||
|
|
3bb20dbf2e | ||
|
|
7a8b3c419b | ||
|
|
60e7c6d150 | ||
|
|
a9aaa5ad73 | ||
|
|
6c1fee736b | ||
|
|
f81d2595f9 | ||
|
|
1896bd0920 | ||
|
|
183f32390c | ||
|
|
455948ad14 | ||
|
|
0918063c55 | ||
|
|
22c001c8a6 | ||
|
|
d15b0bf4c4 | ||
|
|
01a910fedc | ||
|
|
8c05067f88 | ||
|
|
f67563e9ee | ||
|
|
d0841919ea | ||
|
|
a23e60ab69 | ||
|
|
ab30297d02 | ||
|
|
3362d6bc56 | ||
|
|
e5f391ab53 | ||
|
|
19a5e425cf | ||
|
|
69d0e82453 | ||
|
|
f84737d7d4 | ||
|
|
0ee0ea554d | ||
|
|
40845578c6 | ||
|
|
f4e22e49b6 | ||
|
|
8a2af9b818 | ||
|
|
255901ca7c | ||
|
|
52644bb28a | ||
|
|
7cad3c89d3 | ||
|
|
bcdddfe4e8 | ||
|
|
c4ca1444f9 | ||
|
|
f5565d4814 | ||
|
|
f20ee6b482 | ||
|
|
6c8d084664 | ||
|
|
412e7bcdae | ||
|
|
3b65fc0107 | ||
|
|
5792a16222 | ||
|
|
6a9f451091 | ||
|
|
a559d59d80 | ||
|
|
de20a8930e | ||
|
|
9343b0378d | ||
|
|
3fabd2ea1b | ||
|
|
5de69b288f | ||
|
|
5eea02b17a | ||
|
|
5c0812ab6f | ||
|
|
5af3fe93f2 | ||
|
|
ee400df930 | ||
|
|
09b8401324 | ||
|
|
be1fb13162 | ||
|
|
aa83dc15e2 | ||
|
|
7c482064df | ||
|
|
c93a3ce227 | ||
|
|
03c10ef885 | ||
|
|
cc1ed98fc4 | ||
|
|
ebf0bd5fc9 | ||
|
|
be48caf59f | ||
|
|
c0cf0cb802 | ||
|
|
3d60d0dfa5 | ||
|
|
b68df56b03 | ||
|
|
6fbba13ab3 | ||
|
|
311624beaa | ||
|
|
ca5099f53b | ||
|
|
5877e5e11a | ||
|
|
69eb62c09f | ||
|
|
ec36e28368 | ||
|
|
4da56b65ab | ||
|
|
71febeb71f | ||
|
|
a292aedd9c | ||
|
|
b58e605b99 | ||
|
|
7776803890 | ||
|
|
cd23ab9955 | ||
|
|
aa32459bc2 | ||
|
|
41a0995db7 | ||
|
|
3f9f0679ec | ||
|
|
d1145ed3fb | ||
|
|
f074c1eaff | ||
|
|
ea566fff24 | ||
|
|
b8cb5e0367 | ||
|
|
7a87c900ee | ||
|
|
e95170e9fd | ||
|
|
d0dead0a08 | ||
|
|
71d718a6e2 | ||
|
|
ad94f99d57 | ||
|
|
bcaaedf2ff | ||
|
|
3dc3d363fd | ||
|
|
690a6e1a59 | ||
|
|
eacc46da6d | ||
|
|
0903d5541b | ||
|
|
c19a2e5b45 | ||
|
|
10a764c4f2 | ||
|
|
0a9f705308 | ||
|
|
dabd680d6b | ||
|
|
4522b02925 | ||
|
|
fabaf5cc04 | ||
|
|
f7888886e9 | ||
|
|
dfd5413b10 | ||
|
|
1b341f8000 | ||
|
|
af9b864b83 | ||
|
|
93e424de4c | ||
|
|
e7a0ab76c3 | ||
|
|
d8b90721b3 | ||
|
|
cb5c1bd24d | ||
|
|
af371249f9 | ||
|
|
0dd7fb7361 | ||
|
|
22fd2aed02 | ||
|
|
c433167950 | ||
|
|
e0ffcda32e | ||
|
|
d34ba416a6 | ||
|
|
3d15ee6d74 | ||
|
|
48cf56b69a | ||
|
|
406ee43ae5 | ||
|
|
488165ec73 | ||
|
|
545c39356a | ||
|
|
42db1378e0 | ||
|
|
c35b51a268 | ||
|
|
df1e52e394 | ||
|
|
246b04f904 | ||
|
|
333f9101a0 | ||
|
|
24acea7261 | ||
|
|
08ca72399b | ||
|
|
e29e3416db | ||
|
|
83ce40191c | ||
|
|
7c06b5cc22 | ||
|
|
3b8e478a6a | ||
|
|
9498c78576 | ||
|
|
746e203f7b | ||
|
|
a7d7f31e76 | ||
|
|
16847fdb41 | ||
|
|
28e7f0f74f | ||
|
|
80d757b371 | ||
|
|
5bdf0cd136 | ||
|
|
e498503428 | ||
|
|
26f70a5fd7 | ||
|
|
ef46b23250 | ||
|
|
39ccf1526f | ||
|
|
12889a9509 | ||
|
|
c24935b519 | ||
|
|
3693473f40 | ||
|
|
2cb83cf19d | ||
|
|
8c02a7bd6b | ||
|
|
8ee0e5d11f | ||
|
|
c87b425639 | ||
|
|
e320bd025f | ||
|
|
d465c445fc | ||
|
|
dc30b9d37b | ||
|
|
37cfe2a3cb | ||
|
|
26abce647d | ||
|
|
ca84ef38f8 | ||
|
|
78fe588330 | ||
|
|
ddf72fa53f | ||
|
|
3a6e8a535c | ||
|
|
d882af9f94 | ||
|
|
48539c851e | ||
|
|
a701bba839 | ||
|
|
c7ba60162b | ||
|
|
d4e98cd9bc | ||
|
|
05ec24e7b8 | ||
|
|
e44ef7f823 | ||
|
|
04ff97cd72 | ||
|
|
8e6fdf62fb | ||
|
|
74d7a946a7 | ||
|
|
2b58b6b5d7 | ||
|
|
7ee290cc57 | ||
|
|
3868a796a4 | ||
|
|
b99ea80b58 | ||
|
|
ce2ae31950 | ||
|
|
f355f36d09 | ||
|
|
5aa11b4578 | ||
|
|
c48da9b5cf | ||
|
|
12d65bfdfa | ||
|
|
cba471b09b | ||
|
|
f1b897b3de | ||
|
|
0589134006 | ||
|
|
6ed36e01ac | ||
|
|
25d93d1041 | ||
|
|
e28c9b3309 | ||
|
|
5335a6b636 | ||
|
|
f83d5f4280 | ||
|
|
28ec6b4d60 | ||
|
|
27a0ef7ee8 | ||
|
|
5eab5dc47b | ||
|
|
2ec5bc77d7 | ||
|
|
2f3587ee8a | ||
|
|
9ece45caa5 | ||
|
|
f163ceffd0 | ||
|
|
31de9faaf2 | ||
|
|
d302c82c82 | ||
|
|
6fa5e681aa | ||
|
|
e631940d9e | ||
|
|
e22e20fa9d | ||
|
|
79c8556927 | ||
|
|
7d16307db4 | ||
|
|
1626982a3a | ||
|
|
6beb9be42c | ||
|
|
bf41eb824d | ||
|
|
38f4cfb7a2 | ||
|
|
aca9d3965d | ||
|
|
4cc06ad779 | ||
|
|
79d56f779d | ||
|
|
280f9befae | ||
|
|
201f50b121 | ||
|
|
1cfa523f49 | ||
|
|
548ee47aa7 | ||
|
|
55448de92a | ||
|
|
b63471ebe9 | ||
|
|
33395d530d | ||
|
|
fcd3af30ec | ||
|
|
e334107c7d | ||
|
|
f5eb54e595 | ||
|
|
56c3dd3652 | ||
|
|
6ddd458402 | ||
|
|
ee328667d0 | ||
|
|
bc2bc1f2ac | ||
|
|
3dee75603c | ||
|
|
c7e3ed096f | ||
|
|
62fe5cdbaa | ||
|
|
10f66fa78f | ||
|
|
0cbc493113 | ||
|
|
c30c9fbca9 | ||
|
|
f4fd3f48f0 | ||
|
|
4ee9e48e7c | ||
|
|
55fab0493d | ||
|
|
22c4e605cf | ||
|
|
67737b1556 | ||
|
|
cdfd3449ed | ||
|
|
fab1062c0b | ||
|
|
766b9d5270 | ||
|
|
023fa2b2cc | ||
|
|
8910351f5c | ||
|
|
1b42e3015e | ||
|
|
4e9e18d4c0 | ||
|
|
ba5b127684 | ||
|
|
225e7a6a32 | ||
|
|
7e9963ae05 | ||
|
|
b7c0f3ea95 | ||
|
|
a8e2610d7d | ||
|
|
b934ace1fc | ||
|
|
82cbfc9905 | ||
|
|
9f294e3565 | ||
|
|
68775182f0 | ||
|
|
dc3e172eb4 | ||
|
|
5bd128ba85 | ||
|
|
1a8579cd6d | ||
|
|
5921bb0589 | ||
|
|
c8e894e8f8 | ||
|
|
141f22bedf | ||
|
|
d9844350fe | ||
|
|
2d9d11a89c | ||
|
|
4fa92198a0 | ||
|
|
662430d5db | ||
|
|
139b19f9ac | ||
|
|
6e50e2412e | ||
|
|
005e14a060 | ||
|
|
c8c9e0a7e7 | ||
|
|
0f65cb2b79 | ||
|
|
85094fc74d | ||
|
|
5227dc679d | ||
|
|
77c510c364 | ||
|
|
2d2ad8b237 | ||
|
|
6ea00a4f7c | ||
|
|
1bb0530c69 | ||
|
|
b36f644628 | ||
|
|
2dee9c8d74 | ||
|
|
9c6eb7736f | ||
|
|
e86dfcf55c | ||
|
|
d6311aefb7 | ||
|
|
8e18f2c5d2 | ||
|
|
0644bfe27c | ||
|
|
0b285845d1 | ||
|
|
d3ff4bf75e | ||
|
|
aa4ac9fa05 | ||
|
|
0339a5ad01 | ||
|
|
bffb217d37 | ||
|
|
40f85e5ca3 | ||
|
|
2dba2f4a95 | ||
|
|
70542fb730 | ||
|
|
cd742979b1 | ||
|
|
736d58e35f | ||
|
|
64138bd424 | ||
|
|
f51d74fa68 | ||
|
|
78c6ce842e | ||
|
|
ad79df9b74 | ||
|
|
b4763290de | ||
|
|
8264c76642 | ||
|
|
6edd6c8f03 | ||
|
|
f1bc87133d | ||
|
|
dd7a13930f | ||
|
|
8ad10149ab | ||
|
|
0731064375 | ||
|
|
e194461420 | ||
|
|
b97b23647e | ||
|
|
7bdeceff36 | ||
|
|
45c69fa638 | ||
|
|
d7f3869959 | ||
|
|
cdc36dd171 | ||
|
|
ed16914715 | ||
|
|
a1d66d98dc | ||
|
|
dd3295da60 | ||
|
|
282aaa5cf0 | ||
|
|
462a939438 | ||
|
|
030f902ca5 | ||
|
|
58093941c0 | ||
|
|
005271d24b | ||
|
|
2b263bcb5d | ||
|
|
79d0f47ee7 | ||
|
|
1ebb18ae57 | ||
|
|
fad4875f11 | ||
|
|
42d1205260 | ||
|
|
3d90340446 | ||
|
|
d68e1fd308 | ||
|
|
217d5df276 | ||
|
|
d1ccf83236 | ||
|
|
28968144d6 | ||
|
|
4c5cfd51d7 | ||
|
|
b6044910ec | ||
|
|
5aa90eb086 | ||
|
|
ce58486850 | ||
|
|
7e63978a3f | ||
|
|
c9674f84e8 | ||
|
|
0697274695 | ||
|
|
654d1f939e | ||
|
|
477b876a1f | ||
|
|
523cf21b4a | ||
|
|
df0a5cf52f | ||
|
|
caa6337952 | ||
|
|
700a3f9f84 | ||
|
|
f9b13791de | ||
|
|
7886318341 | ||
|
|
3c13901695 | ||
|
|
573632012e | ||
|
|
002455da07 | ||
|
|
e9e6ac64bd | ||
|
|
36ab8ae19c | ||
|
|
df366da721 | ||
|
|
67dc761344 | ||
|
|
0b4552a8e7 | ||
|
|
2345b41a74 | ||
|
|
141e395489 | ||
|
|
91139672cc | ||
|
|
3d178c8eb6 | ||
|
|
c9bd45ba13 | ||
|
|
db9c288050 | ||
|
|
f1cb8f2f25 | ||
|
|
7ec2c09249 | ||
|
|
354bfcea15 | ||
|
|
891d7c134c | ||
|
|
eb5822bc7c | ||
|
|
154d70e4e2 | ||
|
|
c4a0fe0234 | ||
|
|
0011beb654 | ||
|
|
419251ed35 | ||
|
|
bd850d8158 | ||
|
|
d7c7f27207 | ||
|
|
0fb95297a2 | ||
|
|
cf1f43dc9d | ||
|
|
d6935847b4 | ||
|
|
0715ba3e5e | ||
|
|
efbbb31370 | ||
|
|
207c1a20ee | ||
|
|
579bc1c2c8 | ||
|
|
bd4cb549d6 | ||
|
|
fd392a2422 | ||
|
|
13864853a8 | ||
|
|
d86b2c4fb4 | ||
|
|
a1f103576a | ||
|
|
aa766e3e18 | ||
|
|
ee0e4d2b69 | ||
|
|
8eb3e48bc7 | ||
|
|
384292b647 | ||
|
|
1bb1ddcd29 | ||
|
|
24324939e1 | ||
|
|
2436cda7ac | ||
|
|
75b83af08f | ||
|
|
82d8e3c2b6 | ||
|
|
c351f46e47 | ||
|
|
fb9e8d2166 | ||
|
|
3668cb6dd4 | ||
|
|
93f3e30cac | ||
|
|
52af346ec8 | ||
|
|
8e0bba4f99 | ||
|
|
4cc61d10ff | ||
|
|
8deb6d9246 | ||
|
|
20eb6df9e8 | ||
|
|
a921eeb5e2 | ||
|
|
f3f34e1835 | ||
|
|
4a29d459da | ||
|
|
0f867a3484 | ||
|
|
6eeddaa564 | ||
|
|
d80458ef81 | ||
|
|
ad15df7222 | ||
|
|
98f7febed1 | ||
|
|
4f04eaec3a | ||
|
|
5a2b9b1f44 | ||
|
|
721b37a08e | ||
|
|
b3d494d4c8 | ||
|
|
85ec70e92b | ||
|
|
e2f0ff9e88 | ||
|
|
0dbd7d0e17 | ||
|
|
8cdaa044e1 | ||
|
|
712a420217 | ||
|
|
b38dc70c71 | ||
|
|
72d9fcdcb4 | ||
|
|
5a6981e7af | ||
|
|
79d29db18b | ||
|
|
4f6a52503d | ||
|
|
1b5c40dd1f | ||
|
|
700b77c450 | ||
|
|
8449017592 | ||
|
|
5cf3425b93 | ||
|
|
aa13a80d83 | ||
|
|
9e2ef543ed | ||
|
|
2aabb387b1 | ||
|
|
f972863f49 | ||
|
|
f00320c8b9 | ||
|
|
1f57cf08a7 | ||
|
|
0ff5ff5dbe | ||
|
|
5ba19144d5 | ||
|
|
c9ba856c52 | ||
|
|
a30ceefa6b | ||
|
|
31e2a8b8e9 | ||
|
|
9b4150509c | ||
|
|
c68cd7d19a | ||
|
|
85382dc2e0 | ||
|
|
7315a0ecec | ||
|
|
411bd55cd4 | ||
|
|
9c0141e84e | ||
|
|
ca5d0496ee | ||
|
|
24b9bc1e55 | ||
|
|
cf1e167430 | ||
|
|
a1afd2328d | ||
|
|
ada9bfcae8 | ||
|
|
f88588db90 | ||
|
|
5930dc6354 | ||
|
|
9c64da4323 | ||
|
|
c863ea4aa1 | ||
|
|
e1432f4339 | ||
|
|
890c527ae5 | ||
|
|
1fa8b74595 | ||
|
|
5559ad1238 | ||
|
|
bd8f5e9bfd | ||
|
|
29f6283eab | ||
|
|
396f53d20e | ||
|
|
4a69de1f30 | ||
|
|
bd6e2d6ca4 | ||
|
|
fc78e42a78 | ||
|
|
9d1906d333 | ||
|
|
4a3f50cef7 | ||
|
|
4751e4b94e | ||
|
|
1b7f4f31ca | ||
|
|
ca01604b43 | ||
|
|
93f9a0c39c | ||
|
|
93977316ce | ||
|
|
7e49bdf5a8 | ||
|
|
df0bc7bbc4 | ||
|
|
63b50ab9b1 | ||
|
|
c0beef7572 | ||
|
|
5ec448861d | ||
|
|
7d4326a397 | ||
|
|
cc43b94864 | ||
|
|
57a31828f8 | ||
|
|
0c7fccdcbe | ||
|
|
a1fcd3c5b6 | ||
|
|
c4048f8f22 | ||
|
|
15dc30edf6 | ||
|
|
4254aa5f5a | ||
|
|
09ff042986 | ||
|
|
924ecce2c3 | ||
|
|
69daede583 | ||
|
|
a6e8d61e8e | ||
|
|
65a7fa320a | ||
|
|
be5e6d55fc | ||
|
|
b0c01369c5 | ||
|
|
f6772bb896 | ||
|
|
b21fa2daa0 | ||
|
|
730d4857ba | ||
|
|
0e1c12e65f | ||
|
|
37b125ca98 | ||
|
|
2e9303cb6c | ||
|
|
7db38c80fc | ||
|
|
aad824a562 | ||
|
|
f0087c93b8 | ||
|
|
ae7e7e9656 | ||
|
|
e008473e47 | ||
|
|
79313aa268 | ||
|
|
1c35d4b26b | ||
|
|
a56f657fb1 | ||
|
|
f5db9950f8 | ||
|
|
e5931e264b | ||
|
|
9485e8cfee | ||
|
|
22b139d9f8 | ||
|
|
2a600b25e7 | ||
|
|
393891d6ea | ||
|
|
1bbd056797 | ||
|
|
add5bb47d5 | ||
|
|
305f8d6982 | ||
|
|
93851a9a0f | ||
|
|
8a184e9d30 | ||
|
|
3a66d7c453 | ||
|
|
00a479de6f | ||
|
|
32f9f8fcce | ||
|
|
e4208441b3 | ||
|
|
ee5ebe2e81 | ||
|
|
a71b681e80 | ||
|
|
2cbc62d6c0 | ||
|
|
cc125f5fd7 | ||
|
|
7f9c8a1935 | ||
|
|
3c54d14460 | ||
|
|
c5b39a5100 | ||
|
|
7888c1c614 | ||
|
|
b43315c36d | ||
|
|
fbd6417c8a | ||
|
|
850ad1c0fb | ||
|
|
dbe35bfed1 | ||
|
|
f1caae126e | ||
|
|
bad6a40a12 | ||
|
|
5bc194e1f0 | ||
|
|
d315ff2b96 | ||
|
|
163b45cf37 | ||
|
|
87c718f549 | ||
|
|
e04678f33c | ||
|
|
bbdf75bdfa | ||
|
|
5c0cf9f5d7 | ||
|
|
8a61ec4b4e | ||
|
|
874a6e86fd | ||
|
|
ef4bec1c6d | ||
|
|
4da99d14e6 | ||
|
|
cc80191cd1 | ||
|
|
3cdb3f0d54 | ||
|
|
437b957be1 | ||
|
|
9f17e4ee2c | ||
|
|
509c3dc715 | ||
|
|
4051f04e66 | ||
|
|
d503c5d83d | ||
|
|
02a37d670c | ||
|
|
a7deca1df5 | ||
|
|
1bec6c2aae | ||
|
|
a66825c71f | ||
|
|
0fb110a4af | ||
|
|
167c02d773 | ||
|
|
0c50a7437b | ||
|
|
5339ec66b7 | ||
|
|
2371dcf694 | ||
|
|
65bc194c42 | ||
|
|
99ee38cea3 | ||
|
|
5d8a51c307 | ||
|
|
6325635fce | ||
|
|
7612e47aee | ||
|
|
d06b9401ea | ||
|
|
ecb1552c10 | ||
|
|
9f066d01b1 | ||
|
|
673ae1edc0 | ||
|
|
b25b31e4a0 | ||
|
|
f65fde8bb7 | ||
|
|
0a04b135ca | ||
|
|
88d27fe649 | ||
|
|
5d166dc8cb | ||
|
|
8f81c97aaa | ||
|
|
b5f35261a0 | ||
|
|
f55e24cd12 | ||
|
|
efc0b60d41 | ||
|
|
f3bc726001 | ||
|
|
60e797ccc4 | ||
|
|
20b553461b | ||
|
|
0bff097afb | ||
|
|
b0cb6d6d4c | ||
|
|
b345c7cf46 | ||
|
|
56e2082205 | ||
|
|
fe2d8f1ea0 | ||
|
|
e16bbc660d | ||
|
|
2676f24e0a | ||
|
|
b8e6fcfeae | ||
|
|
b5f18561ab | ||
|
|
22c3ec2d63 | ||
|
|
b678daa744 | ||
|
|
e1433ebb41 | ||
|
|
1b83742e3e | ||
|
|
90cca93951 | ||
|
|
4e37290a7f | ||
|
|
7d3146ed8d | ||
|
|
0a1af65a4c | ||
|
|
4de9ac133a | ||
|
|
60c7bfe9a7 | ||
|
|
9bafc4fea1 | ||
|
|
7387f2e490 | ||
|
|
93b4f3fac8 | ||
|
|
fdeeb73587 | ||
|
|
6062930f9a | ||
|
|
867b838053 | ||
|
|
58dc282ca0 | ||
|
|
d7ee7cb88f | ||
|
|
da9c792ca2 | ||
|
|
8171cd51c4 | ||
|
|
74b10a42ee | ||
|
|
f14ef22bb6 | ||
|
|
e8c9b0806a | ||
|
|
36c4d01ef8 | ||
|
|
e51d403420 | ||
|
|
f54615ed46 | ||
|
|
4c1b6f3059 | ||
|
|
ada641090f | ||
|
|
eb6c8a3521 | ||
|
|
3a021a87a1 | ||
|
|
5100339604 | ||
|
|
8448e3970b | ||
|
|
dbed679904 | ||
|
|
acb5340ffb | ||
|
|
6a01cd56ca | ||
|
|
ae38705bed | ||
|
|
db083c43dd | ||
|
|
c5435596ad | ||
|
|
03130e1217 | ||
|
|
2ca6acc1e9 | ||
|
|
d8f68eb118 | ||
|
|
97697b93ed | ||
|
|
152b484eb5 | ||
|
|
97de8c1cc2 | ||
|
|
6cf46b1635 | ||
|
|
1665cb4282 | ||
|
|
1113081aab | ||
|
|
39bc3cb532 | ||
|
|
0a0a0776e4 | ||
|
|
59d199a148 | ||
|
|
8b9d13491f | ||
|
|
4dcd2ceb01 | ||
|
|
6004ba6554 | ||
|
|
f1847d4501 | ||
|
|
e63ff167a7 | ||
|
|
a27186e34f | ||
|
|
2a8904f844 | ||
|
|
59fc72d37e | ||
|
|
34e3683ded | ||
|
|
13760b1bdd | ||
|
|
8a252774ce | ||
|
|
963f9fdf40 | ||
|
|
b4a2b96e32 | ||
|
|
299a2457cd | ||
|
|
3de4707c98 | ||
|
|
603ec65e91 | ||
|
|
cdcffcd31e | ||
|
|
f8a1c7c8a1 | ||
|
|
5d64568f3e | ||
|
|
374fbad06d | ||
|
|
aa31336c64 | ||
|
|
135ba68ff5 | ||
|
|
d3ee81bb5a | ||
|
|
e0b585779d | ||
|
|
4729bea1a2 | ||
|
|
e1393f9780 | ||
|
|
ad7e66cdae | ||
|
|
2f09ef2970 | ||
|
|
6ea2c08ecb | ||
|
|
b82f1edd63 | ||
|
|
1685e7cea4 | ||
|
|
287d8ca367 | ||
|
|
6397b8c1ef | ||
|
|
89eedd59a8 | ||
|
|
af65a81d5b | ||
|
|
03e2f25adb | ||
|
|
aa9093bcf6 | ||
|
|
dc4f347ae1 | ||
|
|
23599814a3 | ||
|
|
89ce1a5159 | ||
|
|
22a4ef42fc | ||
|
|
358ba395ac | ||
|
|
e7d5ea8a6c | ||
|
|
a36711e640 | ||
|
|
2b6df412b7 | ||
|
|
6fabff4769 | ||
|
|
6af86152e6 | ||
|
|
06d97c78c8 | ||
|
|
da31fffb16 | ||
|
|
c97e3ec7ae | ||
|
|
09b3433e32 | ||
|
|
323e84375b | ||
|
|
3b67a6a222 | ||
|
|
da3d5375b8 | ||
|
|
38bd0d1aec | ||
|
|
59bd029e46 | ||
|
|
1dbf0ad976 | ||
|
|
3b4c095b49 | ||
|
|
2e155bdeda | ||
|
|
8305fd0451 | ||
|
|
7477667df1 | ||
|
|
a066d7ddcb | ||
|
|
a5c742cee5 | ||
|
|
cac142b134 | ||
|
|
da7ae2b0ab | ||
|
|
052c9aca15 | ||
|
|
e4fecb48e3 | ||
|
|
b0e975bfce | ||
|
|
d4664507f1 | ||
|
|
21f3f859b9 | ||
|
|
54be4c5e2c | ||
|
|
45cdbe0a18 | ||
|
|
6c76e9728e | ||
|
|
0a6a3f9ab7 | ||
|
|
bad8ab232d | ||
|
|
91a814d295 | ||
|
|
7205cf8ce1 | ||
|
|
6fe6a33da3 | ||
|
|
9b59fc1c94 | ||
|
|
e7834b885a | ||
|
|
4ec6691ea9 | ||
|
|
6b9b08da30 | ||
|
|
184307816f | ||
|
|
c1d592b72c | ||
|
|
2d23251da9 | ||
|
|
5b01e9ec97 | ||
|
|
8526230b59 | ||
|
|
9d04a4c4f0 | ||
|
|
ae93f2b936 | ||
|
|
fcaecf4782 | ||
|
|
0b28db7fae | ||
|
|
87715d6231 | ||
|
|
3228c4f41a | ||
|
|
ce5b4089b5 | ||
|
|
0903aa4596 | ||
|
|
26a45c8dc0 | ||
|
|
62c908a905 | ||
|
|
eb8c2d9053 | ||
|
|
1e2e4ba3ad | ||
|
|
aaf4b1a399 | ||
|
|
a5e3d7a94b | ||
|
|
58497ed596 | ||
|
|
ae81fbdffe | ||
|
|
fc0705e87c | ||
|
|
c489d806dc | ||
|
|
f3ecdc5af4 | ||
|
|
6fecb4bf3e | ||
|
|
867ac5df67 | ||
|
|
1ff3c3be84 | ||
|
|
1cb9de07a6 | ||
|
|
43ca50ebbe | ||
|
|
b70b730cb9 | ||
|
|
dbc1a9cf82 | ||
|
|
c95a991cb3 | ||
|
|
c320e9d583 | ||
|
|
e507afc3d5 | ||
|
|
bd77fd92bb | ||
|
|
882a988143 | ||
|
|
0b3e33e226 | ||
|
|
524f5d45ec | ||
|
|
85887ad1cf | ||
|
|
d94b6635af | ||
|
|
3c7a483f5c | ||
|
|
dc5c3a3939 | ||
|
|
9185c94a2d | ||
|
|
70269c8196 | ||
|
|
51a589f5a6 | ||
|
|
cf89b565a6 | ||
|
|
7d24c5fda2 | ||
|
|
0bc85d27f8 | ||
|
|
43c2ca2d7d | ||
|
|
e3e21a251f | ||
|
|
267417d6a8 | ||
|
|
e8256f0ad7 | ||
|
|
458e6da700 | ||
|
|
a906fa178a | ||
|
|
4588c5a19a | ||
|
|
23404decea | ||
|
|
e873574e8c | ||
|
|
d09bff9039 | ||
|
|
c0da52aac8 | ||
|
|
7e2f653bc7 | ||
|
|
c831369974 | ||
|
|
f0a13b2a0d | ||
|
|
b68987dcde | ||
|
|
c1f77eeaea | ||
|
|
9b5a0a54cf | ||
|
|
14f3a68215 | ||
|
|
bf25b9f443 | ||
|
|
3435aaea45 | ||
|
|
9fc91b7aa1 | ||
|
|
04eefb8480 | ||
|
|
8789be7671 | ||
|
|
fe46410c31 | ||
|
|
aef644bd21 | ||
|
|
df4d5ea8a6 | ||
|
|
c34c3ac845 | ||
|
|
4bb656b704 | ||
|
|
a94720878b | ||
|
|
59a2042a31 | ||
|
|
f680c15283 | ||
|
|
f11785001c | ||
|
|
106fe4854f | ||
|
|
44d377b810 | ||
|
|
a2bf3e056d | ||
|
|
2d722e26de | ||
|
|
182e079d25 | ||
|
|
318af9b418 | ||
|
|
0bcda4a2eb | ||
|
|
0dc0e03c4c | ||
|
|
0db2d07a1a | ||
|
|
3d52095765 | ||
|
|
0912cec0e5 | ||
|
|
180ba33ac8 | ||
|
|
04f4454974 | ||
|
|
91285baea5 | ||
|
|
875d80aa72 | ||
|
|
5e19fdb492 | ||
|
|
bddcc6491a | ||
|
|
d37e18fdcf | ||
|
|
af8d12124a | ||
|
|
5e34823e7c | ||
|
|
f44eaae88a | ||
|
|
3cc69112c1 | ||
|
|
205d4232b9 | ||
|
|
3c6a06a327 | ||
|
|
057b533a39 | ||
|
|
b774b91b92 | ||
|
|
7dc923a292 | ||
|
|
ef2094f817 | ||
|
|
f0f791d226 | ||
|
|
7ca261e33e | ||
|
|
228aac2d48 | ||
|
|
d0b744387b | ||
|
|
7cadb9012a | ||
|
|
0c222c4e8c | ||
|
|
83052352dc | ||
|
|
73516c0c97 | ||
|
|
b90e4057ba | ||
|
|
67f253830f | ||
|
|
59dbe45784 | ||
|
|
f053b41645 | ||
|
|
84615ad299 | ||
|
|
2e291d73aa | ||
|
|
055efa3904 | ||
|
|
daee7970f3 | ||
|
|
2dc8fcd3be | ||
|
|
2f55c18d56 | ||
|
|
cf0748895e | ||
|
|
6e66b8a0fa | ||
|
|
e70b99a706 | ||
|
|
42e7a70d99 | ||
|
|
ee85eb2779 | ||
|
|
6c1adf9187 | ||
|
|
81a660eae4 | ||
|
|
8b029388a5 | ||
|
|
c816ed2527 | ||
|
|
866ea7f942 | ||
|
|
d9d3da4def | ||
|
|
be6cb24e10 | ||
|
|
1a63d9eb3b | ||
|
|
bf98cfeadc | ||
|
|
8a39b32b5c | ||
|
|
7d2646f60a | ||
|
|
1a8bc1dd60 | ||
|
|
7e434fc019 | ||
|
|
49d57cf596 | ||
|
|
8dfbc55851 | ||
|
|
3cbfe21b2c | ||
|
|
cb7424ce5e | ||
|
|
a567939f78 | ||
|
|
a3748d4b97 | ||
|
|
b80dc92ca5 | ||
|
|
57dee76c88 | ||
|
|
2513639499 | ||
|
|
9ae6ac25f5 | ||
|
|
01ec8d0bcb | ||
|
|
d09e8a12b4 | ||
|
|
5dd64b97d2 | ||
|
|
9600b1f103 | ||
|
|
ca9861e749 | ||
|
|
38bf07f4da | ||
|
|
189796891e | ||
|
|
8134905a86 | ||
|
|
45fb760a35 | ||
|
|
026fffa19f | ||
|
|
9da5ef3cbf | ||
|
|
ea7fe0c761 | ||
|
|
25d7b8d08d | ||
|
|
f467cb8cd2 | ||
|
|
f4e3c0a2e4 | ||
|
|
9cdf0601eb | ||
|
|
28ef972c9f | ||
|
|
c66476f6b6 | ||
|
|
3f90220208 | ||
|
|
81ebaae12e | ||
|
|
71984b25e9 | ||
|
|
4100c9881a | ||
|
|
075d01820c | ||
|
|
6f43cbf665 | ||
|
|
866f48f92d | ||
|
|
2790e4e819 | ||
|
|
8bb2b5e290 | ||
|
|
63290d0f5d | ||
|
|
5c55617585 | ||
|
|
0e0caabf7d | ||
|
|
024a319512 | ||
|
|
f632b3b029 | ||
|
|
b37f9a7db0 | ||
|
|
6f9c306260 | ||
|
|
c369350ca7 | ||
|
|
bc3c394210 | ||
|
|
e9df31b650 | ||
|
|
e49bb1ccc0 | ||
|
|
0ef8e086a2 | ||
|
|
63665dccae | ||
|
|
792b194d0e | ||
|
|
e694a74c9d | ||
|
|
9de016bfe3 | ||
|
|
3eddfc028e | ||
|
|
2125648798 | ||
|
|
24bff6e04d | ||
|
|
cdab0d208e | ||
|
|
20f04ab352 | ||
|
|
7f1af24318 | ||
|
|
8d87db58c6 | ||
|
|
feae4c6c8b | ||
|
|
00c89b8354 | ||
|
|
fb767f5680 | ||
|
|
c7d22aafd2 | ||
|
|
b5f237a69b | ||
|
|
b4093ccf59 | ||
|
|
a23217cc6f | ||
|
|
f4f7f47901 | ||
|
|
2f68687de9 | ||
|
|
86f4907cc4 | ||
|
|
bffb795d7a | ||
|
|
c21cffa6d4 | ||
|
|
96b0e70ddd | ||
|
|
febe56b062 | ||
|
|
f5e6722826 | ||
|
|
cea13b1823 | ||
|
|
3d85e85f29 | ||
|
|
923df8244b | ||
|
|
69db9e0d45 | ||
|
|
d1534d4dcf | ||
|
|
a8a94ef87b | ||
|
|
f93215f4ec | ||
|
|
9af460600d | ||
|
|
e1576b7131 | ||
|
|
5d05de8bda | ||
|
|
5e949b0564 | ||
|
|
2a52d9bdf6 | ||
|
|
ebf49d0668 | ||
|
|
f42955ab99 | ||
|
|
5d516592d9 | ||
|
|
7dc2b36413 | ||
|
|
5eefa36111 | ||
|
|
c26209d579 | ||
|
|
a30f73fe36 | ||
|
|
1a9c52e17f | ||
|
|
5ad38ee9f8 | ||
|
|
4c79591403 | ||
|
|
a9812167d7 | ||
|
|
a7cc36f741 | ||
|
|
4c0262cbd0 | ||
|
|
a0a98cb035 | ||
|
|
4fccfbf543 | ||
|
|
62ae80eeae | ||
|
|
d705108be5 | ||
|
|
3912eb7b26 | ||
|
|
1f959272c5 | ||
|
|
f9cd942363 | ||
|
|
1282da52eb | ||
|
|
10c099a52d | ||
|
|
fa0542ca8b | ||
|
|
3926226417 | ||
|
|
6a30511fc4 | ||
|
|
4ffa26cf2c | ||
|
|
1ad10914ce | ||
|
|
86ed85aa6e | ||
|
|
b7de847236 | ||
|
|
3cf2cd4684 | ||
|
|
2b95cd5081 | ||
|
|
8f45324bce | ||
|
|
5545cdbf4d | ||
|
|
9dec50832d | ||
|
|
64973f1d57 | ||
|
|
d7bfb727b0 | ||
|
|
37ad58c69e | ||
|
|
de753bf330 | ||
|
|
d17f8538b2 | ||
|
|
1900c81d9f | ||
|
|
9db6f82628 | ||
|
|
d96a6a59ee | ||
|
|
7535677ed4 | ||
|
|
6488324cf1 | ||
|
|
812e4c7cd4 | ||
|
|
85baae1ebd | ||
|
|
8174b9f041 | ||
|
|
fb9e91e486 | ||
|
|
1429737a60 | ||
|
|
286b4c0e46 | ||
|
|
166a3c4d64 | ||
|
|
d4a701aad0 | ||
|
|
47bf1bd21a | ||
|
|
852f9bd277 | ||
|
|
555cbeffa5 | ||
|
|
3d4d822528 | ||
|
|
c238130842 | ||
|
|
76e9ebde36 | ||
|
|
0688050552 | ||
|
|
9023171940 | ||
|
|
84371f03b5 | ||
|
|
20407bca89 | ||
|
|
96af2debfc | ||
|
|
6e532231dc | ||
|
|
dceec44671 | ||
|
|
0b5f40e66c | ||
|
|
da832368f0 | ||
|
|
abac8bccc6 | ||
|
|
82061c7c3b | ||
|
|
ec3a684be2 | ||
|
|
5572588c54 | ||
|
|
a8197df1c1 | ||
|
|
005e1e002b | ||
|
|
9603dce469 | ||
|
|
13190f6f15 | ||
|
|
eaa061d90c | ||
|
|
1ab374008f | ||
|
|
8c9d551826 | ||
|
|
c4c3f9dc1f | ||
|
|
5b722deb39 | ||
|
|
b61b7f0c3b | ||
|
|
3c40310e9b | ||
|
|
7a167742d0 | ||
|
|
d2a798eb3d | ||
|
|
3e9e34afb8 | ||
|
|
26d8a041ef | ||
|
|
7c25edc7b2 | ||
|
|
2725053c82 | ||
|
|
e2cb66f8d7 | ||
|
|
fad1d4cf98 | ||
|
|
daf64421f2 | ||
|
|
fa3329271d | ||
|
|
fdcb4473af | ||
|
|
41154d6d11 | ||
|
|
9904d01958 | ||
|
|
171ed497f9 | ||
|
|
212a8ad6a6 | ||
|
|
f2c518ba24 | ||
|
|
f8b61a4ebe | ||
|
|
35cc3837a0 | ||
|
|
572a80d1d1 | ||
|
|
2aa695fb66 | ||
|
|
f361f324da | ||
|
|
3999a3caa2 | ||
|
|
efc3def7f2 | ||
|
|
6c304924f7 | ||
|
|
f90714f8fe | ||
|
|
0960360b35 | ||
|
|
8db47e335f | ||
|
|
c609f67e16 | ||
|
|
14cb2b0143 | ||
|
|
b24c539206 | ||
|
|
52eeefa6d9 | ||
|
|
f942ec952e | ||
|
|
3e9aca3ed4 | ||
|
|
2d832e10b0 | ||
|
|
f1e995ec79 | ||
|
|
756ec8ccd7 | ||
|
|
c48f24d269 | ||
|
|
0d2e13549a | ||
|
|
f9ce9bdcec | ||
|
|
e339dbf473 | ||
|
|
f27f028d44 | ||
|
|
697aaf7e70 | ||
|
|
cc1e3d0101 | ||
|
|
9daa3997e9 | ||
|
|
83930ec9d1 | ||
|
|
b83a1bf4cc | ||
|
|
668b47cc6e | ||
|
|
f29471521c | ||
|
|
5beced458c | ||
|
|
ead451a979 | ||
|
|
97d42991a7 | ||
|
|
cd6bdc1a78 | ||
|
|
977f538420 | ||
|
|
590b155c6c | ||
|
|
7e9f11ea1c | ||
|
|
64cee145e0 | ||
|
|
525724cc1f | ||
|
|
63f9dc826f | ||
|
|
b3bda02063 | ||
|
|
df1d56e7b1 | ||
|
|
b80adcc00a | ||
|
|
68a7c3fa3b | ||
|
|
d099d8950f | ||
|
|
ae7093e0bb | ||
|
|
d932a877e8 | ||
|
|
745a7b4461 | ||
|
|
9e1a9723c2 | ||
|
|
e48754c73c | ||
|
|
096a554bfb | ||
|
|
74da5a610c | ||
|
|
ea7c6edcd0 | ||
|
|
27d5f02329 | ||
|
|
d56e7787f2 | ||
|
|
6d7c8431be | ||
|
|
3ed63d09d9 | ||
|
|
4b4299604b | ||
|
|
3842bcb921 | ||
|
|
f9b98767e7 | ||
|
|
6989c6332d | ||
|
|
209e9ebda7 | ||
|
|
e27e9dc2aa | ||
|
|
28474d9340 | ||
|
|
aa89416bca | ||
|
|
6c04ee1abd | ||
|
|
e93fba206d | ||
|
|
822a689b82 | ||
|
|
ffbf70af25 | ||
|
|
d3e307b102 | ||
|
|
a3e4abfd5e | ||
|
|
56d1411253 | ||
|
|
7bccd17bbe | ||
|
|
c193208cd2 | ||
|
|
923f9345a7 | ||
|
|
d618526037 | ||
|
|
a1dcd5f069 | ||
|
|
3dfa28570f | ||
|
|
d78c9fa2d2 | ||
|
|
6fac241404 | ||
|
|
99bb9d4fcf | ||
|
|
d19e101e6b | ||
|
|
13c70ac02c | ||
|
|
3405e44a1d | ||
|
|
8c5a28c0b8 | ||
|
|
7229c59b8e | ||
|
|
14884d5a2b | ||
|
|
688ed405df | ||
|
|
d3c79c9b49 | ||
|
|
de0f04ec3c | ||
|
|
c61b22cefb | ||
|
|
24dfa55465 | ||
|
|
d25624a8ad | ||
|
|
41f1e5f7c9 | ||
|
|
be3f657073 | ||
|
|
7e44a8ed1d | ||
|
|
874503ca68 | ||
|
|
29c833d623 | ||
|
|
46c0215b1f | ||
|
|
7c6e49ec65 | ||
|
|
9a142cea7a | ||
|
|
7b911aea46 | ||
|
|
af95daadf4 | ||
|
|
6e8d5cd873 | ||
|
|
48686cf9f7 | ||
|
|
b7fc3059b6 | ||
|
|
64ce5e0fad | ||
|
|
d815d06c1c | ||
|
|
c0c8465ec2 | ||
|
|
364d9de751 | ||
|
|
ca5e8c73d7 | ||
|
|
3e0c66edab | ||
|
|
e74be5887c | ||
|
|
253d0c834c | ||
|
|
feb19adb8f | ||
|
|
5d69c69b7c | ||
|
|
06077faa6a | ||
|
|
fcc369e854 | ||
|
|
ea187961da | ||
|
|
c9b2cec5ff | ||
|
|
960a4f71a3 | ||
|
|
292db86c9e | ||
|
|
6d3b36d61b | ||
|
|
c876aa537a | ||
|
|
f1e5238e16 | ||
|
|
d75d4a5c08 | ||
|
|
266fe876ba | ||
|
|
ca53ae4fc5 | ||
|
|
8f35683ccb | ||
|
|
30cd782e92 | ||
|
|
3d37c9c9a3 | ||
|
|
7072af7c14 | ||
|
|
c72bddf15e | ||
|
|
74ea266157 | ||
|
|
235bbc9c7e | ||
|
|
abd7c15ba8 | ||
|
|
a4ff1e4f33 | ||
|
|
5b9ea96dc5 | ||
|
|
269441fe3d | ||
|
|
00f76ecaf6 | ||
|
|
952a69abca | ||
|
|
aa21bfd8a8 | ||
|
|
5768762591 | ||
|
|
ca9c11486e | ||
|
|
01d9849e44 | ||
|
|
0339026674 | ||
|
|
2f5115ca45 | ||
|
|
66878a9b48 | ||
|
|
333952a231 | ||
|
|
50281f12b9 | ||
|
|
4f8cea6e2d | ||
|
|
1c6b7203cc | ||
|
|
bf5081ec8c | ||
|
|
4f7587492d | ||
|
|
9a9c9b2b12 | ||
|
|
d4432ddd64 | ||
|
|
5c2d49f7ce | ||
|
|
28ccd63255 | ||
|
|
0dc263d919 | ||
|
|
3de041a411 | ||
|
|
00f5f8b2a0 | ||
|
|
95f1343a59 | ||
|
|
b4115b0362 | ||
|
|
6ee0f2c6a7 | ||
|
|
af39e4de3e | ||
|
|
4a6b5274bc | ||
|
|
f7ea420a3f | ||
|
|
56d5b0b12a | ||
|
|
bb81248eaa | ||
|
|
0e18eafcfb | ||
|
|
c138f390ac | ||
|
|
a16c63a43e | ||
|
|
9e21a089d2 | ||
|
|
3105215425 | ||
|
|
e916f93787 | ||
|
|
1332ddbc93 | ||
|
|
b30dfcf28a | ||
|
|
b9cfade18c | ||
|
|
ad1fa110ff | ||
|
|
ed49962120 | ||
|
|
0651f134e4 | ||
|
|
16fa5c4df3 | ||
|
|
2f849be9d8 | ||
|
|
6c49ab932e | ||
|
|
dc9c2773cb | ||
|
|
60eec49e95 | ||
|
|
f784551e20 | ||
|
|
a3d9169930 | ||
|
|
e87502285b | ||
|
|
caccacf52b | ||
|
|
5aee981590 | ||
|
|
e6d09b3266 | ||
|
|
8fcaa4997d | ||
|
|
7370af9a82 | ||
|
|
e4baef94bc | ||
|
|
8c05f9cf3e | ||
|
|
ebcab0f26e | ||
|
|
14996bd08b | ||
|
|
dd9fb9d526 | ||
|
|
f3ffed673b | ||
|
|
5b342dd229 | ||
|
|
e626bbf415 | ||
|
|
04795709a3 | ||
|
|
745162c589 | ||
|
|
089508db8e | ||
|
|
a912323d01 | ||
|
|
511a592ec8 | ||
|
|
d132d3abfd | ||
|
|
fb9b5e4274 | ||
|
|
8dcc5645db | ||
|
|
c6798892b8 | ||
|
|
eea5b026ce | ||
|
|
331e858ed3 | ||
|
|
3d602a2558 | ||
|
|
14386a2f62 | ||
|
|
4e91e05470 | ||
|
|
ea0bec8bf2 | ||
|
|
c2e8a1d733 | ||
|
|
c6155723a1 | ||
|
|
8c64afc81e | ||
|
|
eafd1d8c53 | ||
|
|
df0673f907 | ||
|
|
fe093c6385 | ||
|
|
ed536f18ee | ||
|
|
96590f591c | ||
|
|
32bfcbcdbc | ||
|
|
82feeff3aa | ||
|
|
3af451caeb | ||
|
|
ae953f2420 | ||
|
|
43ef9f909a | ||
|
|
4f42dae3cb | ||
|
|
e01c68dcea | ||
|
|
234d1291f9 | ||
|
|
90169d6a05 | ||
|
|
809562c874 | ||
|
|
be7a3a0940 | ||
|
|
1ea0b5371a | ||
|
|
74932e6311 | ||
|
|
b0b96aa410 | ||
|
|
deedd166db | ||
|
|
6ffab821b2 | ||
|
|
e53c8100a3 | ||
|
|
6705902a94 | ||
|
|
fd96e30c9c | ||
|
|
2b59724ea8 | ||
|
|
aa4d6d6f0f | ||
|
|
ca65671553 | ||
|
|
2d99308219 | ||
|
|
a4be75f410 | ||
|
|
4439545428 | ||
|
|
835fd383ad | ||
|
|
dfd1bff389 | ||
|
|
e53c1e39d3 | ||
|
|
775e044e69 | ||
|
|
6a697eed2f | ||
|
|
134819cb45 | ||
|
|
88ce05976e | ||
|
|
93b8287d23 | ||
|
|
b64c550989 | ||
|
|
9d25d2674b | ||
|
|
5a160f426e | ||
|
|
6d6af09296 | ||
|
|
ab54971763 | ||
|
|
d75f96fdd5 | ||
|
|
024c112944 | ||
|
|
3242354a4b | ||
|
|
4ac652b127 | ||
|
|
6088f83408 | ||
|
|
e92f2ecea1 | ||
|
|
a82aa8203b | ||
|
|
2c7e807738 | ||
|
|
2724cf5db8 | ||
|
|
0ffcce1b5d | ||
|
|
444807c35b | ||
|
|
c3a5822a40 | ||
|
|
57c78bc603 | ||
|
|
f76374cd8f | ||
|
|
eb88a53223 | ||
|
|
76c18e50a4 | ||
|
|
2dbb370955 | ||
|
|
0b05f88543 | ||
|
|
e395211654 | ||
|
|
b01b121a4b |
@@ -1,6 +1,6 @@
|
||||
[run]
|
||||
init_cmds = [
|
||||
["go", "build", "-o", "./bin/grafana-server"],
|
||||
["go", "build", "-o", "./bin/grafana-server", "./pkg/cmd/grafana-server"],
|
||||
["./bin/grafana-server"]
|
||||
]
|
||||
watch_all = true
|
||||
@@ -9,9 +9,9 @@ watch_dirs = [
|
||||
"$WORKDIR/public/views",
|
||||
"$WORKDIR/conf",
|
||||
]
|
||||
watch_exts = [".go", "conf/*"]
|
||||
watch_exts = [".go", ".ini", ".toml", ".html"]
|
||||
build_delay = 1500
|
||||
cmds = [
|
||||
["go", "build", "-o", "./bin/grafana-server"],
|
||||
["go", "build", "-o", "./bin/grafana-server", "./pkg/cmd/grafana-server"],
|
||||
["./bin/grafana-server"]
|
||||
]
|
||||
|
||||
19
.editorconfig
Normal file
19
.editorconfig
Normal file
@@ -0,0 +1,19 @@
|
||||
# http://editorconfig.org
|
||||
root = true
|
||||
|
||||
[*.go]
|
||||
indent_style = tabs
|
||||
indent_size = 2
|
||||
charset = utf-8
|
||||
trim_trailing_whitespace = true
|
||||
insert_final_newline = true
|
||||
|
||||
[*]
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
charset = utf-8
|
||||
trim_trailing_whitespace = true
|
||||
insert_final_newline = true
|
||||
|
||||
[*.md]
|
||||
trim_trailing_whitespace = false
|
||||
22
.github/CONTRIBUTING.md
vendored
Normal file
22
.github/CONTRIBUTING.md
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
Follow the setup guide in README.md
|
||||
|
||||
### Rebuild frontend assets on source change
|
||||
```
|
||||
grunt && grunt watch
|
||||
```
|
||||
|
||||
### Rerun tests on source change
|
||||
```
|
||||
grunt karma:dev
|
||||
```
|
||||
|
||||
### Run tests for backend assets before commit
|
||||
```
|
||||
test -z "$(gofmt -s -l . | grep -v Godeps/_workspace/src/ | tee /dev/stderr)"
|
||||
```
|
||||
|
||||
### Run tests for frontend assets before commit
|
||||
```
|
||||
grunt test
|
||||
godep go test -v ./pkg/...
|
||||
```
|
||||
12
.github/ISSUE_TEMPLATE.md
vendored
Normal file
12
.github/ISSUE_TEMPLATE.md
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
Thank you! For helping us make Grafana even better.
|
||||
|
||||
To help us respond to your issues faster, please make sure to add as much information as possible.
|
||||
|
||||
If this issue is about a plugin, please open the issue in that repository.
|
||||
|
||||
Start your issues title with [Feature Request] / [Bug] / [Question] or no tag if your unsure.
|
||||
|
||||
Ex
|
||||
* What grafana version are you using?
|
||||
* What datasource are you using?
|
||||
* What OS are you running grafana on?
|
||||
2
.github/PULL_REQUEST_TEMPLATE.md
vendored
Normal file
2
.github/PULL_REQUEST_TEMPLATE.md
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
* Link the PR to an issue for new features
|
||||
* Rebase your PR if it gets out of sync with master
|
||||
12
.gitignore
vendored
12
.gitignore
vendored
@@ -1,9 +1,14 @@
|
||||
node_modules
|
||||
npm-debug.log
|
||||
coverage/
|
||||
.aws-config.json
|
||||
awsconfig
|
||||
/dist
|
||||
/emails/dist
|
||||
/public_gen
|
||||
/public/vendor/npm
|
||||
/tmp
|
||||
vendor/phantomjs/phantomjs
|
||||
|
||||
docs/AWS_S3_BUCKET
|
||||
docs/GIT_BRANCH
|
||||
@@ -26,5 +31,10 @@ public/css/*.min.css
|
||||
|
||||
conf/custom.ini
|
||||
fig.yml
|
||||
docker-compose.yml
|
||||
profile.cov
|
||||
|
||||
/grafana
|
||||
.notouch
|
||||
/pkg/cmd/grafana-cli/grafana-cli
|
||||
/pkg/cmd/grafana-server/grafana-server
|
||||
/examples/*/dist
|
||||
@@ -5,3 +5,6 @@ if [ $? -gt 0 ]; then
|
||||
echo "Some files aren't formatted, please run 'go fmt ./pkg/...' to format your source code before committing"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
grunt test
|
||||
|
||||
10
.jshintrc
10
.jshintrc
@@ -4,7 +4,7 @@
|
||||
"bitwise":false,
|
||||
"curly": true,
|
||||
"eqnull": true,
|
||||
"globalstrict": true,
|
||||
"strict": true,
|
||||
"devel": true,
|
||||
"eqeqeq": true,
|
||||
"forin": false,
|
||||
@@ -12,7 +12,7 @@
|
||||
"supernew": true,
|
||||
"expr": true,
|
||||
"indent": 2,
|
||||
"latedef": true,
|
||||
"latedef": false,
|
||||
"newcap": true,
|
||||
"noarg": true,
|
||||
"noempty": true,
|
||||
@@ -23,13 +23,15 @@
|
||||
"laxcomma": true,
|
||||
"sub": true,
|
||||
"unused": true,
|
||||
"maxdepth": 5,
|
||||
"maxdepth": 6,
|
||||
"maxlen": 140,
|
||||
|
||||
"globals": {
|
||||
"System": true,
|
||||
"Promise": true,
|
||||
"define": true,
|
||||
"require": true,
|
||||
"Chromath": false,
|
||||
"setImmediate": true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
158
CHANGELOG.md
158
CHANGELOG.md
@@ -1,10 +1,159 @@
|
||||
# 2.1.2 (unreleased)
|
||||
# 3.0.0 (unrelased master branch)
|
||||
|
||||
### New Features
|
||||
* **Playlists**: Playlists can now be persisted and started from urls, closes [#3655](https://github.com/grafana/grafana/issues/3655)
|
||||
* **Metadata**: Settings panel now shows dashboard metadata, closes [#3304](https://github.com/grafana/grafana/issues/3304)
|
||||
* **InfluxDB**: Support for policy selection in query editor, closes [#2018](https://github.com/grafana/grafana/issues/2018)
|
||||
* **Snapshots UI**: Dashboard snapshots list can be managed through UI, closes[#1984](https://github.com/grafana/grafana/issues/1984)
|
||||
* **Prometheus**: Prometheus annotation support, closes[#2883](https://github.com/grafana/grafana/pull/2883)
|
||||
* **Cli**: New cli tool for downloading and updating plugins
|
||||
* **Annotations**: Annotations can now contain links that can be clicked (you can navigate on to annotation popovers), closes [#1588](https://github.com/grafana/grafana/issues/1588)
|
||||
* **Opentsdb**: Opentsdb 2.2 filters support, closes[#3077](https://github.com/grafana/grafana/issues/3077)
|
||||
|
||||
### Breaking changes
|
||||
* **Plugin API**: Both datasource and panel plugin api (and plugin.json schema) have been updated, requiring an update to plugins. See [plugin api](https://github.com/grafana/grafana/blob/master/public/app/plugins/plugin_api.md) for more info.
|
||||
* **InfluxDB 0.8.x** The data source for the old version of influxdb (0.8.x) is no longer included in default builds, but can easily be installed via improved plugin system, closes [#3523](https://github.com/grafana/grafana/issues/3523)
|
||||
* **KairosDB** The data source is no longer included in default builds, but can easily be installed via improved plugin system, closes [#3524](https://github.com/grafana/grafana/issues/3524)
|
||||
* **Templating**: Templating value formats (glob/regex/pipe etc) are now handled automatically and not specified by the user, this makes variable values possible to reuse in many contexts. It can in some edge cases break existing dashboards that have template variables that do not reload on dashboard load. To fix any issue just go into template variable options and update the variable (so it's values are reloaded.).
|
||||
|
||||
### Enhancements
|
||||
* **LDAP**: Support for nested LDAP Groups, closes [#4401](https://github.com/grafana/grafana/issues/4401), [#3808](https://github.com/grafana/grafana/issues/3808)
|
||||
* **Sessions**: Support for memcached as session storage, closes [#3458](https://github.com/grafana/grafana/issues/3458)
|
||||
* **mysql**: Grafana now supports ssl for mysql, closes [#3584](https://github.com/grafana/grafana/issues/3584)
|
||||
* **snapshot**: Annotations are now included in snapshots, closes [#3635](https://github.com/grafana/grafana/issues/3635)
|
||||
* **Admin**: Admin can now have global overview of Grafana setup, closes [#3812](https://github.com/grafana/grafana/issues/3812)
|
||||
* **graph**: Right side legend height is now fixed at row height, closes [#1277](https://github.com/grafana/grafana/issues/1277)
|
||||
* **Table**: All content in table panel is now html escaped, closes [#3673](https://github.com/grafana/grafana/issues/3673)
|
||||
* **graph**: Template variables can now be used in TimeShift and TimeFrom, closes[#1960](https://github.com/grafana/grafana/issues/1960)
|
||||
* **Tooltip**: Optionally add milliseconds to timestamp in tool tip, closes[#2248](https://github.com/grafana/grafana/issues/2248)
|
||||
* **Opentsdb**: Support milliseconds when using openTSDB datasource, closes [#2865](https://github.com/grafana/grafana/issues/2865)
|
||||
* **Opentsdb**: Add support for annotations, closes[#664](https://github.com/grafana/grafana/issues/664)
|
||||
|
||||
### Bug fixes
|
||||
* **Playlist**: Fix for memory leak when running a playlist, closes [#3794](https://github.com/grafana/grafana/pull/3794)
|
||||
* **InfluxDB**: Fix for InfluxDB and table panel when using Format As Table and having group by time, fixes [#3928](https://github.com/grafana/grafana/issues/3928)
|
||||
* **Panel Time shift**: Fix for panel time range and using dashboard times liek `Today` and `This Week`, fixes [#3941](https://github.com/grafana/grafana/issues/3941)
|
||||
* **Row repeat**: Repeated rows will now appear next to each other and not by the bottom of the dashboard, fixes [#3942](https://github.com/grafana/grafana/issues/3942)
|
||||
* **Png renderer**: Fix for phantomjs path on windows, fixes [#3657](https://github.com/grafana/grafana/issues/3657)
|
||||
|
||||
# 2.6.1 (unrelased, 2.6.x branch)
|
||||
|
||||
### New Features
|
||||
* **Elasticsearch**: Support for derivative unit option, closes [#3512](https://github.com/grafana/grafana/issues/3512)
|
||||
|
||||
### Bug fixes
|
||||
* **Graph Panel**: Fixed typehead when adding series style override, closes [#3554](https://github.com/grafana/grafana/issues/3554)
|
||||
|
||||
# 2.6.0 (2015-12-14)
|
||||
|
||||
### New Features
|
||||
* **Elasticsearch**: Support for pipeline aggregations Moving average and derivative, closes [#2715](https://github.com/grafana/grafana/issues/2715)
|
||||
* **Elasticsearch**: Support for inline script and missing options for metrics, closes [#3500](https://github.com/grafana/grafana/issues/3500)
|
||||
* **Syslog**: Support for syslog logging, closes [#3161](https://github.com/grafana/grafana/pull/3161)
|
||||
* **Timepicker**: Always show refresh button even with refresh rate, closes [#3498](https://github.com/grafana/grafana/pull/3498)
|
||||
* **Login**: Make it possible to change the login hint on the login page, closes [#2571](https://github.com/grafana/grafana/pull/2571)
|
||||
|
||||
### Bug Fixes
|
||||
* **metric editors**: Fix for clicking typeahead auto dropdown option, fixes [#3428](https://github.com/grafana/grafana/issues/3428)
|
||||
* **influxdb**: Fixed issue showing Group By label only on first query, fixes [#3453](https://github.com/grafana/grafana/issues/3453)
|
||||
* **logging**: Add more verbose info logging for http reqeusts, closes [#3405](https://github.com/grafana/grafana/pull/3405)
|
||||
|
||||
# 2.6.0-Beta1 (2015-12-04)
|
||||
|
||||
### New Table Panel
|
||||
* **table**: New powerful and flexible table panel, closes [#215](https://github.com/grafana/grafana/issues/215)
|
||||
|
||||
### Enhancements
|
||||
* **CloudWatch**: Support for multiple AWS Credentials, closes [#3053](https://github.com/grafana/grafana/issues/3053), [#3080](https://github.com/grafana/grafana/issues/3080)
|
||||
* **Elasticsearch**: Support for dynamic daily indices for annotations, closes [#3061](https://github.com/grafana/grafana/issues/3061)
|
||||
* **Elasticsearch**: Support for setting min_doc_count for date histogram, closes [#3416](https://github.com/grafana/grafana/issues/3416)
|
||||
* **Graph Panel**: Option to hide series with all zeroes from legend and tooltip, closes [#1381](https://github.com/grafana/grafana/issues/1381), [#3336](https://github.com/grafana/grafana/issues/3336)
|
||||
|
||||
### Bug Fixes
|
||||
* **cloudwatch**: fix for handling of period for long time ranges, fixes [#3086](https://github.com/grafana/grafana/issues/3086)
|
||||
* **dashboard**: fix for collapse row by clicking on row title, fixes [#3065](https://github.com/grafana/grafana/issues/3065)
|
||||
* **influxdb**: fix for relative time ranges `last x months` and `last x years`, fixes [#3067](https://github.com/grafana/grafana/issues/3067)
|
||||
* **graph**: layout fix for color picker when right side legend was enabled, fixes [#3093](https://github.com/grafana/grafana/issues/3093)
|
||||
* **elasticsearch**: disabling elastic query (via eye) caused error, fixes [#3300](https://github.com/grafana/grafana/issues/3300)
|
||||
|
||||
### Breaking changes
|
||||
* **elasticsearch**: Manual json edited queries are not supported any more (They very barely worked in 2.5)
|
||||
|
||||
# 2.5 (2015-10-28)
|
||||
|
||||
**New Feature: Mix data sources**
|
||||
- A built in data source is now available named `-- Mixed --`, When picked in the metrics tab,
|
||||
it allows you to add queries of differnet data source types & instances to the same graph/panel!
|
||||
[Issue #436](https://github.com/grafana/grafana/issues/436)
|
||||
|
||||
**New Feature: Elasticsearch Metrics Query Editor and Viz Support**
|
||||
- Feature rich query editor and processing features enables you to issues all kind of metric queries to Elasticsearch
|
||||
- See [Issue #1034](https://github.com/grafana/grafana/issues/1034) for more info.
|
||||
|
||||
**New Feature: New and much improved time picker**
|
||||
- Support for quick ranges like `Today`, `This day last week`, `This week`, `The day so far`, etc.
|
||||
- Improved UI and improved support for UTC, [Issue #2761](https://github.com/grafana/grafana/issues/2761) for more info.
|
||||
|
||||
**User Onboarding**
|
||||
- Org admin can now send email invites (or invite links) to people who are not yet Grafana users
|
||||
- Sign up flow now supports email verification (if enabled)
|
||||
- See [Issue #2353](https://github.com/grafana/grafana/issues/2353) for more info.
|
||||
|
||||
**Other new Features && Enhancements**
|
||||
- [Pull #2720](https://github.com/grafana/grafana/pull/2720). Admin: Initial basic quota support (per Org)
|
||||
- [Issue #2577](https://github.com/grafana/grafana/issues/2577). Panel: Resize handles in panel bottom right corners for easy width and height change
|
||||
- [Issue #2457](https://github.com/grafana/grafana/issues/2457). Admin: admin page for all grafana organizations (list / edit view)
|
||||
- [Issue #1186](https://github.com/grafana/grafana/issues/1186). Time Picker: New option `today`, will set time range from midnight to now
|
||||
- [Issue #2647](https://github.com/grafana/grafana/issues/2647). InfluxDB: You can now set group by time interval on each query
|
||||
- [Issue #2599](https://github.com/grafana/grafana/issues/2599). InfluxDB: Improved alias support, you can now use the `AS` clause for each select statement
|
||||
- [Issue #2708](https://github.com/grafana/grafana/issues/2708). InfluxDB: You can now set math expression for select clauses.
|
||||
- [Issue #1575](https://github.com/grafana/grafana/issues/1575). Drilldown link: now you can click on the external link icon in the panel header to access drilldown links!
|
||||
- [Issue #1646](https://github.com/grafana/grafana/issues/1646). OpenTSDB: Fetch list of aggregators from OpenTSDB
|
||||
- [Issue #2955](https://github.com/grafana/grafana/issues/2955). Graph: More axis units (Length, Volume, Temperature, Pressure, etc), thanks @greglook
|
||||
- [Issue #2928](https://github.com/grafana/grafana/issues/2928). LDAP: Support for searching for groups memberships, i.e. POSIX (no memberOf) schemas, also multiple ldap servers, and root ca cert, thanks @abligh
|
||||
|
||||
**Fixes**
|
||||
- [Issue #2413](https://github.com/grafana/grafana/issues/2413). InfluxDB 0.9: Fix for handling empty series object in response from influxdb
|
||||
- [Issue #2574](https://github.com/grafana/grafana/issues/2574). Snapshot: Fix for snapshot with expire 7 days option, 7 days option not correct, was 7 hours
|
||||
- [Issue #2568](https://github.com/grafana/grafana/issues/2568). AuthProxy: Fix for server side rendering of panel when using auth proxy
|
||||
- [Issue #2490](https://github.com/grafana/grafana/issues/2490). Graphite: Dashboard import was broken in 2.1 and 2.1.1, working now
|
||||
- [Issue #2565](https://github.com/grafana/grafana/issues/2565). TimePicker: Fix for when you applied custom time range it did not refreh dashboard
|
||||
- [Issue #2563](https://github.com/grafana/grafana/issues/2563). Annotations: Fixed issue when html sanitizer failes for title to annotation body, now fallbacks to html escaping title and text
|
||||
- [Issue #2564](https://github.com/grafana/grafana/issues/2564). Templating: Another atempt at fixing #2534 (Init multi value template var used in repeat panel from url)
|
||||
- [Issue #2620](https://github.com/grafana/grafana/issues/2620). Graph: multi series tooltip did no highlight correct point when stacking was enabled and series were of different resolution
|
||||
- [Issue #2636](https://github.com/grafana/grafana/issues/2636). InfluxDB: Do no show template vars in dropdown for tag keys and group by keys
|
||||
- [Issue #2604](https://github.com/grafana/grafana/issues/2604). InfluxDB: More alias options, can now use `$[0-9]` syntax to reference part of a measurement name (seperated by dots)
|
||||
|
||||
**Breaking Changes**
|
||||
- Notice to makers/users of custom data sources, there is a minor breaking change in 2.2 that
|
||||
require an update to custom data sources for them to work in 2.2. [Read this doc](https://github.com/grafana/grafana/tree/master/docs/sources/datasources/plugin_api.md) for more on the
|
||||
data source api change.
|
||||
- Data source api changes, [PLUGIN_CHANGES.md](https://github.com/grafana/grafana/blob/master/public/app/plugins/PLUGIN_CHANGES.md)
|
||||
- The duplicate query function used in data source editors is changed, and moveMetricQuery function was renamed
|
||||
|
||||
**Tech (Note for devs)**
|
||||
Started using Typescript (transpiled to ES5), uncompiled typescript files and less files are in public folder (in source tree)
|
||||
This folder is never modified by build steps. Compiled css and javascript files are put in public_gen, all other files
|
||||
that do not undergo transformation are just copied from public to public_gen, it is public_gen that is used by grafana-server
|
||||
if it is found.
|
||||
|
||||
Grunt & Watch tasks:
|
||||
- `grunt` : default task, will remove public_gen, copy over all files from public, do less & typescript compilation
|
||||
- `grunt watch`: will watch for changes to less, and typescript files and compile them to public_gen, and for other files it will just copy them to public_gen
|
||||
|
||||
|
||||
# 2.1.3 (2015-08-24)
|
||||
|
||||
**Fixes**
|
||||
- [Issue #2580](https://github.com/grafana/grafana/issues/2580). Packaging: ldap.toml was not marked as config file and could be overwritten in upgrade
|
||||
- [Issue #2564](https://github.com/grafana/grafana/issues/2564). Templating: Another atempt at fixing #2534 (Init multi value template var used in repeat panel from url)
|
||||
|
||||
# 2.1.2 (2015-08-20)
|
||||
|
||||
**Fixes**
|
||||
- [Issue #2558](https://github.com/grafana/grafana/issues/2558). DragDrop: Fix for broken drag drop behavior
|
||||
- [Issue #2534](https://github.com/grafana/grafana/issues/2534). Templating: fix for setting template variable value via url and having repeated panels or rows
|
||||
|
||||
|
||||
# 2.1.1 (2015-08-11)
|
||||
|
||||
**Fixes**
|
||||
@@ -14,6 +163,7 @@
|
||||
- [Issue #2460](https://github.com/grafana/grafana/issues/2460). SinglestatPanel: Fix to handle series with no data points
|
||||
- [Issue #2461](https://github.com/grafana/grafana/issues/2461). LDAP: Fix for ldap users with empty email address
|
||||
- [Issue #2484](https://github.com/grafana/grafana/issues/2484). Graphite: Fix bug when using series ref (#A-Z) and referenced series is hidden in query editor.
|
||||
- [Issue #1896](https://github.com/grafana/grafana/issues/1896). Postgres: Dashboard search is now case insensitive when using Postgres
|
||||
|
||||
**Enhancements**
|
||||
- [Issue #2477](https://github.com/grafana/grafana/issues/2477). InfluxDB(0.9): Added more condition operators (`<`, `>`, `<>`, `!~`), thx @thuck
|
||||
@@ -124,6 +274,10 @@
|
||||
|
||||
# 2.0.0-Beta1 (2015-03-30)
|
||||
|
||||
**Important Note**
|
||||
|
||||
Grafana 2.x is fundamentally different from 1.x; it now ships with an integrated backend server. Please read the [Documentation](http://docs.grafana.org) for more detailed about this SIGNIFCANT change to Grafana
|
||||
|
||||
**New features**
|
||||
- [Issue #1623](https://github.com/grafana/grafana/issues/1623). Share Dashboard: Dashboard snapshot sharing (dash and data snapshot), save to local or save to public snapshot dashboard snapshots.raintank.io site
|
||||
- [Issue #1622](https://github.com/grafana/grafana/issues/1622). Share Panel: The share modal now has an embed option, gives you an iframe that you can use to embedd a single graph on another web site
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
If you have any idea for an improvement or found a bug do not hesitate to open an issue.
|
||||
And if you have time clone this repo and submit a pull request and help me make Grafana the
|
||||
kickass metrics & devops dashboard we all dream about!
|
||||
|
||||
Prerequisites:
|
||||
- Nodejs (for jshint & grunt & development server)
|
||||
|
||||
Clone repository:
|
||||
|
||||
npm install
|
||||
grunt server (starts development web server in src folder)
|
||||
grunt (runs jshint and less -> css compilation)
|
||||
|
||||
Please remember to run grunt before doing pull request to verify that your code passes all the jshint validations.
|
||||
268
Godeps/Godeps.json
generated
268
Godeps/Godeps.json
generated
@@ -1,6 +1,7 @@
|
||||
{
|
||||
"ImportPath": "github.com/grafana/grafana",
|
||||
"GoVersion": "go1.4.2",
|
||||
"GoVersion": "go1.5.1",
|
||||
"GodepVersion": "v60",
|
||||
"Packages": [
|
||||
"./pkg/..."
|
||||
],
|
||||
@@ -15,52 +16,263 @@
|
||||
"Rev": "d9bcf409c8a368d06c9b347705c381e7c12d54df"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/Unknwon/macaron",
|
||||
"Rev": "93de4f3fad97bf246b838f828e2348f46f21f20a"
|
||||
"ImportPath": "github.com/aws/aws-sdk-go/aws",
|
||||
"Comment": "v1.0.0",
|
||||
"Rev": "abb928e07c4108683d6b4d0b6ca08fe6bc0eee5f"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/aws/aws-sdk-go/aws/awserr",
|
||||
"Comment": "v1.0.0",
|
||||
"Rev": "abb928e07c4108683d6b4d0b6ca08fe6bc0eee5f"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/aws/aws-sdk-go/aws/awsutil",
|
||||
"Comment": "v1.0.0",
|
||||
"Rev": "abb928e07c4108683d6b4d0b6ca08fe6bc0eee5f"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/aws/aws-sdk-go/aws/client",
|
||||
"Comment": "v1.0.0",
|
||||
"Rev": "abb928e07c4108683d6b4d0b6ca08fe6bc0eee5f"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/aws/aws-sdk-go/aws/client/metadata",
|
||||
"Comment": "v1.0.0",
|
||||
"Rev": "abb928e07c4108683d6b4d0b6ca08fe6bc0eee5f"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/aws/aws-sdk-go/aws/corehandlers",
|
||||
"Comment": "v1.0.0",
|
||||
"Rev": "abb928e07c4108683d6b4d0b6ca08fe6bc0eee5f"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/aws/aws-sdk-go/aws/credentials",
|
||||
"Comment": "v1.0.0",
|
||||
"Rev": "abb928e07c4108683d6b4d0b6ca08fe6bc0eee5f"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/aws/aws-sdk-go/aws/credentials/ec2rolecreds",
|
||||
"Comment": "v1.0.0",
|
||||
"Rev": "abb928e07c4108683d6b4d0b6ca08fe6bc0eee5f"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/aws/aws-sdk-go/aws/defaults",
|
||||
"Comment": "v1.0.0",
|
||||
"Rev": "abb928e07c4108683d6b4d0b6ca08fe6bc0eee5f"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/aws/aws-sdk-go/aws/ec2metadata",
|
||||
"Comment": "v1.0.0",
|
||||
"Rev": "abb928e07c4108683d6b4d0b6ca08fe6bc0eee5f"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/aws/aws-sdk-go/aws/request",
|
||||
"Comment": "v1.0.0",
|
||||
"Rev": "abb928e07c4108683d6b4d0b6ca08fe6bc0eee5f"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/aws/aws-sdk-go/aws/session",
|
||||
"Comment": "v1.0.0",
|
||||
"Rev": "abb928e07c4108683d6b4d0b6ca08fe6bc0eee5f"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/aws/aws-sdk-go/private/endpoints",
|
||||
"Comment": "v1.0.0",
|
||||
"Rev": "abb928e07c4108683d6b4d0b6ca08fe6bc0eee5f"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/aws/aws-sdk-go/private/protocol/ec2query",
|
||||
"Comment": "v1.0.0",
|
||||
"Rev": "abb928e07c4108683d6b4d0b6ca08fe6bc0eee5f"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/aws/aws-sdk-go/private/protocol/query",
|
||||
"Comment": "v1.0.0",
|
||||
"Rev": "abb928e07c4108683d6b4d0b6ca08fe6bc0eee5f"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/aws/aws-sdk-go/private/protocol/query/queryutil",
|
||||
"Comment": "v1.0.0",
|
||||
"Rev": "abb928e07c4108683d6b4d0b6ca08fe6bc0eee5f"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/aws/aws-sdk-go/private/protocol/rest",
|
||||
"Comment": "v1.0.0",
|
||||
"Rev": "abb928e07c4108683d6b4d0b6ca08fe6bc0eee5f"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/aws/aws-sdk-go/private/protocol/xml/xmlutil",
|
||||
"Comment": "v1.0.0",
|
||||
"Rev": "abb928e07c4108683d6b4d0b6ca08fe6bc0eee5f"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/aws/aws-sdk-go/private/signer/v4",
|
||||
"Comment": "v1.0.0",
|
||||
"Rev": "abb928e07c4108683d6b4d0b6ca08fe6bc0eee5f"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/aws/aws-sdk-go/private/waiter",
|
||||
"Comment": "v1.0.0",
|
||||
"Rev": "abb928e07c4108683d6b4d0b6ca08fe6bc0eee5f"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/aws/aws-sdk-go/service/cloudwatch",
|
||||
"Comment": "v1.0.0",
|
||||
"Rev": "abb928e07c4108683d6b4d0b6ca08fe6bc0eee5f"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/aws/aws-sdk-go/service/ec2",
|
||||
"Comment": "v1.0.0",
|
||||
"Rev": "abb928e07c4108683d6b4d0b6ca08fe6bc0eee5f"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/bmizerany/assert",
|
||||
"Comment": "release.r60-6-ge17e998",
|
||||
"Rev": "e17e99893cb6509f428e1728281c2ad60a6b31e3"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/bradfitz/gomemcache/memcache",
|
||||
"Comment": "release.r60-40-g72a6864",
|
||||
"Rev": "72a68649ba712ee7c4b5b4a943a626bcd7d90eb8"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/codegangsta/cli",
|
||||
"Comment": "1.2.0-187-gc31a797",
|
||||
"Rev": "c31a7975863e7810c92e2e288a9ab074f9a88f29"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/davecgh/go-spew/spew",
|
||||
"Rev": "2df174808ee097f90d259e432cc04442cf60be21"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/fatih/color",
|
||||
"Comment": "v0.1-16-g4f7bcef",
|
||||
"Rev": "4f7bcef27eec7925456d0c30c5e7b0408b3339be"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/franela/goreq",
|
||||
"Rev": "3ddeded65be21dacb5a2e2d0b95af9ff6862a2b5"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/go-ini/ini",
|
||||
"Comment": "v0-48-g060d7da",
|
||||
"Rev": "060d7da055ba6ec5ea7a31f116332fe5efa04ce0"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/go-ldap/ldap",
|
||||
"Comment": "v1-19-g83e6542",
|
||||
"Rev": "83e65426fd1c06626e88aa8a085e5bfed0208e29"
|
||||
"Comment": "v2.2.1",
|
||||
"Rev": "07a7330929b9ee80495c88a4439657d89c7dbd87"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/go-macaron/binding",
|
||||
"Rev": "2502aaf4bce3a4e6451b4610847bfb8dffdb6266"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/go-macaron/gzip",
|
||||
"Rev": "4938e9be6b279d8426cb1c89a6bcf7af70b0c21d"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/go-macaron/inject",
|
||||
"Rev": "c5ab7bf3a307593cd44cb272d1a5beea473dd072"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/go-macaron/session",
|
||||
"Rev": "66031fcb37a0fff002a1f028eb0b3a815c78306b"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/go-macaron/session/memcache",
|
||||
"Rev": "66031fcb37a0fff002a1f028eb0b3a815c78306b"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/go-macaron/session/mysql",
|
||||
"Rev": "66031fcb37a0fff002a1f028eb0b3a815c78306b"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/go-macaron/session/postgres",
|
||||
"Rev": "66031fcb37a0fff002a1f028eb0b3a815c78306b"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/go-macaron/session/redis",
|
||||
"Rev": "66031fcb37a0fff002a1f028eb0b3a815c78306b"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/go-sql-driver/mysql",
|
||||
"Comment": "v1.2-26-g9543750",
|
||||
"Rev": "9543750295406ef070f7de8ae9c43ccddd44e15e"
|
||||
"Comment": "v1.2-171-g267b128",
|
||||
"Rev": "267b128680c46286b9ca13475c3cca5de8f79bd7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/go-xorm/core",
|
||||
"Rev": "be6e7ac47dc57bd0ada25322fa526944f66ccaa6"
|
||||
"Comment": "v0.4.4-7-g9e608f7",
|
||||
"Rev": "9e608f7330b9d16fe2818cfe731128b3f156cb9a"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/go-xorm/xorm",
|
||||
"Comment": "v0.4.2-58-ge2889e5",
|
||||
"Rev": "e2889e5517600b82905f1d2ba8b70deb71823ffe"
|
||||
"Comment": "v0.4.4-44-gf561133",
|
||||
"Rev": "f56113384f2c63dfe4cd8e768e349f1c35122b58"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/gorilla/websocket",
|
||||
"Rev": "c45a635370221f34fea2d5163fd156fcb4e38e8a"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/gosimple/slug",
|
||||
"Rev": "8d258463b4459f161f51d6a357edacd3eef9d663"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/hashicorp/go-version",
|
||||
"Rev": "7e3c02b30806fa5779d3bdfc152ce4c6f40e7b38"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/jmespath/go-jmespath",
|
||||
"Comment": "0.2.2",
|
||||
"Rev": "3433f3ea46d9f8019119e7dd41274e112a2359a9"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/jtolds/gls",
|
||||
"Rev": "f1ac7f4f24f50328e6bc838ca4437d1612a0243c"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/klauspost/compress/flate",
|
||||
"Rev": "7b02889a2005228347aef0e76beeaee564d82f8c"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/klauspost/compress/gzip",
|
||||
"Rev": "7b02889a2005228347aef0e76beeaee564d82f8c"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/klauspost/cpuid",
|
||||
"Rev": "349c675778172472f5e8f3a3e0fe187e302e5a10"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/klauspost/crc32",
|
||||
"Rev": "6834731faf32e62a2dd809d99fb24d1e4ae5a92d"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/kr/pretty",
|
||||
"Comment": "go.weekly.2011-12-22-27-ge6ac2fc",
|
||||
"Rev": "e6ac2fc51e89a3249e82157fa0bb7a18ef9dd5bb"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/kr/text",
|
||||
"Rev": "bb797dc4fb8320488f47bf11de07a733d7233e1f"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/lib/pq",
|
||||
"Comment": "go1.0-cutoff-13-g19eeca3",
|
||||
"Rev": "19eeca3e30d2577b1761db471ec130810e67f532"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/macaron-contrib/binding",
|
||||
"Rev": "0fbe4b9707e6eb556ef843e5471592f55ce0a5e7"
|
||||
"ImportPath": "github.com/lib/pq/oid",
|
||||
"Comment": "go1.0-cutoff-13-g19eeca3",
|
||||
"Rev": "19eeca3e30d2577b1761db471ec130810e67f532"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/macaron-contrib/session",
|
||||
"Rev": "31e841d95c7302b9ac456c830ea2d6dfcef4f84a"
|
||||
"ImportPath": "github.com/mattn/go-colorable",
|
||||
"Rev": "9cbef7c35391cca05f15f8181dc0b18bc9736dbb"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/mattn/go-isatty",
|
||||
"Rev": "56b76bdf51f7708750eac80fa38b952bb9f32639"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/mattn/go-sqlite3",
|
||||
@@ -75,6 +287,26 @@
|
||||
"Comment": "1.5.0-356-gfbc0a1c",
|
||||
"Rev": "fbc0a1c888f9f96263f9a559d1769905245f1123"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/smartystreets/goconvey/convey/assertions",
|
||||
"Comment": "1.5.0-356-gfbc0a1c",
|
||||
"Rev": "fbc0a1c888f9f96263f9a559d1769905245f1123"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/smartystreets/goconvey/convey/assertions/oglematchers",
|
||||
"Comment": "1.5.0-356-gfbc0a1c",
|
||||
"Rev": "fbc0a1c888f9f96263f9a559d1769905245f1123"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/smartystreets/goconvey/convey/gotest",
|
||||
"Comment": "1.5.0-356-gfbc0a1c",
|
||||
"Rev": "fbc0a1c888f9f96263f9a559d1769905245f1123"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/smartystreets/goconvey/convey/reporting",
|
||||
"Comment": "1.5.0-356-gfbc0a1c",
|
||||
"Rev": "fbc0a1c888f9f96263f9a559d1769905245f1123"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/streadway/amqp",
|
||||
"Rev": "150b7f24d6ad507e6026c13d85ce1f1391ac7400"
|
||||
@@ -87,6 +319,10 @@
|
||||
"ImportPath": "golang.org/x/oauth2",
|
||||
"Rev": "c58fcf0ffc1c772aa2e1ee4894bc19f2649263b2"
|
||||
},
|
||||
{
|
||||
"ImportPath": "golang.org/x/sys/unix",
|
||||
"Rev": "7a56174f0086b32866ebd746a794417edbc678a1"
|
||||
},
|
||||
{
|
||||
"ImportPath": "gopkg.in/asn1-ber.v1",
|
||||
"Comment": "v1",
|
||||
@@ -102,6 +338,10 @@
|
||||
"Comment": "v0-16-g1772191",
|
||||
"Rev": "177219109c97e7920c933e21c9b25f874357b237"
|
||||
},
|
||||
{
|
||||
"ImportPath": "gopkg.in/macaron.v1",
|
||||
"Rev": "1c6dd87797ae9319b4658cbd48d1d0420b279fd5"
|
||||
},
|
||||
{
|
||||
"ImportPath": "gopkg.in/redis.v2",
|
||||
"Comment": "v2.3.2",
|
||||
|
||||
94
Godeps/_workspace/src/github.com/Unknwon/macaron/README.md
generated
vendored
94
Godeps/_workspace/src/github.com/Unknwon/macaron/README.md
generated
vendored
@@ -1,94 +0,0 @@
|
||||
Macaron [](https://drone.io/github.com/Unknwon/macaron/latest) [](http://gocover.io/github.com/Unknwon/macaron)
|
||||
=======================
|
||||
|
||||

|
||||
|
||||
Package macaron is a high productive and modular design web framework in Go.
|
||||
|
||||
##### Current version: 0.5.4
|
||||
|
||||
## Getting Started
|
||||
|
||||
To install Macaron:
|
||||
|
||||
go get github.com/Unknwon/macaron
|
||||
|
||||
The very basic usage of Macaron:
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import "github.com/Unknwon/macaron"
|
||||
|
||||
func main() {
|
||||
m := macaron.Classic()
|
||||
m.Get("/", func() string {
|
||||
return "Hello world!"
|
||||
})
|
||||
m.Run()
|
||||
}
|
||||
```
|
||||
|
||||
## Features
|
||||
|
||||
- Powerful routing with suburl.
|
||||
- Flexible routes combinations.
|
||||
- Unlimited nested group routers.
|
||||
- Directly integrate with existing services.
|
||||
- Dynamically change template files at runtime.
|
||||
- Allow to use in-memory template and static files.
|
||||
- Easy to plugin/unplugin features with modular design.
|
||||
- Handy dependency injection powered by [inject](https://github.com/codegangsta/inject).
|
||||
- Better router layer and less reflection make faster speed.
|
||||
|
||||
## Middlewares
|
||||
|
||||
Middlewares allow you easily plugin/unplugin features for your Macaron applications.
|
||||
|
||||
There are already many [middlewares](https://github.com/macaron-contrib) to simplify your work:
|
||||
|
||||
- gzip - Gzip compression to all requests
|
||||
- render - Go template engine
|
||||
- static - Serves static files
|
||||
- [binding](https://github.com/macaron-contrib/binding) - Request data binding and validation
|
||||
- [i18n](https://github.com/macaron-contrib/i18n) - Internationalization and Localization
|
||||
- [cache](https://github.com/macaron-contrib/cache) - Cache manager
|
||||
- [session](https://github.com/macaron-contrib/session) - Session manager
|
||||
- [csrf](https://github.com/macaron-contrib/csrf) - Generates and validates csrf tokens
|
||||
- [captcha](https://github.com/macaron-contrib/captcha) - Captcha service
|
||||
- [pongo2](https://github.com/macaron-contrib/pongo2) - Pongo2 template engine support
|
||||
- [sockets](https://github.com/macaron-contrib/sockets) - WebSockets channels binding
|
||||
- [bindata](https://github.com/macaron-contrib/bindata) - Embed binary data as static and template files
|
||||
- [toolbox](https://github.com/macaron-contrib/toolbox) - Health check, pprof, profile and statistic services
|
||||
- [oauth2](https://github.com/macaron-contrib/oauth2) - OAuth 2.0 backend
|
||||
- [switcher](https://github.com/macaron-contrib/switcher) - Multiple-site support
|
||||
- [method](https://github.com/macaron-contrib/method) - HTTP method override
|
||||
- [permissions2](https://github.com/xyproto/permissions2) - Cookies, users and permissions
|
||||
- [renders](https://github.com/macaron-contrib/renders) - Beego-like render engine(Macaron has built-in template engine, this is another option)
|
||||
|
||||
## Use Cases
|
||||
|
||||
- [Gogs](https://github.com/gogits/gogs): Go Git Service
|
||||
- [Gogs Web](https://github.com/gogits/gogsweb): Gogs official website
|
||||
- [Go Walker](https://gowalker.org): Go online API documentation
|
||||
- [Switch](https://github.com/gpmgo/switch): Gopm registry
|
||||
- [YouGam](http://yougam.com): Online Forum
|
||||
- [Car Girl](http://qcnl.gzsy.com/): Online campaign
|
||||
- [Critical Stack Intel](https://intel.criticalstack.com/): A 100% free intel marketplace from Critical Stack, Inc.
|
||||
|
||||
## Getting Help
|
||||
|
||||
- [API Reference](https://gowalker.org/github.com/Unknwon/macaron)
|
||||
- [Documentation](http://macaron.gogs.io)
|
||||
- [FAQs](http://macaron.gogs.io/docs/faqs)
|
||||
- [](https://gitter.im/Unknwon/macaron?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||
|
||||
## Credits
|
||||
|
||||
- Basic design of [Martini](https://github.com/go-martini/martini).
|
||||
- Router layer of [beego](https://github.com/astaxie/beego).
|
||||
- Logo is modified by [@insionng](https://github.com/insionng) based on [Tribal Dragon](http://xtremeyamazaki.deviantart.com/art/Tribal-Dragon-27005087).
|
||||
|
||||
## License
|
||||
|
||||
This project is under Apache v2 License. See the [LICENSE](LICENSE) file for the full license text.
|
||||
370
Godeps/_workspace/src/github.com/Unknwon/macaron/context_test.go
generated
vendored
370
Godeps/_workspace/src/github.com/Unknwon/macaron/context_test.go
generated
vendored
@@ -1,370 +0,0 @@
|
||||
// Copyright 2014 Unknwon
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"): you may
|
||||
// not use this file except in compliance with the License. You may obtain
|
||||
// a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
// License for the specific language governing permissions and limitations
|
||||
// under the License.
|
||||
|
||||
package macaron
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"net/url"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/Unknwon/com"
|
||||
|
||||
. "github.com/smartystreets/goconvey/convey"
|
||||
)
|
||||
|
||||
func Test_Context(t *testing.T) {
|
||||
Convey("Do advanced encapsulation operations", t, func() {
|
||||
m := Classic()
|
||||
m.Use(Renderers(RenderOptions{
|
||||
Directory: "fixtures/basic",
|
||||
}, "fixtures/basic2"))
|
||||
|
||||
Convey("Get request body", func() {
|
||||
m.Get("/body1", func(ctx *Context) {
|
||||
data, err := ioutil.ReadAll(ctx.Req.Body().ReadCloser())
|
||||
So(err, ShouldBeNil)
|
||||
So(string(data), ShouldEqual, "This is my request body")
|
||||
})
|
||||
m.Get("/body2", func(ctx *Context) {
|
||||
data, err := ctx.Req.Body().Bytes()
|
||||
So(err, ShouldBeNil)
|
||||
So(string(data), ShouldEqual, "This is my request body")
|
||||
})
|
||||
m.Get("/body3", func(ctx *Context) {
|
||||
data, err := ctx.Req.Body().String()
|
||||
So(err, ShouldBeNil)
|
||||
So(data, ShouldEqual, "This is my request body")
|
||||
})
|
||||
|
||||
for i := 1; i <= 3; i++ {
|
||||
resp := httptest.NewRecorder()
|
||||
req, err := http.NewRequest("GET", "/body"+com.ToStr(i), nil)
|
||||
req.Body = ioutil.NopCloser(bytes.NewBufferString("This is my request body"))
|
||||
So(err, ShouldBeNil)
|
||||
m.ServeHTTP(resp, req)
|
||||
}
|
||||
})
|
||||
|
||||
Convey("Get remote IP address", func() {
|
||||
m.Get("/remoteaddr", func(ctx *Context) string {
|
||||
return ctx.RemoteAddr()
|
||||
})
|
||||
|
||||
resp := httptest.NewRecorder()
|
||||
req, err := http.NewRequest("GET", "/remoteaddr", nil)
|
||||
req.RemoteAddr = "127.0.0.1:3333"
|
||||
So(err, ShouldBeNil)
|
||||
m.ServeHTTP(resp, req)
|
||||
So(resp.Body.String(), ShouldEqual, "127.0.0.1")
|
||||
})
|
||||
|
||||
Convey("Render HTML", func() {
|
||||
|
||||
Convey("Normal HTML", func() {
|
||||
m.Get("/html", func(ctx *Context) {
|
||||
ctx.HTML(304, "hello", "Unknwon") // 304 for logger test.
|
||||
})
|
||||
|
||||
resp := httptest.NewRecorder()
|
||||
req, err := http.NewRequest("GET", "/html", nil)
|
||||
So(err, ShouldBeNil)
|
||||
m.ServeHTTP(resp, req)
|
||||
So(resp.Body.String(), ShouldEqual, "<h1>Hello Unknwon</h1>")
|
||||
})
|
||||
|
||||
Convey("HTML template set", func() {
|
||||
m.Get("/html2", func(ctx *Context) {
|
||||
ctx.Data["Name"] = "Unknwon"
|
||||
ctx.HTMLSet(200, "basic2", "hello2")
|
||||
})
|
||||
|
||||
resp := httptest.NewRecorder()
|
||||
req, err := http.NewRequest("GET", "/html2", nil)
|
||||
So(err, ShouldBeNil)
|
||||
m.ServeHTTP(resp, req)
|
||||
So(resp.Body.String(), ShouldEqual, "<h1>Hello Unknwon</h1>")
|
||||
})
|
||||
|
||||
Convey("With layout", func() {
|
||||
m.Get("/layout", func(ctx *Context) {
|
||||
ctx.HTML(200, "hello", "Unknwon", HTMLOptions{"layout"})
|
||||
})
|
||||
|
||||
resp := httptest.NewRecorder()
|
||||
req, err := http.NewRequest("GET", "/layout", nil)
|
||||
So(err, ShouldBeNil)
|
||||
m.ServeHTTP(resp, req)
|
||||
So(resp.Body.String(), ShouldEqual, "head<h1>Hello Unknwon</h1>foot")
|
||||
})
|
||||
})
|
||||
|
||||
Convey("Parse from and query", func() {
|
||||
m.Get("/query", func(ctx *Context) string {
|
||||
var buf bytes.Buffer
|
||||
buf.WriteString(ctx.QueryTrim("name") + " ")
|
||||
buf.WriteString(ctx.QueryEscape("name") + " ")
|
||||
buf.WriteString(com.ToStr(ctx.QueryInt("int")) + " ")
|
||||
buf.WriteString(com.ToStr(ctx.QueryInt64("int64")) + " ")
|
||||
buf.WriteString(com.ToStr(ctx.QueryFloat64("float64")) + " ")
|
||||
return buf.String()
|
||||
})
|
||||
m.Get("/query2", func(ctx *Context) string {
|
||||
var buf bytes.Buffer
|
||||
buf.WriteString(strings.Join(ctx.QueryStrings("list"), ",") + " ")
|
||||
buf.WriteString(strings.Join(ctx.QueryStrings("404"), ",") + " ")
|
||||
return buf.String()
|
||||
})
|
||||
|
||||
resp := httptest.NewRecorder()
|
||||
req, err := http.NewRequest("GET", "/query?name=Unknwon&int=12&int64=123&float64=1.25", nil)
|
||||
So(err, ShouldBeNil)
|
||||
m.ServeHTTP(resp, req)
|
||||
So(resp.Body.String(), ShouldEqual, "Unknwon Unknwon 12 123 1.25 ")
|
||||
|
||||
resp = httptest.NewRecorder()
|
||||
req, err = http.NewRequest("GET", "/query2?list=item1&list=item2", nil)
|
||||
So(err, ShouldBeNil)
|
||||
m.ServeHTTP(resp, req)
|
||||
So(resp.Body.String(), ShouldEqual, "item1,item2 ")
|
||||
})
|
||||
|
||||
Convey("URL parameter", func() {
|
||||
m.Get("/:name/:int/:int64/:float64", func(ctx *Context) string {
|
||||
var buf bytes.Buffer
|
||||
ctx.SetParams("name", ctx.Params("name"))
|
||||
buf.WriteString(ctx.Params(""))
|
||||
buf.WriteString(ctx.Params(":name") + " ")
|
||||
buf.WriteString(ctx.ParamsEscape(":name") + " ")
|
||||
buf.WriteString(com.ToStr(ctx.ParamsInt(":int")) + " ")
|
||||
buf.WriteString(com.ToStr(ctx.ParamsInt64(":int64")) + " ")
|
||||
buf.WriteString(com.ToStr(ctx.ParamsFloat64(":float64")) + " ")
|
||||
return buf.String()
|
||||
})
|
||||
|
||||
resp := httptest.NewRecorder()
|
||||
req, err := http.NewRequest("GET", "/user/1/13/1.24", nil)
|
||||
So(err, ShouldBeNil)
|
||||
m.ServeHTTP(resp, req)
|
||||
So(resp.Body.String(), ShouldEqual, "user user 1 13 1.24 ")
|
||||
})
|
||||
|
||||
Convey("Get file", func() {
|
||||
m.Get("/getfile", func(ctx *Context) {
|
||||
ctx.GetFile("hi")
|
||||
})
|
||||
|
||||
resp := httptest.NewRecorder()
|
||||
req, err := http.NewRequest("GET", "/getfile", nil)
|
||||
So(err, ShouldBeNil)
|
||||
m.ServeHTTP(resp, req)
|
||||
})
|
||||
|
||||
Convey("Set and get cookie", func() {
|
||||
m.Get("/set", func(ctx *Context) {
|
||||
ctx.SetCookie("user", "Unknwon", 1, "/", "localhost", true, true)
|
||||
ctx.SetCookie("user", "Unknwon", int32(1), "/", "localhost", 1)
|
||||
ctx.SetCookie("user", "Unknwon", int64(1))
|
||||
})
|
||||
|
||||
resp := httptest.NewRecorder()
|
||||
req, err := http.NewRequest("GET", "/set", nil)
|
||||
So(err, ShouldBeNil)
|
||||
m.ServeHTTP(resp, req)
|
||||
So(resp.Header().Get("Set-Cookie"), ShouldEqual, "user=Unknwon; Path=/; Domain=localhost; Max-Age=1; HttpOnly; Secure")
|
||||
|
||||
m.Get("/get", func(ctx *Context) string {
|
||||
ctx.GetCookie("404")
|
||||
So(ctx.GetCookieInt("uid"), ShouldEqual, 1)
|
||||
So(ctx.GetCookieInt64("uid"), ShouldEqual, 1)
|
||||
So(ctx.GetCookieFloat64("balance"), ShouldEqual, 1.25)
|
||||
return ctx.GetCookie("user")
|
||||
})
|
||||
|
||||
resp = httptest.NewRecorder()
|
||||
req, err = http.NewRequest("GET", "/get", nil)
|
||||
So(err, ShouldBeNil)
|
||||
req.Header.Set("Cookie", "user=Unknwon; uid=1; balance=1.25")
|
||||
m.ServeHTTP(resp, req)
|
||||
So(resp.Body.String(), ShouldEqual, "Unknwon")
|
||||
})
|
||||
|
||||
Convey("Set and get secure cookie", func() {
|
||||
m.SetDefaultCookieSecret("macaron")
|
||||
m.Get("/set", func(ctx *Context) {
|
||||
ctx.SetSecureCookie("user", "Unknwon", 1)
|
||||
})
|
||||
|
||||
resp := httptest.NewRecorder()
|
||||
req, err := http.NewRequest("GET", "/set", nil)
|
||||
So(err, ShouldBeNil)
|
||||
m.ServeHTTP(resp, req)
|
||||
|
||||
cookie := resp.Header().Get("Set-Cookie")
|
||||
|
||||
m.Get("/get", func(ctx *Context) string {
|
||||
name, ok := ctx.GetSecureCookie("user")
|
||||
So(ok, ShouldBeTrue)
|
||||
return name
|
||||
})
|
||||
|
||||
resp = httptest.NewRecorder()
|
||||
req, err = http.NewRequest("GET", "/get", nil)
|
||||
So(err, ShouldBeNil)
|
||||
req.Header.Set("Cookie", cookie)
|
||||
m.ServeHTTP(resp, req)
|
||||
So(resp.Body.String(), ShouldEqual, "Unknwon")
|
||||
})
|
||||
|
||||
Convey("Serve files", func() {
|
||||
m.Get("/file", func(ctx *Context) {
|
||||
ctx.ServeFile("fixtures/custom_funcs/index.tmpl")
|
||||
})
|
||||
|
||||
resp := httptest.NewRecorder()
|
||||
req, err := http.NewRequest("GET", "/file", nil)
|
||||
So(err, ShouldBeNil)
|
||||
m.ServeHTTP(resp, req)
|
||||
So(resp.Body.String(), ShouldEqual, "{{ myCustomFunc }}")
|
||||
|
||||
m.Get("/file2", func(ctx *Context) {
|
||||
ctx.ServeFile("fixtures/custom_funcs/index.tmpl", "ok.tmpl")
|
||||
})
|
||||
|
||||
resp = httptest.NewRecorder()
|
||||
req, err = http.NewRequest("GET", "/file2", nil)
|
||||
So(err, ShouldBeNil)
|
||||
m.ServeHTTP(resp, req)
|
||||
So(resp.Body.String(), ShouldEqual, "{{ myCustomFunc }}")
|
||||
})
|
||||
|
||||
Convey("Serve file content", func() {
|
||||
m.Get("/file", func(ctx *Context) {
|
||||
ctx.ServeFileContent("fixtures/custom_funcs/index.tmpl")
|
||||
})
|
||||
|
||||
resp := httptest.NewRecorder()
|
||||
req, err := http.NewRequest("GET", "/file", nil)
|
||||
So(err, ShouldBeNil)
|
||||
m.ServeHTTP(resp, req)
|
||||
So(resp.Body.String(), ShouldEqual, "{{ myCustomFunc }}")
|
||||
|
||||
m.Get("/file2", func(ctx *Context) {
|
||||
ctx.ServeFileContent("fixtures/custom_funcs/index.tmpl", "ok.tmpl")
|
||||
})
|
||||
|
||||
resp = httptest.NewRecorder()
|
||||
req, err = http.NewRequest("GET", "/file2", nil)
|
||||
So(err, ShouldBeNil)
|
||||
m.ServeHTTP(resp, req)
|
||||
So(resp.Body.String(), ShouldEqual, "{{ myCustomFunc }}")
|
||||
|
||||
m.Get("/file3", func(ctx *Context) {
|
||||
ctx.ServeFileContent("404.tmpl")
|
||||
})
|
||||
|
||||
resp = httptest.NewRecorder()
|
||||
req, err = http.NewRequest("GET", "/file3", nil)
|
||||
So(err, ShouldBeNil)
|
||||
m.ServeHTTP(resp, req)
|
||||
So(resp.Body.String(), ShouldEqual, "open 404.tmpl: no such file or directory\n")
|
||||
So(resp.Code, ShouldEqual, 500)
|
||||
})
|
||||
|
||||
Convey("Serve content", func() {
|
||||
m.Get("/content", func(ctx *Context) {
|
||||
ctx.ServeContent("content1", bytes.NewReader([]byte("Hello world!")))
|
||||
})
|
||||
|
||||
resp := httptest.NewRecorder()
|
||||
req, err := http.NewRequest("GET", "/content", nil)
|
||||
So(err, ShouldBeNil)
|
||||
m.ServeHTTP(resp, req)
|
||||
So(resp.Body.String(), ShouldEqual, "Hello world!")
|
||||
|
||||
m.Get("/content2", func(ctx *Context) {
|
||||
ctx.ServeContent("content1", bytes.NewReader([]byte("Hello world!")), time.Now())
|
||||
})
|
||||
|
||||
resp = httptest.NewRecorder()
|
||||
req, err = http.NewRequest("GET", "/content2", nil)
|
||||
So(err, ShouldBeNil)
|
||||
m.ServeHTTP(resp, req)
|
||||
So(resp.Body.String(), ShouldEqual, "Hello world!")
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func Test_Context_Render(t *testing.T) {
|
||||
Convey("Invalid render", t, func() {
|
||||
defer func() {
|
||||
So(recover(), ShouldNotBeNil)
|
||||
}()
|
||||
|
||||
m := New()
|
||||
m.Get("/", func(ctx *Context) {
|
||||
ctx.HTML(200, "hey")
|
||||
})
|
||||
|
||||
resp := httptest.NewRecorder()
|
||||
req, err := http.NewRequest("GET", "/", nil)
|
||||
So(err, ShouldBeNil)
|
||||
m.ServeHTTP(resp, req)
|
||||
})
|
||||
}
|
||||
|
||||
func Test_Context_Redirect(t *testing.T) {
|
||||
Convey("Context with default redirect", t, func() {
|
||||
url, err := url.Parse("http://localhost/path/one")
|
||||
So(err, ShouldBeNil)
|
||||
resp := httptest.NewRecorder()
|
||||
req := http.Request{
|
||||
Method: "GET",
|
||||
URL: url,
|
||||
}
|
||||
ctx := &Context{
|
||||
Req: Request{&req},
|
||||
Resp: NewResponseWriter(resp),
|
||||
Data: make(map[string]interface{}),
|
||||
}
|
||||
ctx.Redirect("two")
|
||||
|
||||
So(resp.Code, ShouldEqual, http.StatusFound)
|
||||
So(resp.HeaderMap["Location"][0], ShouldEqual, "/path/two")
|
||||
})
|
||||
|
||||
Convey("Context with custom redirect", t, func() {
|
||||
url, err := url.Parse("http://localhost/path/one")
|
||||
So(err, ShouldBeNil)
|
||||
resp := httptest.NewRecorder()
|
||||
req := http.Request{
|
||||
Method: "GET",
|
||||
URL: url,
|
||||
}
|
||||
ctx := &Context{
|
||||
Req: Request{&req},
|
||||
Resp: NewResponseWriter(resp),
|
||||
Data: make(map[string]interface{}),
|
||||
}
|
||||
ctx.Redirect("two", 307)
|
||||
|
||||
So(resp.Code, ShouldEqual, http.StatusTemporaryRedirect)
|
||||
So(resp.HeaderMap["Location"][0], ShouldEqual, "/path/two")
|
||||
})
|
||||
}
|
||||
81
Godeps/_workspace/src/github.com/Unknwon/macaron/gzip.go
generated
vendored
81
Godeps/_workspace/src/github.com/Unknwon/macaron/gzip.go
generated
vendored
@@ -1,81 +0,0 @@
|
||||
// Copyright 2013 Martini Authors
|
||||
// Copyright 2014 Unknwon
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"): you may
|
||||
// not use this file except in compliance with the License. You may obtain
|
||||
// a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
// License for the specific language governing permissions and limitations
|
||||
// under the License.
|
||||
|
||||
package macaron
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"compress/gzip"
|
||||
"fmt"
|
||||
"net"
|
||||
"net/http"
|
||||
"strings"
|
||||
)
|
||||
|
||||
const (
|
||||
HeaderAcceptEncoding = "Accept-Encoding"
|
||||
HeaderContentEncoding = "Content-Encoding"
|
||||
HeaderContentLength = "Content-Length"
|
||||
HeaderContentType = "Content-Type"
|
||||
HeaderVary = "Vary"
|
||||
)
|
||||
|
||||
// Gziper returns a Handler that adds gzip compression to all requests.
|
||||
// Make sure to include the Gzip middleware above other middleware
|
||||
// that alter the response body (like the render middleware).
|
||||
func Gziper() Handler {
|
||||
return func(ctx *Context) {
|
||||
if !strings.Contains(ctx.Req.Header.Get(HeaderAcceptEncoding), "gzip") {
|
||||
return
|
||||
}
|
||||
|
||||
headers := ctx.Resp.Header()
|
||||
headers.Set(HeaderContentEncoding, "gzip")
|
||||
headers.Set(HeaderVary, HeaderAcceptEncoding)
|
||||
|
||||
gz := gzip.NewWriter(ctx.Resp)
|
||||
defer gz.Close()
|
||||
|
||||
gzw := gzipResponseWriter{gz, ctx.Resp}
|
||||
ctx.Resp = gzw
|
||||
ctx.MapTo(gzw, (*http.ResponseWriter)(nil))
|
||||
|
||||
ctx.Next()
|
||||
|
||||
// delete content length after we know we have been written to
|
||||
gzw.Header().Del("Content-Length")
|
||||
}
|
||||
}
|
||||
|
||||
type gzipResponseWriter struct {
|
||||
w *gzip.Writer
|
||||
ResponseWriter
|
||||
}
|
||||
|
||||
func (grw gzipResponseWriter) Write(p []byte) (int, error) {
|
||||
if len(grw.Header().Get(HeaderContentType)) == 0 {
|
||||
grw.Header().Set(HeaderContentType, http.DetectContentType(p))
|
||||
}
|
||||
|
||||
return grw.w.Write(p)
|
||||
}
|
||||
|
||||
func (grw gzipResponseWriter) Hijack() (net.Conn, *bufio.ReadWriter, error) {
|
||||
hijacker, ok := grw.ResponseWriter.(http.Hijacker)
|
||||
if !ok {
|
||||
return nil, nil, fmt.Errorf("the ResponseWriter doesn't support the Hijacker interface")
|
||||
}
|
||||
return hijacker.Hijack()
|
||||
}
|
||||
65
Godeps/_workspace/src/github.com/Unknwon/macaron/gzip_test.go
generated
vendored
65
Godeps/_workspace/src/github.com/Unknwon/macaron/gzip_test.go
generated
vendored
@@ -1,65 +0,0 @@
|
||||
// Copyright 2013 Martini Authors
|
||||
// Copyright 2014 Unknwon
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"): you may
|
||||
// not use this file except in compliance with the License. You may obtain
|
||||
// a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
// License for the specific language governing permissions and limitations
|
||||
// under the License.
|
||||
|
||||
package macaron
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
. "github.com/smartystreets/goconvey/convey"
|
||||
)
|
||||
|
||||
func Test_Gzip(t *testing.T) {
|
||||
Convey("Gzip response content", t, func() {
|
||||
before := false
|
||||
|
||||
m := New()
|
||||
m.Use(Gziper())
|
||||
m.Use(func(r http.ResponseWriter) {
|
||||
r.(ResponseWriter).Before(func(rw ResponseWriter) {
|
||||
before = true
|
||||
})
|
||||
})
|
||||
m.Get("/", func() string { return "hello wolrd!" })
|
||||
|
||||
// Not yet gzip.
|
||||
resp := httptest.NewRecorder()
|
||||
req, err := http.NewRequest("GET", "/", nil)
|
||||
So(err, ShouldBeNil)
|
||||
m.ServeHTTP(resp, req)
|
||||
|
||||
_, ok := resp.HeaderMap[HeaderContentEncoding]
|
||||
So(ok, ShouldBeFalse)
|
||||
|
||||
ce := resp.Header().Get(HeaderContentEncoding)
|
||||
So(strings.EqualFold(ce, "gzip"), ShouldBeFalse)
|
||||
|
||||
// Gzip now.
|
||||
resp = httptest.NewRecorder()
|
||||
req.Header.Set(HeaderAcceptEncoding, "gzip")
|
||||
m.ServeHTTP(resp, req)
|
||||
|
||||
_, ok = resp.HeaderMap[HeaderContentEncoding]
|
||||
So(ok, ShouldBeTrue)
|
||||
|
||||
ce = resp.Header().Get(HeaderContentEncoding)
|
||||
So(strings.EqualFold(ce, "gzip"), ShouldBeTrue)
|
||||
|
||||
So(before, ShouldBeTrue)
|
||||
})
|
||||
}
|
||||
4
Godeps/_workspace/src/github.com/Unknwon/macaron/inject/README.md
generated
vendored
4
Godeps/_workspace/src/github.com/Unknwon/macaron/inject/README.md
generated
vendored
@@ -1,4 +0,0 @@
|
||||
inject
|
||||
======
|
||||
|
||||
Dependency injection for go
|
||||
1
Godeps/_workspace/src/github.com/Unknwon/macaron/inject/inject.goconvey
generated
vendored
1
Godeps/_workspace/src/github.com/Unknwon/macaron/inject/inject.goconvey
generated
vendored
@@ -1 +0,0 @@
|
||||
ignore
|
||||
174
Godeps/_workspace/src/github.com/Unknwon/macaron/inject/inject_test.go
generated
vendored
174
Godeps/_workspace/src/github.com/Unknwon/macaron/inject/inject_test.go
generated
vendored
@@ -1,174 +0,0 @@
|
||||
// Copyright 2013 Martini Authors
|
||||
// Copyright 2014 Unknwon
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"): you may
|
||||
// not use this file except in compliance with the License. You may obtain
|
||||
// a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
// License for the specific language governing permissions and limitations
|
||||
// under the License.
|
||||
|
||||
package inject_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"github.com/Unknwon/macaron/inject"
|
||||
)
|
||||
|
||||
type SpecialString interface {
|
||||
}
|
||||
|
||||
type TestStruct struct {
|
||||
Dep1 string `inject:"t" json:"-"`
|
||||
Dep2 SpecialString `inject`
|
||||
Dep3 string
|
||||
}
|
||||
|
||||
type Greeter struct {
|
||||
Name string
|
||||
}
|
||||
|
||||
func (g *Greeter) String() string {
|
||||
return "Hello, My name is" + g.Name
|
||||
}
|
||||
|
||||
/* Test Helpers */
|
||||
func expect(t *testing.T, a interface{}, b interface{}) {
|
||||
if a != b {
|
||||
t.Errorf("Expected %v (type %v) - Got %v (type %v)", b, reflect.TypeOf(b), a, reflect.TypeOf(a))
|
||||
}
|
||||
}
|
||||
|
||||
func refute(t *testing.T, a interface{}, b interface{}) {
|
||||
if a == b {
|
||||
t.Errorf("Did not expect %v (type %v) - Got %v (type %v)", b, reflect.TypeOf(b), a, reflect.TypeOf(a))
|
||||
}
|
||||
}
|
||||
|
||||
func Test_InjectorInvoke(t *testing.T) {
|
||||
injector := inject.New()
|
||||
expect(t, injector == nil, false)
|
||||
|
||||
dep := "some dependency"
|
||||
injector.Map(dep)
|
||||
dep2 := "another dep"
|
||||
injector.MapTo(dep2, (*SpecialString)(nil))
|
||||
dep3 := make(chan *SpecialString)
|
||||
dep4 := make(chan *SpecialString)
|
||||
typRecv := reflect.ChanOf(reflect.RecvDir, reflect.TypeOf(dep3).Elem())
|
||||
typSend := reflect.ChanOf(reflect.SendDir, reflect.TypeOf(dep4).Elem())
|
||||
injector.Set(typRecv, reflect.ValueOf(dep3))
|
||||
injector.Set(typSend, reflect.ValueOf(dep4))
|
||||
|
||||
_, err := injector.Invoke(func(d1 string, d2 SpecialString, d3 <-chan *SpecialString, d4 chan<- *SpecialString) {
|
||||
expect(t, d1, dep)
|
||||
expect(t, d2, dep2)
|
||||
expect(t, reflect.TypeOf(d3).Elem(), reflect.TypeOf(dep3).Elem())
|
||||
expect(t, reflect.TypeOf(d4).Elem(), reflect.TypeOf(dep4).Elem())
|
||||
expect(t, reflect.TypeOf(d3).ChanDir(), reflect.RecvDir)
|
||||
expect(t, reflect.TypeOf(d4).ChanDir(), reflect.SendDir)
|
||||
})
|
||||
|
||||
expect(t, err, nil)
|
||||
}
|
||||
|
||||
func Test_InjectorInvokeReturnValues(t *testing.T) {
|
||||
injector := inject.New()
|
||||
expect(t, injector == nil, false)
|
||||
|
||||
dep := "some dependency"
|
||||
injector.Map(dep)
|
||||
dep2 := "another dep"
|
||||
injector.MapTo(dep2, (*SpecialString)(nil))
|
||||
|
||||
result, err := injector.Invoke(func(d1 string, d2 SpecialString) string {
|
||||
expect(t, d1, dep)
|
||||
expect(t, d2, dep2)
|
||||
return "Hello world"
|
||||
})
|
||||
|
||||
expect(t, result[0].String(), "Hello world")
|
||||
expect(t, err, nil)
|
||||
}
|
||||
|
||||
func Test_InjectorApply(t *testing.T) {
|
||||
injector := inject.New()
|
||||
|
||||
injector.Map("a dep").MapTo("another dep", (*SpecialString)(nil))
|
||||
|
||||
s := TestStruct{}
|
||||
err := injector.Apply(&s)
|
||||
expect(t, err, nil)
|
||||
|
||||
expect(t, s.Dep1, "a dep")
|
||||
expect(t, s.Dep2, "another dep")
|
||||
}
|
||||
|
||||
func Test_InterfaceOf(t *testing.T) {
|
||||
iType := inject.InterfaceOf((*SpecialString)(nil))
|
||||
expect(t, iType.Kind(), reflect.Interface)
|
||||
|
||||
iType = inject.InterfaceOf((**SpecialString)(nil))
|
||||
expect(t, iType.Kind(), reflect.Interface)
|
||||
|
||||
// Expecting nil
|
||||
defer func() {
|
||||
rec := recover()
|
||||
refute(t, rec, nil)
|
||||
}()
|
||||
iType = inject.InterfaceOf((*testing.T)(nil))
|
||||
}
|
||||
|
||||
func Test_InjectorSet(t *testing.T) {
|
||||
injector := inject.New()
|
||||
typ := reflect.TypeOf("string")
|
||||
typSend := reflect.ChanOf(reflect.SendDir, typ)
|
||||
typRecv := reflect.ChanOf(reflect.RecvDir, typ)
|
||||
|
||||
// instantiating unidirectional channels is not possible using reflect
|
||||
// http://golang.org/src/pkg/reflect/value.go?s=60463:60504#L2064
|
||||
chanRecv := reflect.MakeChan(reflect.ChanOf(reflect.BothDir, typ), 0)
|
||||
chanSend := reflect.MakeChan(reflect.ChanOf(reflect.BothDir, typ), 0)
|
||||
|
||||
injector.Set(typSend, chanSend)
|
||||
injector.Set(typRecv, chanRecv)
|
||||
|
||||
expect(t, injector.GetVal(typSend).IsValid(), true)
|
||||
expect(t, injector.GetVal(typRecv).IsValid(), true)
|
||||
expect(t, injector.GetVal(chanSend.Type()).IsValid(), false)
|
||||
}
|
||||
|
||||
func Test_InjectorGet(t *testing.T) {
|
||||
injector := inject.New()
|
||||
|
||||
injector.Map("some dependency")
|
||||
|
||||
expect(t, injector.GetVal(reflect.TypeOf("string")).IsValid(), true)
|
||||
expect(t, injector.GetVal(reflect.TypeOf(11)).IsValid(), false)
|
||||
}
|
||||
|
||||
func Test_InjectorSetParent(t *testing.T) {
|
||||
injector := inject.New()
|
||||
injector.MapTo("another dep", (*SpecialString)(nil))
|
||||
|
||||
injector2 := inject.New()
|
||||
injector2.SetParent(injector)
|
||||
|
||||
expect(t, injector2.GetVal(inject.InterfaceOf((*SpecialString)(nil))).IsValid(), true)
|
||||
}
|
||||
|
||||
func TestInjectImplementors(t *testing.T) {
|
||||
injector := inject.New()
|
||||
g := &Greeter{"Jeremy"}
|
||||
injector.Map(g)
|
||||
|
||||
expect(t, injector.GetVal(inject.InterfaceOf((*fmt.Stringer)(nil))).IsValid(), true)
|
||||
}
|
||||
67
Godeps/_workspace/src/github.com/Unknwon/macaron/logger_test.go
generated
vendored
67
Godeps/_workspace/src/github.com/Unknwon/macaron/logger_test.go
generated
vendored
@@ -1,67 +0,0 @@
|
||||
// Copyright 2013 Martini Authors
|
||||
// Copyright 2014 Unknwon
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"): you may
|
||||
// not use this file except in compliance with the License. You may obtain
|
||||
// a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
// License for the specific language governing permissions and limitations
|
||||
// under the License.
|
||||
|
||||
package macaron
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"log"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
|
||||
"github.com/Unknwon/com"
|
||||
|
||||
. "github.com/smartystreets/goconvey/convey"
|
||||
)
|
||||
|
||||
func Test_Logger(t *testing.T) {
|
||||
Convey("Global logger", t, func() {
|
||||
buf := bytes.NewBufferString("")
|
||||
m := New()
|
||||
m.Map(log.New(buf, "[Macaron] ", 0))
|
||||
m.Use(Logger())
|
||||
m.Use(func(res http.ResponseWriter) {
|
||||
res.WriteHeader(http.StatusNotFound)
|
||||
})
|
||||
m.Get("/", func() {})
|
||||
|
||||
resp := httptest.NewRecorder()
|
||||
req, err := http.NewRequest("GET", "http://localhost:4000/", nil)
|
||||
So(err, ShouldBeNil)
|
||||
m.ServeHTTP(resp, req)
|
||||
So(resp.Code, ShouldEqual, http.StatusNotFound)
|
||||
So(len(buf.String()), ShouldBeGreaterThan, 0)
|
||||
})
|
||||
|
||||
if ColorLog {
|
||||
Convey("Color console output", t, func() {
|
||||
m := Classic()
|
||||
m.Get("/:code:int", func(ctx *Context) (int, string) {
|
||||
return ctx.ParamsInt(":code"), ""
|
||||
})
|
||||
|
||||
// Just for testing if logger would capture.
|
||||
codes := []int{200, 201, 202, 301, 302, 304, 401, 403, 404, 500}
|
||||
for _, code := range codes {
|
||||
resp := httptest.NewRecorder()
|
||||
req, err := http.NewRequest("GET", "http://localhost:4000/"+com.ToStr(code), nil)
|
||||
So(err, ShouldBeNil)
|
||||
m.ServeHTTP(resp, req)
|
||||
So(resp.Code, ShouldEqual, code)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
218
Godeps/_workspace/src/github.com/Unknwon/macaron/macaron_test.go
generated
vendored
218
Godeps/_workspace/src/github.com/Unknwon/macaron/macaron_test.go
generated
vendored
@@ -1,218 +0,0 @@
|
||||
// Copyright 2013 Martini Authors
|
||||
// Copyright 2014 Unknwon
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"): you may
|
||||
// not use this file except in compliance with the License. You may obtain
|
||||
// a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
// License for the specific language governing permissions and limitations
|
||||
// under the License.
|
||||
|
||||
package macaron
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"os"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
. "github.com/smartystreets/goconvey/convey"
|
||||
)
|
||||
|
||||
func Test_Version(t *testing.T) {
|
||||
Convey("Get version", t, func() {
|
||||
So(Version(), ShouldEqual, _VERSION)
|
||||
})
|
||||
}
|
||||
|
||||
func Test_New(t *testing.T) {
|
||||
Convey("Initialize a new instance", t, func() {
|
||||
So(New(), ShouldNotBeNil)
|
||||
})
|
||||
|
||||
Convey("Just test that Run doesn't bomb", t, func() {
|
||||
go New().Run()
|
||||
time.Sleep(1 * time.Second)
|
||||
os.Setenv("PORT", "4001")
|
||||
go New().Run("0.0.0.0")
|
||||
go New().Run(4002)
|
||||
go New().Run("0.0.0.0", 4003)
|
||||
})
|
||||
}
|
||||
|
||||
func Test_Macaron_Before(t *testing.T) {
|
||||
Convey("Register before handlers", t, func() {
|
||||
m := New()
|
||||
m.Before(func(rw http.ResponseWriter, req *http.Request) bool {
|
||||
return false
|
||||
})
|
||||
m.Before(func(rw http.ResponseWriter, req *http.Request) bool {
|
||||
return true
|
||||
})
|
||||
resp := httptest.NewRecorder()
|
||||
req, err := http.NewRequest("GET", "/", nil)
|
||||
So(err, ShouldBeNil)
|
||||
m.ServeHTTP(resp, req)
|
||||
})
|
||||
}
|
||||
|
||||
func Test_Macaron_ServeHTTP(t *testing.T) {
|
||||
Convey("Serve HTTP requests", t, func() {
|
||||
result := ""
|
||||
m := New()
|
||||
m.Use(func(c *Context) {
|
||||
result += "foo"
|
||||
c.Next()
|
||||
result += "ban"
|
||||
})
|
||||
m.Use(func(c *Context) {
|
||||
result += "bar"
|
||||
c.Next()
|
||||
result += "baz"
|
||||
})
|
||||
m.Get("/", func() {})
|
||||
m.Action(func(res http.ResponseWriter, req *http.Request) {
|
||||
result += "bat"
|
||||
res.WriteHeader(http.StatusBadRequest)
|
||||
})
|
||||
|
||||
resp := httptest.NewRecorder()
|
||||
req, err := http.NewRequest("GET", "/", nil)
|
||||
So(err, ShouldBeNil)
|
||||
m.ServeHTTP(resp, req)
|
||||
So(result, ShouldEqual, "foobarbatbazban")
|
||||
So(resp.Code, ShouldEqual, http.StatusBadRequest)
|
||||
})
|
||||
}
|
||||
|
||||
func Test_Macaron_Handlers(t *testing.T) {
|
||||
Convey("Add custom handlers", t, func() {
|
||||
result := ""
|
||||
batman := func(c *Context) {
|
||||
result += "batman!"
|
||||
}
|
||||
|
||||
m := New()
|
||||
m.Use(func(c *Context) {
|
||||
result += "foo"
|
||||
c.Next()
|
||||
result += "ban"
|
||||
})
|
||||
m.Handlers(
|
||||
batman,
|
||||
batman,
|
||||
batman,
|
||||
)
|
||||
|
||||
Convey("Add not callable function", func() {
|
||||
defer func() {
|
||||
So(recover(), ShouldNotBeNil)
|
||||
}()
|
||||
m.Use("shit")
|
||||
})
|
||||
|
||||
m.Get("/", func() {})
|
||||
m.Action(func(res http.ResponseWriter, req *http.Request) {
|
||||
result += "bat"
|
||||
res.WriteHeader(http.StatusBadRequest)
|
||||
})
|
||||
|
||||
resp := httptest.NewRecorder()
|
||||
req, err := http.NewRequest("GET", "/", nil)
|
||||
So(err, ShouldBeNil)
|
||||
m.ServeHTTP(resp, req)
|
||||
So(result, ShouldEqual, "batman!batman!batman!bat")
|
||||
So(resp.Code, ShouldEqual, http.StatusBadRequest)
|
||||
})
|
||||
}
|
||||
|
||||
func Test_Macaron_EarlyWrite(t *testing.T) {
|
||||
Convey("Write early content to response", t, func() {
|
||||
result := ""
|
||||
m := New()
|
||||
m.Use(func(res http.ResponseWriter) {
|
||||
result += "foobar"
|
||||
res.Write([]byte("Hello world"))
|
||||
})
|
||||
m.Use(func() {
|
||||
result += "bat"
|
||||
})
|
||||
m.Get("/", func() {})
|
||||
m.Action(func(res http.ResponseWriter) {
|
||||
result += "baz"
|
||||
res.WriteHeader(http.StatusBadRequest)
|
||||
})
|
||||
|
||||
resp := httptest.NewRecorder()
|
||||
req, err := http.NewRequest("GET", "/", nil)
|
||||
So(err, ShouldBeNil)
|
||||
m.ServeHTTP(resp, req)
|
||||
So(result, ShouldEqual, "foobar")
|
||||
So(resp.Code, ShouldEqual, http.StatusOK)
|
||||
})
|
||||
}
|
||||
|
||||
func Test_Macaron_Written(t *testing.T) {
|
||||
Convey("Written sign", t, func() {
|
||||
resp := httptest.NewRecorder()
|
||||
m := New()
|
||||
m.Handlers(func(res http.ResponseWriter) {
|
||||
res.WriteHeader(http.StatusOK)
|
||||
})
|
||||
|
||||
ctx := m.createContext(resp, &http.Request{Method: "GET"})
|
||||
So(ctx.Written(), ShouldBeFalse)
|
||||
|
||||
ctx.run()
|
||||
So(ctx.Written(), ShouldBeTrue)
|
||||
})
|
||||
}
|
||||
|
||||
func Test_Macaron_Basic_NoRace(t *testing.T) {
|
||||
Convey("Make sure no race between requests", t, func() {
|
||||
m := New()
|
||||
handlers := []Handler{func() {}, func() {}}
|
||||
// Ensure append will not realloc to trigger the race condition
|
||||
m.handlers = handlers[:1]
|
||||
m.Get("/", func() {})
|
||||
req, _ := http.NewRequest("GET", "/", nil)
|
||||
for i := 0; i < 2; i++ {
|
||||
go func() {
|
||||
resp := httptest.NewRecorder()
|
||||
m.ServeHTTP(resp, req)
|
||||
}()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func Test_SetENV(t *testing.T) {
|
||||
Convey("Get and save environment variable", t, func() {
|
||||
tests := []struct {
|
||||
in string
|
||||
out string
|
||||
}{
|
||||
{"", "development"},
|
||||
{"not_development", "not_development"},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
setENV(test.in)
|
||||
So(Env, ShouldEqual, test.out)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func Test_Config(t *testing.T) {
|
||||
Convey("Set and get configuration object", t, func() {
|
||||
So(Config(), ShouldNotBeNil)
|
||||
cfg, err := SetConfig([]byte(""))
|
||||
So(err, ShouldBeNil)
|
||||
So(cfg, ShouldNotBeNil)
|
||||
})
|
||||
}
|
||||
74
Godeps/_workspace/src/github.com/Unknwon/macaron/recovery_test.go
generated
vendored
74
Godeps/_workspace/src/github.com/Unknwon/macaron/recovery_test.go
generated
vendored
@@ -1,74 +0,0 @@
|
||||
// Copyright 2013 Martini Authors
|
||||
// Copyright 2014 Unknwon
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"): you may
|
||||
// not use this file except in compliance with the License. You may obtain
|
||||
// a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
// License for the specific language governing permissions and limitations
|
||||
// under the License.
|
||||
|
||||
package macaron
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"log"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
|
||||
. "github.com/smartystreets/goconvey/convey"
|
||||
)
|
||||
|
||||
func Test_Recovery(t *testing.T) {
|
||||
Convey("Recovery from panic", t, func() {
|
||||
buf := bytes.NewBufferString("")
|
||||
setENV(DEV)
|
||||
|
||||
m := New()
|
||||
m.Map(log.New(buf, "[Macaron] ", 0))
|
||||
m.Use(func(res http.ResponseWriter, req *http.Request) {
|
||||
res.Header().Set("Content-Type", "unpredictable")
|
||||
})
|
||||
m.Use(Recovery())
|
||||
m.Use(func(res http.ResponseWriter, req *http.Request) {
|
||||
panic("here is a panic!")
|
||||
})
|
||||
m.Get("/", func() {})
|
||||
|
||||
resp := httptest.NewRecorder()
|
||||
req, err := http.NewRequest("GET", "/", nil)
|
||||
So(err, ShouldBeNil)
|
||||
m.ServeHTTP(resp, req)
|
||||
So(resp.Code, ShouldEqual, http.StatusInternalServerError)
|
||||
So(resp.HeaderMap.Get("Content-Type"), ShouldEqual, "text/html")
|
||||
So(buf.String(), ShouldNotBeEmpty)
|
||||
})
|
||||
|
||||
Convey("Revocery panic to another response writer", t, func() {
|
||||
resp := httptest.NewRecorder()
|
||||
resp2 := httptest.NewRecorder()
|
||||
setENV(DEV)
|
||||
|
||||
m := New()
|
||||
m.Use(Recovery())
|
||||
m.Use(func(c *Context) {
|
||||
c.MapTo(resp2, (*http.ResponseWriter)(nil))
|
||||
panic("here is a panic!")
|
||||
})
|
||||
m.Get("/", func() {})
|
||||
|
||||
req, err := http.NewRequest("GET", "/", nil)
|
||||
So(err, ShouldBeNil)
|
||||
m.ServeHTTP(resp, req)
|
||||
|
||||
So(resp2.Code, ShouldEqual, http.StatusInternalServerError)
|
||||
So(resp2.HeaderMap.Get("Content-Type"), ShouldEqual, "text/html")
|
||||
So(resp2.Body.Len(), ShouldBeGreaterThan, 0)
|
||||
})
|
||||
}
|
||||
581
Godeps/_workspace/src/github.com/Unknwon/macaron/render_test.go
generated
vendored
581
Godeps/_workspace/src/github.com/Unknwon/macaron/render_test.go
generated
vendored
@@ -1,581 +0,0 @@
|
||||
// Copyright 2013 Martini Authors
|
||||
// Copyright 2014 Unknwon
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"): you may
|
||||
// not use this file except in compliance with the License. You may obtain
|
||||
// a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
// License for the specific language governing permissions and limitations
|
||||
// under the License.
|
||||
|
||||
package macaron
|
||||
|
||||
import (
|
||||
"encoding/xml"
|
||||
"html/template"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
. "github.com/smartystreets/goconvey/convey"
|
||||
)
|
||||
|
||||
type Greeting struct {
|
||||
One string `json:"one"`
|
||||
Two string `json:"two"`
|
||||
}
|
||||
|
||||
type GreetingXML struct {
|
||||
XMLName xml.Name `xml:"greeting"`
|
||||
One string `xml:"one,attr"`
|
||||
Two string `xml:"two,attr"`
|
||||
}
|
||||
|
||||
func Test_Render_JSON(t *testing.T) {
|
||||
Convey("Render JSON", t, func() {
|
||||
m := Classic()
|
||||
m.Use(Renderer())
|
||||
m.Get("/foobar", func(r Render) {
|
||||
r.JSON(300, Greeting{"hello", "world"})
|
||||
})
|
||||
|
||||
resp := httptest.NewRecorder()
|
||||
req, err := http.NewRequest("GET", "/foobar", nil)
|
||||
So(err, ShouldBeNil)
|
||||
m.ServeHTTP(resp, req)
|
||||
|
||||
So(resp.Code, ShouldEqual, http.StatusMultipleChoices)
|
||||
So(resp.Header().Get(ContentType), ShouldEqual, ContentJSON+"; charset=UTF-8")
|
||||
So(resp.Body.String(), ShouldEqual, `{"one":"hello","two":"world"}`)
|
||||
})
|
||||
|
||||
Convey("Render JSON with prefix", t, func() {
|
||||
m := Classic()
|
||||
prefix := ")]}',\n"
|
||||
m.Use(Renderer(RenderOptions{
|
||||
PrefixJSON: []byte(prefix),
|
||||
}))
|
||||
m.Get("/foobar", func(r Render) {
|
||||
r.JSON(300, Greeting{"hello", "world"})
|
||||
})
|
||||
|
||||
resp := httptest.NewRecorder()
|
||||
req, err := http.NewRequest("GET", "/foobar", nil)
|
||||
So(err, ShouldBeNil)
|
||||
m.ServeHTTP(resp, req)
|
||||
|
||||
So(resp.Code, ShouldEqual, http.StatusMultipleChoices)
|
||||
So(resp.Header().Get(ContentType), ShouldEqual, ContentJSON+"; charset=UTF-8")
|
||||
So(resp.Body.String(), ShouldEqual, prefix+`{"one":"hello","two":"world"}`)
|
||||
})
|
||||
|
||||
Convey("Render Indented JSON", t, func() {
|
||||
m := Classic()
|
||||
m.Use(Renderer(RenderOptions{
|
||||
IndentJSON: true,
|
||||
}))
|
||||
m.Get("/foobar", func(r Render) {
|
||||
r.JSON(300, Greeting{"hello", "world"})
|
||||
})
|
||||
|
||||
resp := httptest.NewRecorder()
|
||||
req, err := http.NewRequest("GET", "/foobar", nil)
|
||||
So(err, ShouldBeNil)
|
||||
m.ServeHTTP(resp, req)
|
||||
|
||||
So(resp.Code, ShouldEqual, http.StatusMultipleChoices)
|
||||
So(resp.Header().Get(ContentType), ShouldEqual, ContentJSON+"; charset=UTF-8")
|
||||
So(resp.Body.String(), ShouldEqual, `{
|
||||
"one": "hello",
|
||||
"two": "world"
|
||||
}`)
|
||||
})
|
||||
|
||||
Convey("Render JSON and return string", t, func() {
|
||||
m := Classic()
|
||||
m.Use(Renderer())
|
||||
m.Get("/foobar", func(r Render) {
|
||||
result, err := r.JSONString(Greeting{"hello", "world"})
|
||||
So(err, ShouldBeNil)
|
||||
So(result, ShouldEqual, `{"one":"hello","two":"world"}`)
|
||||
})
|
||||
|
||||
resp := httptest.NewRecorder()
|
||||
req, err := http.NewRequest("GET", "/foobar", nil)
|
||||
So(err, ShouldBeNil)
|
||||
m.ServeHTTP(resp, req)
|
||||
})
|
||||
|
||||
Convey("Render with charset JSON", t, func() {
|
||||
m := Classic()
|
||||
m.Use(Renderer(RenderOptions{
|
||||
Charset: "foobar",
|
||||
}))
|
||||
m.Get("/foobar", func(r Render) {
|
||||
r.JSON(300, Greeting{"hello", "world"})
|
||||
})
|
||||
|
||||
resp := httptest.NewRecorder()
|
||||
req, err := http.NewRequest("GET", "/foobar", nil)
|
||||
So(err, ShouldBeNil)
|
||||
m.ServeHTTP(resp, req)
|
||||
|
||||
So(resp.Code, ShouldEqual, http.StatusMultipleChoices)
|
||||
So(resp.Header().Get(ContentType), ShouldEqual, ContentJSON+"; charset=foobar")
|
||||
So(resp.Body.String(), ShouldEqual, `{"one":"hello","two":"world"}`)
|
||||
})
|
||||
}
|
||||
|
||||
func Test_Render_XML(t *testing.T) {
|
||||
Convey("Render XML", t, func() {
|
||||
m := Classic()
|
||||
m.Use(Renderer())
|
||||
m.Get("/foobar", func(r Render) {
|
||||
r.XML(300, GreetingXML{One: "hello", Two: "world"})
|
||||
})
|
||||
|
||||
resp := httptest.NewRecorder()
|
||||
req, err := http.NewRequest("GET", "/foobar", nil)
|
||||
So(err, ShouldBeNil)
|
||||
m.ServeHTTP(resp, req)
|
||||
|
||||
So(resp.Code, ShouldEqual, http.StatusMultipleChoices)
|
||||
So(resp.Header().Get(ContentType), ShouldEqual, ContentXML+"; charset=UTF-8")
|
||||
So(resp.Body.String(), ShouldEqual, `<greeting one="hello" two="world"></greeting>`)
|
||||
})
|
||||
|
||||
Convey("Render XML with prefix", t, func() {
|
||||
m := Classic()
|
||||
prefix := ")]}',\n"
|
||||
m.Use(Renderer(RenderOptions{
|
||||
PrefixXML: []byte(prefix),
|
||||
}))
|
||||
m.Get("/foobar", func(r Render) {
|
||||
r.XML(300, GreetingXML{One: "hello", Two: "world"})
|
||||
})
|
||||
|
||||
resp := httptest.NewRecorder()
|
||||
req, err := http.NewRequest("GET", "/foobar", nil)
|
||||
So(err, ShouldBeNil)
|
||||
m.ServeHTTP(resp, req)
|
||||
|
||||
So(resp.Code, ShouldEqual, http.StatusMultipleChoices)
|
||||
So(resp.Header().Get(ContentType), ShouldEqual, ContentXML+"; charset=UTF-8")
|
||||
So(resp.Body.String(), ShouldEqual, prefix+`<greeting one="hello" two="world"></greeting>`)
|
||||
})
|
||||
|
||||
Convey("Render Indented XML", t, func() {
|
||||
m := Classic()
|
||||
m.Use(Renderer(RenderOptions{
|
||||
IndentXML: true,
|
||||
}))
|
||||
m.Get("/foobar", func(r Render) {
|
||||
r.XML(300, GreetingXML{One: "hello", Two: "world"})
|
||||
})
|
||||
|
||||
resp := httptest.NewRecorder()
|
||||
req, err := http.NewRequest("GET", "/foobar", nil)
|
||||
So(err, ShouldBeNil)
|
||||
m.ServeHTTP(resp, req)
|
||||
|
||||
So(resp.Code, ShouldEqual, http.StatusMultipleChoices)
|
||||
So(resp.Header().Get(ContentType), ShouldEqual, ContentXML+"; charset=UTF-8")
|
||||
So(resp.Body.String(), ShouldEqual, `<greeting one="hello" two="world"></greeting>`)
|
||||
})
|
||||
}
|
||||
|
||||
func Test_Render_HTML(t *testing.T) {
|
||||
Convey("Render HTML", t, func() {
|
||||
m := Classic()
|
||||
m.Use(Renderers(RenderOptions{
|
||||
Directory: "fixtures/basic",
|
||||
}, "fixtures/basic2"))
|
||||
m.Get("/foobar", func(r Render) {
|
||||
r.HTML(200, "hello", "jeremy")
|
||||
r.SetTemplatePath("", "fixtures/basic2")
|
||||
})
|
||||
m.Get("/foobar2", func(r Render) {
|
||||
if r.HasTemplateSet("basic2") {
|
||||
r.HTMLSet(200, "basic2", "hello", "jeremy")
|
||||
}
|
||||
})
|
||||
|
||||
resp := httptest.NewRecorder()
|
||||
req, err := http.NewRequest("GET", "/foobar", nil)
|
||||
So(err, ShouldBeNil)
|
||||
m.ServeHTTP(resp, req)
|
||||
|
||||
So(resp.Code, ShouldEqual, http.StatusOK)
|
||||
So(resp.Header().Get(ContentType), ShouldEqual, ContentHTML+"; charset=UTF-8")
|
||||
So(resp.Body.String(), ShouldEqual, "<h1>Hello jeremy</h1>")
|
||||
|
||||
resp = httptest.NewRecorder()
|
||||
req, err = http.NewRequest("GET", "/foobar2", nil)
|
||||
So(err, ShouldBeNil)
|
||||
m.ServeHTTP(resp, req)
|
||||
|
||||
So(resp.Code, ShouldEqual, http.StatusOK)
|
||||
So(resp.Header().Get(ContentType), ShouldEqual, ContentHTML+"; charset=UTF-8")
|
||||
So(resp.Body.String(), ShouldEqual, "<h1>What's up, jeremy</h1>")
|
||||
|
||||
Convey("Change render templates path", func() {
|
||||
resp := httptest.NewRecorder()
|
||||
req, err := http.NewRequest("GET", "/foobar", nil)
|
||||
So(err, ShouldBeNil)
|
||||
m.ServeHTTP(resp, req)
|
||||
|
||||
So(resp.Code, ShouldEqual, http.StatusOK)
|
||||
So(resp.Header().Get(ContentType), ShouldEqual, ContentHTML+"; charset=UTF-8")
|
||||
So(resp.Body.String(), ShouldEqual, "<h1>What's up, jeremy</h1>")
|
||||
})
|
||||
})
|
||||
|
||||
Convey("Render HTML and return string", t, func() {
|
||||
m := Classic()
|
||||
m.Use(Renderers(RenderOptions{
|
||||
Directory: "fixtures/basic",
|
||||
}, "basic2:fixtures/basic2"))
|
||||
m.Get("/foobar", func(r Render) {
|
||||
result, err := r.HTMLString("hello", "jeremy")
|
||||
So(err, ShouldBeNil)
|
||||
So(result, ShouldEqual, "<h1>Hello jeremy</h1>")
|
||||
})
|
||||
m.Get("/foobar2", func(r Render) {
|
||||
result, err := r.HTMLSetString("basic2", "hello", "jeremy")
|
||||
So(err, ShouldBeNil)
|
||||
So(result, ShouldEqual, "<h1>What's up, jeremy</h1>")
|
||||
})
|
||||
|
||||
resp := httptest.NewRecorder()
|
||||
req, err := http.NewRequest("GET", "/foobar", nil)
|
||||
So(err, ShouldBeNil)
|
||||
m.ServeHTTP(resp, req)
|
||||
|
||||
resp = httptest.NewRecorder()
|
||||
req, err = http.NewRequest("GET", "/foobar2", nil)
|
||||
So(err, ShouldBeNil)
|
||||
m.ServeHTTP(resp, req)
|
||||
})
|
||||
|
||||
Convey("Render with nested HTML", t, func() {
|
||||
m := Classic()
|
||||
m.Use(Renderer(RenderOptions{
|
||||
Directory: "fixtures/basic",
|
||||
}))
|
||||
m.Get("/foobar", func(r Render) {
|
||||
r.HTML(200, "admin/index", "jeremy")
|
||||
})
|
||||
|
||||
resp := httptest.NewRecorder()
|
||||
req, err := http.NewRequest("GET", "/foobar", nil)
|
||||
So(err, ShouldBeNil)
|
||||
m.ServeHTTP(resp, req)
|
||||
|
||||
So(resp.Code, ShouldEqual, http.StatusOK)
|
||||
So(resp.Header().Get(ContentType), ShouldEqual, ContentHTML+"; charset=UTF-8")
|
||||
So(resp.Body.String(), ShouldEqual, "<h1>Admin jeremy</h1>")
|
||||
})
|
||||
|
||||
Convey("Render bad HTML", t, func() {
|
||||
m := Classic()
|
||||
m.Use(Renderer(RenderOptions{
|
||||
Directory: "fixtures/basic",
|
||||
}))
|
||||
m.Get("/foobar", func(r Render) {
|
||||
r.HTML(200, "nope", nil)
|
||||
})
|
||||
|
||||
resp := httptest.NewRecorder()
|
||||
req, err := http.NewRequest("GET", "/foobar", nil)
|
||||
So(err, ShouldBeNil)
|
||||
m.ServeHTTP(resp, req)
|
||||
|
||||
So(resp.Code, ShouldEqual, http.StatusInternalServerError)
|
||||
So(resp.Body.String(), ShouldEqual, "html/template: \"nope\" is undefined\n")
|
||||
})
|
||||
|
||||
Convey("Invalid template set", t, func() {
|
||||
Convey("Empty template set argument", func() {
|
||||
defer func() {
|
||||
So(recover(), ShouldNotBeNil)
|
||||
}()
|
||||
m := Classic()
|
||||
m.Use(Renderers(RenderOptions{
|
||||
Directory: "fixtures/basic",
|
||||
}, ""))
|
||||
})
|
||||
|
||||
Convey("Bad template set path", func() {
|
||||
defer func() {
|
||||
So(recover(), ShouldNotBeNil)
|
||||
}()
|
||||
m := Classic()
|
||||
m.Use(Renderers(RenderOptions{
|
||||
Directory: "fixtures/basic",
|
||||
}, "404"))
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func Test_Render_XHTML(t *testing.T) {
|
||||
Convey("Render XHTML", t, func() {
|
||||
m := Classic()
|
||||
m.Use(Renderer(RenderOptions{
|
||||
Directory: "fixtures/basic",
|
||||
HTMLContentType: ContentXHTML,
|
||||
}))
|
||||
m.Get("/foobar", func(r Render) {
|
||||
r.HTML(200, "hello", "jeremy")
|
||||
})
|
||||
|
||||
resp := httptest.NewRecorder()
|
||||
req, err := http.NewRequest("GET", "/foobar", nil)
|
||||
So(err, ShouldBeNil)
|
||||
m.ServeHTTP(resp, req)
|
||||
|
||||
So(resp.Code, ShouldEqual, http.StatusOK)
|
||||
So(resp.Header().Get(ContentType), ShouldEqual, ContentXHTML+"; charset=UTF-8")
|
||||
So(resp.Body.String(), ShouldEqual, "<h1>Hello jeremy</h1>")
|
||||
})
|
||||
}
|
||||
|
||||
func Test_Render_Extensions(t *testing.T) {
|
||||
Convey("Render with extensions", t, func() {
|
||||
m := Classic()
|
||||
m.Use(Renderer(RenderOptions{
|
||||
Directory: "fixtures/basic",
|
||||
Extensions: []string{".tmpl", ".html"},
|
||||
}))
|
||||
m.Get("/foobar", func(r Render) {
|
||||
r.HTML(200, "hypertext", nil)
|
||||
})
|
||||
|
||||
resp := httptest.NewRecorder()
|
||||
req, err := http.NewRequest("GET", "/foobar", nil)
|
||||
So(err, ShouldBeNil)
|
||||
m.ServeHTTP(resp, req)
|
||||
|
||||
So(resp.Code, ShouldEqual, http.StatusOK)
|
||||
So(resp.Header().Get(ContentType), ShouldEqual, ContentHTML+"; charset=UTF-8")
|
||||
So(resp.Body.String(), ShouldEqual, "Hypertext!")
|
||||
})
|
||||
}
|
||||
|
||||
func Test_Render_Funcs(t *testing.T) {
|
||||
Convey("Render with functions", t, func() {
|
||||
m := Classic()
|
||||
m.Use(Renderer(RenderOptions{
|
||||
Directory: "fixtures/custom_funcs",
|
||||
Funcs: []template.FuncMap{
|
||||
{
|
||||
"myCustomFunc": func() string {
|
||||
return "My custom function"
|
||||
},
|
||||
},
|
||||
},
|
||||
}))
|
||||
m.Get("/foobar", func(r Render) {
|
||||
r.HTML(200, "index", "jeremy")
|
||||
})
|
||||
|
||||
resp := httptest.NewRecorder()
|
||||
req, err := http.NewRequest("GET", "/foobar", nil)
|
||||
So(err, ShouldBeNil)
|
||||
m.ServeHTTP(resp, req)
|
||||
|
||||
So(resp.Body.String(), ShouldEqual, "My custom function")
|
||||
})
|
||||
}
|
||||
|
||||
func Test_Render_Layout(t *testing.T) {
|
||||
Convey("Render with layout", t, func() {
|
||||
m := Classic()
|
||||
m.Use(Renderer(RenderOptions{
|
||||
Directory: "fixtures/basic",
|
||||
Layout: "layout",
|
||||
}))
|
||||
m.Get("/foobar", func(r Render) {
|
||||
r.HTML(200, "content", "jeremy")
|
||||
})
|
||||
|
||||
resp := httptest.NewRecorder()
|
||||
req, err := http.NewRequest("GET", "/foobar", nil)
|
||||
So(err, ShouldBeNil)
|
||||
m.ServeHTTP(resp, req)
|
||||
|
||||
So(resp.Body.String(), ShouldEqual, "head<h1>jeremy</h1>foot")
|
||||
})
|
||||
|
||||
Convey("Render with current layout", t, func() {
|
||||
m := Classic()
|
||||
m.Use(Renderer(RenderOptions{
|
||||
Directory: "fixtures/basic",
|
||||
Layout: "current_layout",
|
||||
}))
|
||||
m.Get("/foobar", func(r Render) {
|
||||
r.HTML(200, "content", "jeremy")
|
||||
})
|
||||
|
||||
resp := httptest.NewRecorder()
|
||||
req, err := http.NewRequest("GET", "/foobar", nil)
|
||||
So(err, ShouldBeNil)
|
||||
m.ServeHTTP(resp, req)
|
||||
|
||||
So(resp.Body.String(), ShouldEqual, "content head<h1>jeremy</h1>content foot")
|
||||
})
|
||||
|
||||
Convey("Render with override layout", t, func() {
|
||||
m := Classic()
|
||||
m.Use(Renderer(RenderOptions{
|
||||
Directory: "fixtures/basic",
|
||||
Layout: "layout",
|
||||
}))
|
||||
m.Get("/foobar", func(r Render) {
|
||||
r.HTML(200, "content", "jeremy", HTMLOptions{
|
||||
Layout: "another_layout",
|
||||
})
|
||||
})
|
||||
|
||||
resp := httptest.NewRecorder()
|
||||
req, err := http.NewRequest("GET", "/foobar", nil)
|
||||
So(err, ShouldBeNil)
|
||||
m.ServeHTTP(resp, req)
|
||||
|
||||
So(resp.Code, ShouldEqual, http.StatusOK)
|
||||
So(resp.Header().Get(ContentType), ShouldEqual, ContentHTML+"; charset=UTF-8")
|
||||
So(resp.Body.String(), ShouldEqual, "another head<h1>jeremy</h1>another foot")
|
||||
})
|
||||
}
|
||||
|
||||
func Test_Render_Delimiters(t *testing.T) {
|
||||
Convey("Render with delimiters", t, func() {
|
||||
m := Classic()
|
||||
m.Use(Renderer(RenderOptions{
|
||||
Delims: Delims{"{[{", "}]}"},
|
||||
Directory: "fixtures/basic",
|
||||
}))
|
||||
m.Get("/foobar", func(r Render) {
|
||||
r.HTML(200, "delims", "jeremy")
|
||||
})
|
||||
|
||||
resp := httptest.NewRecorder()
|
||||
req, err := http.NewRequest("GET", "/foobar", nil)
|
||||
So(err, ShouldBeNil)
|
||||
m.ServeHTTP(resp, req)
|
||||
|
||||
So(resp.Code, ShouldEqual, http.StatusOK)
|
||||
So(resp.Header().Get(ContentType), ShouldEqual, ContentHTML+"; charset=UTF-8")
|
||||
So(resp.Body.String(), ShouldEqual, "<h1>Hello jeremy</h1>")
|
||||
})
|
||||
}
|
||||
|
||||
func Test_Render_BinaryData(t *testing.T) {
|
||||
Convey("Render binary data", t, func() {
|
||||
m := Classic()
|
||||
m.Use(Renderer())
|
||||
m.Get("/foobar", func(r Render) {
|
||||
r.RawData(200, []byte("hello there"))
|
||||
})
|
||||
m.Get("/foobar2", func(r Render) {
|
||||
r.RenderData(200, []byte("hello there"))
|
||||
})
|
||||
|
||||
resp := httptest.NewRecorder()
|
||||
req, err := http.NewRequest("GET", "/foobar", nil)
|
||||
So(err, ShouldBeNil)
|
||||
m.ServeHTTP(resp, req)
|
||||
|
||||
So(resp.Code, ShouldEqual, http.StatusOK)
|
||||
So(resp.Header().Get(ContentType), ShouldEqual, ContentBinary)
|
||||
So(resp.Body.String(), ShouldEqual, "hello there")
|
||||
|
||||
resp = httptest.NewRecorder()
|
||||
req, err = http.NewRequest("GET", "/foobar2", nil)
|
||||
So(err, ShouldBeNil)
|
||||
m.ServeHTTP(resp, req)
|
||||
|
||||
So(resp.Code, ShouldEqual, http.StatusOK)
|
||||
So(resp.Header().Get(ContentType), ShouldEqual, CONTENT_PLAIN)
|
||||
So(resp.Body.String(), ShouldEqual, "hello there")
|
||||
})
|
||||
|
||||
Convey("Render binary data with mime type", t, func() {
|
||||
m := Classic()
|
||||
m.Use(Renderer())
|
||||
m.Get("/foobar", func(r Render) {
|
||||
r.RW().Header().Set(ContentType, "image/jpeg")
|
||||
r.RawData(200, []byte("..jpeg data.."))
|
||||
})
|
||||
|
||||
resp := httptest.NewRecorder()
|
||||
req, err := http.NewRequest("GET", "/foobar", nil)
|
||||
So(err, ShouldBeNil)
|
||||
m.ServeHTTP(resp, req)
|
||||
|
||||
So(resp.Code, ShouldEqual, http.StatusOK)
|
||||
So(resp.Header().Get(ContentType), ShouldEqual, "image/jpeg")
|
||||
So(resp.Body.String(), ShouldEqual, "..jpeg data..")
|
||||
})
|
||||
}
|
||||
|
||||
func Test_Render_Status(t *testing.T) {
|
||||
Convey("Render with status 204", t, func() {
|
||||
resp := httptest.NewRecorder()
|
||||
r := TplRender{resp, newTemplateSet(), &RenderOptions{}, "", time.Now()}
|
||||
r.Status(204)
|
||||
So(resp.Code, ShouldEqual, http.StatusNoContent)
|
||||
})
|
||||
|
||||
Convey("Render with status 404", t, func() {
|
||||
resp := httptest.NewRecorder()
|
||||
r := TplRender{resp, newTemplateSet(), &RenderOptions{}, "", time.Now()}
|
||||
r.Error(404)
|
||||
So(resp.Code, ShouldEqual, http.StatusNotFound)
|
||||
})
|
||||
|
||||
Convey("Render with status 500", t, func() {
|
||||
resp := httptest.NewRecorder()
|
||||
r := TplRender{resp, newTemplateSet(), &RenderOptions{}, "", time.Now()}
|
||||
r.Error(500)
|
||||
So(resp.Code, ShouldEqual, http.StatusInternalServerError)
|
||||
})
|
||||
}
|
||||
|
||||
func Test_Render_NoRace(t *testing.T) {
|
||||
Convey("Make sure render has no race", t, func() {
|
||||
m := Classic()
|
||||
m.Use(Renderer(RenderOptions{
|
||||
Directory: "fixtures/basic",
|
||||
}))
|
||||
m.Get("/foobar", func(r Render) {
|
||||
r.HTML(200, "hello", "world")
|
||||
})
|
||||
|
||||
done := make(chan bool)
|
||||
doreq := func() {
|
||||
resp := httptest.NewRecorder()
|
||||
req, _ := http.NewRequest("GET", "/foobar", nil)
|
||||
m.ServeHTTP(resp, req)
|
||||
done <- true
|
||||
}
|
||||
// Run two requests to check there is no race condition
|
||||
go doreq()
|
||||
go doreq()
|
||||
<-done
|
||||
<-done
|
||||
})
|
||||
}
|
||||
|
||||
func Test_GetExt(t *testing.T) {
|
||||
Convey("Get extension", t, func() {
|
||||
So(GetExt("test"), ShouldBeBlank)
|
||||
So(GetExt("test.tmpl"), ShouldEqual, ".tmpl")
|
||||
So(GetExt("test.go.tmpl"), ShouldEqual, ".go.tmpl")
|
||||
})
|
||||
}
|
||||
188
Godeps/_workspace/src/github.com/Unknwon/macaron/response_writer_test.go
generated
vendored
188
Godeps/_workspace/src/github.com/Unknwon/macaron/response_writer_test.go
generated
vendored
@@ -1,188 +0,0 @@
|
||||
// Copyright 2013 Martini Authors
|
||||
// Copyright 2014 Unknwon
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"): you may
|
||||
// not use this file except in compliance with the License. You may obtain
|
||||
// a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
// License for the specific language governing permissions and limitations
|
||||
// under the License.
|
||||
|
||||
package macaron
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"io"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
. "github.com/smartystreets/goconvey/convey"
|
||||
)
|
||||
|
||||
type closeNotifyingRecorder struct {
|
||||
*httptest.ResponseRecorder
|
||||
closed chan bool
|
||||
}
|
||||
|
||||
func newCloseNotifyingRecorder() *closeNotifyingRecorder {
|
||||
return &closeNotifyingRecorder{
|
||||
httptest.NewRecorder(),
|
||||
make(chan bool, 1),
|
||||
}
|
||||
}
|
||||
|
||||
func (c *closeNotifyingRecorder) close() {
|
||||
c.closed <- true
|
||||
}
|
||||
|
||||
func (c *closeNotifyingRecorder) CloseNotify() <-chan bool {
|
||||
return c.closed
|
||||
}
|
||||
|
||||
type hijackableResponse struct {
|
||||
Hijacked bool
|
||||
}
|
||||
|
||||
func newHijackableResponse() *hijackableResponse {
|
||||
return &hijackableResponse{}
|
||||
}
|
||||
|
||||
func (h *hijackableResponse) Header() http.Header { return nil }
|
||||
func (h *hijackableResponse) Write(buf []byte) (int, error) { return 0, nil }
|
||||
func (h *hijackableResponse) WriteHeader(code int) {}
|
||||
func (h *hijackableResponse) Flush() {}
|
||||
func (h *hijackableResponse) Hijack() (net.Conn, *bufio.ReadWriter, error) {
|
||||
h.Hijacked = true
|
||||
return nil, nil, nil
|
||||
}
|
||||
|
||||
func Test_ResponseWriter(t *testing.T) {
|
||||
Convey("Write string to response writer", t, func() {
|
||||
resp := httptest.NewRecorder()
|
||||
rw := NewResponseWriter(resp)
|
||||
rw.Write([]byte("Hello world"))
|
||||
|
||||
So(resp.Code, ShouldEqual, rw.Status())
|
||||
So(resp.Body.String(), ShouldEqual, "Hello world")
|
||||
So(rw.Status(), ShouldEqual, http.StatusOK)
|
||||
So(rw.Size(), ShouldEqual, 11)
|
||||
So(rw.Written(), ShouldBeTrue)
|
||||
})
|
||||
|
||||
Convey("Write strings to response writer", t, func() {
|
||||
resp := httptest.NewRecorder()
|
||||
rw := NewResponseWriter(resp)
|
||||
rw.Write([]byte("Hello world"))
|
||||
rw.Write([]byte("foo bar bat baz"))
|
||||
|
||||
So(resp.Code, ShouldEqual, rw.Status())
|
||||
So(resp.Body.String(), ShouldEqual, "Hello worldfoo bar bat baz")
|
||||
So(rw.Status(), ShouldEqual, http.StatusOK)
|
||||
So(rw.Size(), ShouldEqual, 26)
|
||||
So(rw.Written(), ShouldBeTrue)
|
||||
})
|
||||
|
||||
Convey("Write header to response writer", t, func() {
|
||||
resp := httptest.NewRecorder()
|
||||
rw := NewResponseWriter(resp)
|
||||
rw.WriteHeader(http.StatusNotFound)
|
||||
|
||||
So(resp.Code, ShouldEqual, rw.Status())
|
||||
So(resp.Body.String(), ShouldBeBlank)
|
||||
So(rw.Status(), ShouldEqual, http.StatusNotFound)
|
||||
So(rw.Size(), ShouldEqual, 0)
|
||||
})
|
||||
|
||||
Convey("Write before response write", t, func() {
|
||||
result := ""
|
||||
resp := httptest.NewRecorder()
|
||||
rw := NewResponseWriter(resp)
|
||||
rw.Before(func(ResponseWriter) {
|
||||
result += "foo"
|
||||
})
|
||||
rw.Before(func(ResponseWriter) {
|
||||
result += "bar"
|
||||
})
|
||||
rw.WriteHeader(http.StatusNotFound)
|
||||
|
||||
So(resp.Code, ShouldEqual, rw.Status())
|
||||
So(resp.Body.String(), ShouldBeBlank)
|
||||
So(rw.Status(), ShouldEqual, http.StatusNotFound)
|
||||
So(rw.Size(), ShouldEqual, 0)
|
||||
So(result, ShouldEqual, "barfoo")
|
||||
})
|
||||
|
||||
Convey("Response writer with Hijack", t, func() {
|
||||
hijackable := newHijackableResponse()
|
||||
rw := NewResponseWriter(hijackable)
|
||||
hijacker, ok := rw.(http.Hijacker)
|
||||
So(ok, ShouldBeTrue)
|
||||
_, _, err := hijacker.Hijack()
|
||||
So(err, ShouldBeNil)
|
||||
So(hijackable.Hijacked, ShouldBeTrue)
|
||||
})
|
||||
|
||||
Convey("Response writer with bad Hijack", t, func() {
|
||||
hijackable := new(http.ResponseWriter)
|
||||
rw := NewResponseWriter(*hijackable)
|
||||
hijacker, ok := rw.(http.Hijacker)
|
||||
So(ok, ShouldBeTrue)
|
||||
_, _, err := hijacker.Hijack()
|
||||
So(err, ShouldNotBeNil)
|
||||
})
|
||||
|
||||
Convey("Response writer with close notify", t, func() {
|
||||
resp := newCloseNotifyingRecorder()
|
||||
rw := NewResponseWriter(resp)
|
||||
closed := false
|
||||
notifier := rw.(http.CloseNotifier).CloseNotify()
|
||||
resp.close()
|
||||
select {
|
||||
case <-notifier:
|
||||
closed = true
|
||||
case <-time.After(time.Second):
|
||||
}
|
||||
So(closed, ShouldBeTrue)
|
||||
})
|
||||
|
||||
Convey("Response writer with flusher", t, func() {
|
||||
resp := httptest.NewRecorder()
|
||||
rw := NewResponseWriter(resp)
|
||||
_, ok := rw.(http.Flusher)
|
||||
So(ok, ShouldBeTrue)
|
||||
})
|
||||
|
||||
Convey("Response writer with flusher handler", t, func() {
|
||||
m := Classic()
|
||||
m.Get("/events", func(w http.ResponseWriter, r *http.Request) {
|
||||
f, ok := w.(http.Flusher)
|
||||
So(ok, ShouldBeTrue)
|
||||
|
||||
w.Header().Set("Content-Type", "text/event-stream")
|
||||
w.Header().Set("Cache-Control", "no-cache")
|
||||
w.Header().Set("Connection", "keep-alive")
|
||||
|
||||
for i := 0; i < 2; i++ {
|
||||
time.Sleep(10 * time.Millisecond)
|
||||
io.WriteString(w, "data: Hello\n\n")
|
||||
f.Flush()
|
||||
}
|
||||
})
|
||||
|
||||
resp := httptest.NewRecorder()
|
||||
req, err := http.NewRequest("GET", "/events", nil)
|
||||
So(err, ShouldBeNil)
|
||||
m.ServeHTTP(resp, req)
|
||||
|
||||
So(resp.Code, ShouldEqual, http.StatusOK)
|
||||
So(resp.Body.String(), ShouldEqual, "data: Hello\n\ndata: Hello\n\n")
|
||||
})
|
||||
}
|
||||
69
Godeps/_workspace/src/github.com/Unknwon/macaron/return_handler_test.go
generated
vendored
69
Godeps/_workspace/src/github.com/Unknwon/macaron/return_handler_test.go
generated
vendored
@@ -1,69 +0,0 @@
|
||||
// Copyright 2014 Unknwon
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"): you may
|
||||
// not use this file except in compliance with the License. You may obtain
|
||||
// a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
// License for the specific language governing permissions and limitations
|
||||
// under the License.
|
||||
|
||||
package macaron
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
|
||||
. "github.com/smartystreets/goconvey/convey"
|
||||
)
|
||||
|
||||
func Test_Return_Handler(t *testing.T) {
|
||||
Convey("Return with status and body", t, func() {
|
||||
m := Classic()
|
||||
m.Get("/", func() (int, string) {
|
||||
return 418, "i'm a teapot"
|
||||
})
|
||||
|
||||
resp := httptest.NewRecorder()
|
||||
req, err := http.NewRequest("GET", "/", nil)
|
||||
So(err, ShouldBeNil)
|
||||
m.ServeHTTP(resp, req)
|
||||
|
||||
So(resp.Code, ShouldEqual, http.StatusTeapot)
|
||||
So(resp.Body.String(), ShouldEqual, "i'm a teapot")
|
||||
})
|
||||
|
||||
Convey("Return with pointer", t, func() {
|
||||
m := Classic()
|
||||
m.Get("/", func() *string {
|
||||
str := "hello world"
|
||||
return &str
|
||||
})
|
||||
|
||||
resp := httptest.NewRecorder()
|
||||
req, err := http.NewRequest("GET", "/", nil)
|
||||
So(err, ShouldBeNil)
|
||||
m.ServeHTTP(resp, req)
|
||||
|
||||
So(resp.Body.String(), ShouldEqual, "hello world")
|
||||
})
|
||||
|
||||
Convey("Return with byte slice", t, func() {
|
||||
m := Classic()
|
||||
m.Get("/", func() []byte {
|
||||
return []byte("hello world")
|
||||
})
|
||||
|
||||
resp := httptest.NewRecorder()
|
||||
req, err := http.NewRequest("GET", "/", nil)
|
||||
So(err, ShouldBeNil)
|
||||
m.ServeHTTP(resp, req)
|
||||
|
||||
So(resp.Body.String(), ShouldEqual, "hello world")
|
||||
})
|
||||
}
|
||||
199
Godeps/_workspace/src/github.com/Unknwon/macaron/router_test.go
generated
vendored
199
Godeps/_workspace/src/github.com/Unknwon/macaron/router_test.go
generated
vendored
@@ -1,199 +0,0 @@
|
||||
// Copyright 2014 Unknwon
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"): you may
|
||||
// not use this file except in compliance with the License. You may obtain
|
||||
// a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
// License for the specific language governing permissions and limitations
|
||||
// under the License.
|
||||
|
||||
package macaron
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
|
||||
. "github.com/smartystreets/goconvey/convey"
|
||||
)
|
||||
|
||||
func Test_Router_Handle(t *testing.T) {
|
||||
Convey("Register all HTTP methods routes", t, func() {
|
||||
m := Classic()
|
||||
m.Get("/get", func() string {
|
||||
return "GET"
|
||||
})
|
||||
resp := httptest.NewRecorder()
|
||||
req, err := http.NewRequest("GET", "/get", nil)
|
||||
So(err, ShouldBeNil)
|
||||
m.ServeHTTP(resp, req)
|
||||
So(resp.Body.String(), ShouldEqual, "GET")
|
||||
|
||||
m.Patch("/patch", func() string {
|
||||
return "PATCH"
|
||||
})
|
||||
resp = httptest.NewRecorder()
|
||||
req, err = http.NewRequest("PATCH", "/patch", nil)
|
||||
So(err, ShouldBeNil)
|
||||
m.ServeHTTP(resp, req)
|
||||
So(resp.Body.String(), ShouldEqual, "PATCH")
|
||||
|
||||
m.Post("/post", func() string {
|
||||
return "POST"
|
||||
})
|
||||
resp = httptest.NewRecorder()
|
||||
req, err = http.NewRequest("POST", "/post", nil)
|
||||
So(err, ShouldBeNil)
|
||||
m.ServeHTTP(resp, req)
|
||||
So(resp.Body.String(), ShouldEqual, "POST")
|
||||
|
||||
m.Put("/put", func() string {
|
||||
return "PUT"
|
||||
})
|
||||
resp = httptest.NewRecorder()
|
||||
req, err = http.NewRequest("PUT", "/put", nil)
|
||||
So(err, ShouldBeNil)
|
||||
m.ServeHTTP(resp, req)
|
||||
So(resp.Body.String(), ShouldEqual, "PUT")
|
||||
|
||||
m.Delete("/delete", func() string {
|
||||
return "DELETE"
|
||||
})
|
||||
resp = httptest.NewRecorder()
|
||||
req, err = http.NewRequest("DELETE", "/delete", nil)
|
||||
So(err, ShouldBeNil)
|
||||
m.ServeHTTP(resp, req)
|
||||
So(resp.Body.String(), ShouldEqual, "DELETE")
|
||||
|
||||
m.Options("/options", func() string {
|
||||
return "OPTIONS"
|
||||
})
|
||||
resp = httptest.NewRecorder()
|
||||
req, err = http.NewRequest("OPTIONS", "/options", nil)
|
||||
So(err, ShouldBeNil)
|
||||
m.ServeHTTP(resp, req)
|
||||
So(resp.Body.String(), ShouldEqual, "OPTIONS")
|
||||
|
||||
m.Head("/head", func() string {
|
||||
return "HEAD"
|
||||
})
|
||||
resp = httptest.NewRecorder()
|
||||
req, err = http.NewRequest("HEAD", "/head", nil)
|
||||
So(err, ShouldBeNil)
|
||||
m.ServeHTTP(resp, req)
|
||||
So(resp.Body.String(), ShouldEqual, "HEAD")
|
||||
|
||||
m.Any("/any", func() string {
|
||||
return "ANY"
|
||||
})
|
||||
resp = httptest.NewRecorder()
|
||||
req, err = http.NewRequest("GET", "/any", nil)
|
||||
So(err, ShouldBeNil)
|
||||
m.ServeHTTP(resp, req)
|
||||
So(resp.Body.String(), ShouldEqual, "ANY")
|
||||
|
||||
m.Route("/route", "GET,POST", func() string {
|
||||
return "ROUTE"
|
||||
})
|
||||
resp = httptest.NewRecorder()
|
||||
req, err = http.NewRequest("POST", "/route", nil)
|
||||
So(err, ShouldBeNil)
|
||||
m.ServeHTTP(resp, req)
|
||||
So(resp.Body.String(), ShouldEqual, "ROUTE")
|
||||
})
|
||||
|
||||
Convey("Register all HTTP methods routes with combo", t, func() {
|
||||
m := Classic()
|
||||
m.SetURLPrefix("/prefix")
|
||||
m.Use(Renderer())
|
||||
m.Combo("/", func(ctx *Context) {
|
||||
ctx.Data["prefix"] = "Prefix_"
|
||||
}).
|
||||
Get(func(ctx *Context) string { return ctx.Data["prefix"].(string) + "GET" }).
|
||||
Patch(func(ctx *Context) string { return ctx.Data["prefix"].(string) + "PATCH" }).
|
||||
Post(func(ctx *Context) string { return ctx.Data["prefix"].(string) + "POST" }).
|
||||
Put(func(ctx *Context) string { return ctx.Data["prefix"].(string) + "PUT" }).
|
||||
Delete(func(ctx *Context) string { return ctx.Data["prefix"].(string) + "DELETE" }).
|
||||
Options(func(ctx *Context) string { return ctx.Data["prefix"].(string) + "OPTIONS" }).
|
||||
Head(func(ctx *Context) string { return ctx.Data["prefix"].(string) + "HEAD" })
|
||||
|
||||
for name := range _HTTP_METHODS {
|
||||
resp := httptest.NewRecorder()
|
||||
req, err := http.NewRequest(name, "/", nil)
|
||||
So(err, ShouldBeNil)
|
||||
m.ServeHTTP(resp, req)
|
||||
So(resp.Body.String(), ShouldEqual, "Prefix_"+name)
|
||||
}
|
||||
|
||||
defer func() {
|
||||
So(recover(), ShouldNotBeNil)
|
||||
}()
|
||||
m.Combo("/").Get(func() {}).Get(nil)
|
||||
})
|
||||
|
||||
Convey("Register duplicated routes", t, func() {
|
||||
r := NewRouter()
|
||||
r.Get("/")
|
||||
r.Get("/")
|
||||
})
|
||||
|
||||
Convey("Register invalid HTTP method", t, func() {
|
||||
defer func() {
|
||||
So(recover(), ShouldNotBeNil)
|
||||
}()
|
||||
r := NewRouter()
|
||||
r.Handle("404", "/", nil)
|
||||
})
|
||||
}
|
||||
|
||||
func Test_Router_Group(t *testing.T) {
|
||||
Convey("Register route group", t, func() {
|
||||
m := Classic()
|
||||
m.Group("/api", func() {
|
||||
m.Group("/v1", func() {
|
||||
m.Get("/list", func() string {
|
||||
return "Well done!"
|
||||
})
|
||||
})
|
||||
})
|
||||
resp := httptest.NewRecorder()
|
||||
req, err := http.NewRequest("GET", "/api/v1/list", nil)
|
||||
So(err, ShouldBeNil)
|
||||
m.ServeHTTP(resp, req)
|
||||
So(resp.Body.String(), ShouldEqual, "Well done!")
|
||||
})
|
||||
}
|
||||
|
||||
func Test_Router_NotFound(t *testing.T) {
|
||||
Convey("Custom not found handler", t, func() {
|
||||
m := Classic()
|
||||
m.Get("/", func() {})
|
||||
m.NotFound(func() string {
|
||||
return "Custom not found"
|
||||
})
|
||||
resp := httptest.NewRecorder()
|
||||
req, err := http.NewRequest("GET", "/404", nil)
|
||||
So(err, ShouldBeNil)
|
||||
m.ServeHTTP(resp, req)
|
||||
So(resp.Body.String(), ShouldEqual, "Custom not found")
|
||||
})
|
||||
}
|
||||
|
||||
func Test_Router_splat(t *testing.T) {
|
||||
Convey("Register router with glob", t, func() {
|
||||
m := Classic()
|
||||
m.Get("/*", func(ctx *Context) string {
|
||||
return ctx.Params("*")
|
||||
})
|
||||
resp := httptest.NewRecorder()
|
||||
req, err := http.NewRequest("GET", "/hahaha", nil)
|
||||
So(err, ShouldBeNil)
|
||||
m.ServeHTTP(resp, req)
|
||||
So(resp.Body.String(), ShouldEqual, "hahaha")
|
||||
})
|
||||
}
|
||||
246
Godeps/_workspace/src/github.com/Unknwon/macaron/static_test.go
generated
vendored
246
Godeps/_workspace/src/github.com/Unknwon/macaron/static_test.go
generated
vendored
@@ -1,246 +0,0 @@
|
||||
// Copyright 2013 Martini Authors
|
||||
// Copyright 2014 Unknwon
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"): you may
|
||||
// not use this file except in compliance with the License. You may obtain
|
||||
// a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
// License for the specific language governing permissions and limitations
|
||||
// under the License.
|
||||
|
||||
package macaron
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"os"
|
||||
"path"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
. "github.com/smartystreets/goconvey/convey"
|
||||
)
|
||||
|
||||
var currentRoot, _ = os.Getwd()
|
||||
|
||||
func Test_Static(t *testing.T) {
|
||||
Convey("Serve static files", t, func() {
|
||||
m := New()
|
||||
m.Use(Static("./"))
|
||||
|
||||
resp := httptest.NewRecorder()
|
||||
resp.Body = new(bytes.Buffer)
|
||||
req, err := http.NewRequest("GET", "http://localhost:4000/macaron.go", nil)
|
||||
So(err, ShouldBeNil)
|
||||
m.ServeHTTP(resp, req)
|
||||
So(resp.Code, ShouldEqual, http.StatusOK)
|
||||
So(resp.Header().Get("Expires"), ShouldBeBlank)
|
||||
So(resp.Body.Len(), ShouldBeGreaterThan, 0)
|
||||
|
||||
Convey("Change static path", func() {
|
||||
m.Get("/", func(ctx *Context) {
|
||||
ctx.ChangeStaticPath("./", "inject")
|
||||
})
|
||||
|
||||
resp := httptest.NewRecorder()
|
||||
req, err := http.NewRequest("GET", "/", nil)
|
||||
So(err, ShouldBeNil)
|
||||
m.ServeHTTP(resp, req)
|
||||
|
||||
resp = httptest.NewRecorder()
|
||||
resp.Body = new(bytes.Buffer)
|
||||
req, err = http.NewRequest("GET", "http://localhost:4000/inject.go", nil)
|
||||
So(err, ShouldBeNil)
|
||||
m.ServeHTTP(resp, req)
|
||||
So(resp.Code, ShouldEqual, http.StatusOK)
|
||||
So(resp.Header().Get("Expires"), ShouldBeBlank)
|
||||
So(resp.Body.Len(), ShouldBeGreaterThan, 0)
|
||||
})
|
||||
})
|
||||
|
||||
Convey("Serve static files with local path", t, func() {
|
||||
Root = os.TempDir()
|
||||
f, err := ioutil.TempFile(Root, "static_content")
|
||||
So(err, ShouldBeNil)
|
||||
f.WriteString("Expected Content")
|
||||
f.Close()
|
||||
|
||||
m := New()
|
||||
m.Use(Static("."))
|
||||
|
||||
resp := httptest.NewRecorder()
|
||||
resp.Body = new(bytes.Buffer)
|
||||
req, err := http.NewRequest("GET", "http://localhost:4000/"+path.Base(strings.Replace(f.Name(), "\\", "/", -1)), nil)
|
||||
So(err, ShouldBeNil)
|
||||
m.ServeHTTP(resp, req)
|
||||
So(resp.Code, ShouldEqual, http.StatusOK)
|
||||
So(resp.Header().Get("Expires"), ShouldBeBlank)
|
||||
So(resp.Body.String(), ShouldEqual, "Expected Content")
|
||||
})
|
||||
|
||||
Convey("Serve static files with head", t, func() {
|
||||
m := New()
|
||||
m.Use(Static(currentRoot))
|
||||
|
||||
resp := httptest.NewRecorder()
|
||||
resp.Body = new(bytes.Buffer)
|
||||
req, err := http.NewRequest("HEAD", "http://localhost:4000/macaron.go", nil)
|
||||
So(err, ShouldBeNil)
|
||||
m.ServeHTTP(resp, req)
|
||||
So(resp.Code, ShouldEqual, http.StatusOK)
|
||||
So(resp.Body.Len(), ShouldEqual, 0)
|
||||
})
|
||||
|
||||
Convey("Serve static files as post", t, func() {
|
||||
m := New()
|
||||
m.Use(Static(currentRoot))
|
||||
|
||||
resp := httptest.NewRecorder()
|
||||
req, err := http.NewRequest("POST", "http://localhost:4000/macaron.go", nil)
|
||||
So(err, ShouldBeNil)
|
||||
m.ServeHTTP(resp, req)
|
||||
So(resp.Code, ShouldEqual, http.StatusNotFound)
|
||||
})
|
||||
|
||||
Convey("Serve static files with bad directory", t, func() {
|
||||
m := Classic()
|
||||
resp := httptest.NewRecorder()
|
||||
req, err := http.NewRequest("GET", "http://localhost:4000/macaron.go", nil)
|
||||
So(err, ShouldBeNil)
|
||||
m.ServeHTTP(resp, req)
|
||||
So(resp.Code, ShouldNotEqual, http.StatusOK)
|
||||
})
|
||||
}
|
||||
|
||||
func Test_Static_Options(t *testing.T) {
|
||||
Convey("Serve static files with options logging", t, func() {
|
||||
var buf bytes.Buffer
|
||||
m := NewWithLogger(&buf)
|
||||
opt := StaticOptions{}
|
||||
m.Use(Static(currentRoot, opt))
|
||||
|
||||
resp := httptest.NewRecorder()
|
||||
req, err := http.NewRequest("GET", "http://localhost:4000/macaron.go", nil)
|
||||
So(err, ShouldBeNil)
|
||||
m.ServeHTTP(resp, req)
|
||||
|
||||
So(resp.Code, ShouldEqual, http.StatusOK)
|
||||
So(buf.String(), ShouldEqual, "[Macaron] [Static] Serving /macaron.go\n")
|
||||
|
||||
// Not disable logging.
|
||||
m.Handlers()
|
||||
buf.Reset()
|
||||
opt.SkipLogging = true
|
||||
m.Use(Static(currentRoot, opt))
|
||||
m.ServeHTTP(resp, req)
|
||||
|
||||
So(resp.Code, ShouldEqual, http.StatusOK)
|
||||
So(buf.Len(), ShouldEqual, 0)
|
||||
})
|
||||
|
||||
Convey("Serve static files with options serve index", t, func() {
|
||||
var buf bytes.Buffer
|
||||
m := NewWithLogger(&buf)
|
||||
opt := StaticOptions{IndexFile: "macaron.go"}
|
||||
m.Use(Static(currentRoot, opt))
|
||||
|
||||
resp := httptest.NewRecorder()
|
||||
req, err := http.NewRequest("GET", "http://localhost:4000/", nil)
|
||||
So(err, ShouldBeNil)
|
||||
m.ServeHTTP(resp, req)
|
||||
|
||||
So(resp.Code, ShouldEqual, http.StatusOK)
|
||||
So(buf.String(), ShouldEqual, "[Macaron] [Static] Serving /macaron.go\n")
|
||||
})
|
||||
|
||||
Convey("Serve static files with options prefix", t, func() {
|
||||
var buf bytes.Buffer
|
||||
m := NewWithLogger(&buf)
|
||||
opt := StaticOptions{Prefix: "public"}
|
||||
m.Use(Static(currentRoot, opt))
|
||||
|
||||
resp := httptest.NewRecorder()
|
||||
req, err := http.NewRequest("GET", "http://localhost:4000/public/macaron.go", nil)
|
||||
So(err, ShouldBeNil)
|
||||
m.ServeHTTP(resp, req)
|
||||
|
||||
So(resp.Code, ShouldEqual, http.StatusOK)
|
||||
So(buf.String(), ShouldEqual, "[Macaron] [Static] Serving /macaron.go\n")
|
||||
})
|
||||
|
||||
Convey("Serve static files with options expires", t, func() {
|
||||
var buf bytes.Buffer
|
||||
m := NewWithLogger(&buf)
|
||||
opt := StaticOptions{Expires: func() string { return "46" }}
|
||||
m.Use(Static(currentRoot, opt))
|
||||
|
||||
resp := httptest.NewRecorder()
|
||||
req, err := http.NewRequest("GET", "http://localhost:4000/macaron.go", nil)
|
||||
So(err, ShouldBeNil)
|
||||
m.ServeHTTP(resp, req)
|
||||
|
||||
So(resp.Header().Get("Expires"), ShouldEqual, "46")
|
||||
})
|
||||
}
|
||||
|
||||
func Test_Static_Redirect(t *testing.T) {
|
||||
Convey("Serve static files with redirect", t, func() {
|
||||
m := New()
|
||||
m.Use(Static(currentRoot, StaticOptions{Prefix: "/public"}))
|
||||
|
||||
resp := httptest.NewRecorder()
|
||||
req, err := http.NewRequest("GET", "http://localhost:4000/public", nil)
|
||||
So(err, ShouldBeNil)
|
||||
m.ServeHTTP(resp, req)
|
||||
|
||||
So(resp.Code, ShouldEqual, http.StatusFound)
|
||||
So(resp.Header().Get("Location"), ShouldEqual, "/public/")
|
||||
})
|
||||
}
|
||||
|
||||
func Test_Statics(t *testing.T) {
|
||||
Convey("Serve multiple static routers", t, func() {
|
||||
Convey("Register empty directory", func() {
|
||||
defer func() {
|
||||
So(recover(), ShouldNotBeNil)
|
||||
}()
|
||||
|
||||
m := New()
|
||||
m.Use(Statics(StaticOptions{}))
|
||||
|
||||
resp := httptest.NewRecorder()
|
||||
req, err := http.NewRequest("GET", "http://localhost:4000/", nil)
|
||||
So(err, ShouldBeNil)
|
||||
m.ServeHTTP(resp, req)
|
||||
})
|
||||
|
||||
Convey("Serve normally", func() {
|
||||
var buf bytes.Buffer
|
||||
m := NewWithLogger(&buf)
|
||||
m.Use(Statics(StaticOptions{}, currentRoot, currentRoot+"/inject"))
|
||||
|
||||
resp := httptest.NewRecorder()
|
||||
req, err := http.NewRequest("GET", "http://localhost:4000/macaron.go", nil)
|
||||
So(err, ShouldBeNil)
|
||||
m.ServeHTTP(resp, req)
|
||||
|
||||
So(resp.Code, ShouldEqual, http.StatusOK)
|
||||
So(buf.String(), ShouldEqual, "[Macaron] [Static] Serving /macaron.go\n")
|
||||
|
||||
resp = httptest.NewRecorder()
|
||||
req, err = http.NewRequest("GET", "http://localhost:4000/inject/inject.go", nil)
|
||||
So(err, ShouldBeNil)
|
||||
m.ServeHTTP(resp, req)
|
||||
|
||||
So(resp.Code, ShouldEqual, http.StatusOK)
|
||||
So(buf.String(), ShouldEndWith, "[Macaron] [Static] Serving /inject/inject.go\n")
|
||||
})
|
||||
})
|
||||
}
|
||||
421
Godeps/_workspace/src/github.com/Unknwon/macaron/tree.go
generated
vendored
421
Godeps/_workspace/src/github.com/Unknwon/macaron/tree.go
generated
vendored
@@ -1,421 +0,0 @@
|
||||
// Copyright 2013 Beego Authors
|
||||
// Copyright 2014 Unknwon
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"): you may
|
||||
// not use this file except in compliance with the License. You may obtain
|
||||
// a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
// License for the specific language governing permissions and limitations
|
||||
// under the License.
|
||||
|
||||
package macaron
|
||||
|
||||
// NOTE: last sync 0c93364 on Dec 19, 2014.
|
||||
|
||||
import (
|
||||
"path"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/Unknwon/com"
|
||||
)
|
||||
|
||||
type leafInfo struct {
|
||||
// Names of wildcards that lead to this leaf.
|
||||
// eg, ["id" "name"] for the wildcard ":id" and ":name".
|
||||
wildcards []string
|
||||
// Not nil if the leaf is regexp.
|
||||
regexps *regexp.Regexp
|
||||
handle Handle
|
||||
}
|
||||
|
||||
func (leaf *leafInfo) match(wildcardValues []string) (ok bool, params Params) {
|
||||
if leaf.regexps == nil {
|
||||
if len(wildcardValues) == 0 && len(leaf.wildcards) > 0 {
|
||||
if com.IsSliceContainsStr(leaf.wildcards, ":") {
|
||||
params = make(map[string]string)
|
||||
j := 0
|
||||
for _, v := range leaf.wildcards {
|
||||
if v == ":" {
|
||||
continue
|
||||
}
|
||||
params[v] = ""
|
||||
j += 1
|
||||
}
|
||||
return true, params
|
||||
}
|
||||
return false, nil
|
||||
} else if len(wildcardValues) == 0 {
|
||||
return true, nil // Static path.
|
||||
}
|
||||
|
||||
// Match *
|
||||
if len(leaf.wildcards) == 1 && leaf.wildcards[0] == ":splat" {
|
||||
params = make(map[string]string)
|
||||
params[":splat"] = path.Join(wildcardValues...)
|
||||
return true, params
|
||||
}
|
||||
|
||||
// Match *.*
|
||||
if len(leaf.wildcards) == 3 && leaf.wildcards[0] == "." {
|
||||
params = make(map[string]string)
|
||||
lastone := wildcardValues[len(wildcardValues)-1]
|
||||
strs := strings.SplitN(lastone, ".", 2)
|
||||
if len(strs) == 2 {
|
||||
params[":ext"] = strs[1]
|
||||
} else {
|
||||
params[":ext"] = ""
|
||||
}
|
||||
params[":path"] = path.Join(wildcardValues[:len(wildcardValues)-1]...) + "/" + strs[0]
|
||||
return true, params
|
||||
}
|
||||
|
||||
// Match :id
|
||||
params = make(map[string]string)
|
||||
j := 0
|
||||
for _, v := range leaf.wildcards {
|
||||
if v == ":" {
|
||||
continue
|
||||
}
|
||||
if v == "." {
|
||||
lastone := wildcardValues[len(wildcardValues)-1]
|
||||
strs := strings.SplitN(lastone, ".", 2)
|
||||
if len(strs) == 2 {
|
||||
params[":ext"] = strs[1]
|
||||
} else {
|
||||
params[":ext"] = ""
|
||||
}
|
||||
if len(wildcardValues[j:]) == 1 {
|
||||
params[":path"] = strs[0]
|
||||
} else {
|
||||
params[":path"] = path.Join(wildcardValues[j:]...) + "/" + strs[0]
|
||||
}
|
||||
return true, params
|
||||
}
|
||||
if len(wildcardValues) <= j {
|
||||
return false, nil
|
||||
}
|
||||
params[v] = wildcardValues[j]
|
||||
j++
|
||||
}
|
||||
if len(params) != len(wildcardValues) {
|
||||
return false, nil
|
||||
}
|
||||
return true, params
|
||||
}
|
||||
|
||||
if !leaf.regexps.MatchString(path.Join(wildcardValues...)) {
|
||||
return false, nil
|
||||
}
|
||||
params = make(map[string]string)
|
||||
matches := leaf.regexps.FindStringSubmatch(path.Join(wildcardValues...))
|
||||
for i, match := range matches[1:] {
|
||||
params[leaf.wildcards[i]] = match
|
||||
}
|
||||
return true, params
|
||||
}
|
||||
|
||||
// Tree represents a router tree for Macaron instance.
|
||||
type Tree struct {
|
||||
fixroutes map[string]*Tree
|
||||
wildcard *Tree
|
||||
leaves []*leafInfo
|
||||
}
|
||||
|
||||
// NewTree initializes and returns a router tree.
|
||||
func NewTree() *Tree {
|
||||
return &Tree{
|
||||
fixroutes: make(map[string]*Tree),
|
||||
}
|
||||
}
|
||||
|
||||
// splitPath splites patthen into parts.
|
||||
//
|
||||
// Examples:
|
||||
// "/" -> []
|
||||
// "/admin" -> ["admin"]
|
||||
// "/admin/" -> ["admin"]
|
||||
// "/admin/users" -> ["admin", "users"]
|
||||
func splitPath(pattern string) []string {
|
||||
if len(pattern) == 0 {
|
||||
return []string{}
|
||||
}
|
||||
|
||||
elements := strings.Split(pattern, "/")
|
||||
if elements[0] == "" {
|
||||
elements = elements[1:]
|
||||
}
|
||||
if elements[len(elements)-1] == "" {
|
||||
elements = elements[:len(elements)-1]
|
||||
}
|
||||
return elements
|
||||
}
|
||||
|
||||
// AddRouter adds a new route to router tree.
|
||||
func (t *Tree) AddRouter(pattern string, handle Handle) {
|
||||
t.addSegments(splitPath(pattern), handle, nil, "")
|
||||
}
|
||||
|
||||
// splitSegment splits segment into parts.
|
||||
//
|
||||
// Examples:
|
||||
// "admin" -> false, nil, ""
|
||||
// ":id" -> true, [:id], ""
|
||||
// "?:id" -> true, [: :id], "" : meaning can empty
|
||||
// ":id:int" -> true, [:id], ([0-9]+)
|
||||
// ":name:string" -> true, [:name], ([\w]+)
|
||||
// ":id([0-9]+)" -> true, [:id], ([0-9]+)
|
||||
// ":id([0-9]+)_:name" -> true, [:id :name], ([0-9]+)_(.+)
|
||||
// "cms_:id_:page.html" -> true, [:id :page], cms_(.+)_(.+).html
|
||||
// "*" -> true, [:splat], ""
|
||||
// "*.*" -> true,[. :path :ext], "" . meaning separator
|
||||
func splitSegment(key string) (bool, []string, string) {
|
||||
if strings.HasPrefix(key, "*") {
|
||||
if key == "*.*" {
|
||||
return true, []string{".", ":path", ":ext"}, ""
|
||||
} else {
|
||||
return true, []string{":splat"}, ""
|
||||
}
|
||||
}
|
||||
if strings.ContainsAny(key, ":") {
|
||||
var paramsNum int
|
||||
var out []rune
|
||||
var start bool
|
||||
var startexp bool
|
||||
var param []rune
|
||||
var expt []rune
|
||||
var skipnum int
|
||||
params := []string{}
|
||||
reg := regexp.MustCompile(`[a-zA-Z0-9]+`)
|
||||
for i, v := range key {
|
||||
if skipnum > 0 {
|
||||
skipnum -= 1
|
||||
continue
|
||||
}
|
||||
if start {
|
||||
//:id:int and :name:string
|
||||
if v == ':' {
|
||||
if len(key) >= i+4 {
|
||||
if key[i+1:i+4] == "int" {
|
||||
out = append(out, []rune("([0-9]+)")...)
|
||||
params = append(params, ":"+string(param))
|
||||
start = false
|
||||
startexp = false
|
||||
skipnum = 3
|
||||
param = make([]rune, 0)
|
||||
paramsNum += 1
|
||||
continue
|
||||
}
|
||||
}
|
||||
if len(key) >= i+7 {
|
||||
if key[i+1:i+7] == "string" {
|
||||
out = append(out, []rune(`([\w]+)`)...)
|
||||
params = append(params, ":"+string(param))
|
||||
paramsNum += 1
|
||||
start = false
|
||||
startexp = false
|
||||
skipnum = 6
|
||||
param = make([]rune, 0)
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
// params only support a-zA-Z0-9
|
||||
if reg.MatchString(string(v)) {
|
||||
param = append(param, v)
|
||||
continue
|
||||
}
|
||||
if v != '(' {
|
||||
out = append(out, []rune(`(.+)`)...)
|
||||
params = append(params, ":"+string(param))
|
||||
param = make([]rune, 0)
|
||||
paramsNum += 1
|
||||
start = false
|
||||
startexp = false
|
||||
}
|
||||
}
|
||||
if startexp {
|
||||
if v != ')' {
|
||||
expt = append(expt, v)
|
||||
continue
|
||||
}
|
||||
}
|
||||
if v == ':' {
|
||||
param = make([]rune, 0)
|
||||
start = true
|
||||
} else if v == '(' {
|
||||
startexp = true
|
||||
start = false
|
||||
params = append(params, ":"+string(param))
|
||||
paramsNum += 1
|
||||
expt = make([]rune, 0)
|
||||
expt = append(expt, '(')
|
||||
} else if v == ')' {
|
||||
startexp = false
|
||||
expt = append(expt, ')')
|
||||
out = append(out, expt...)
|
||||
param = make([]rune, 0)
|
||||
} else if v == '?' {
|
||||
params = append(params, ":")
|
||||
} else {
|
||||
out = append(out, v)
|
||||
}
|
||||
}
|
||||
if len(param) > 0 {
|
||||
if paramsNum > 0 {
|
||||
out = append(out, []rune(`(.+)`)...)
|
||||
}
|
||||
params = append(params, ":"+string(param))
|
||||
}
|
||||
return true, params, string(out)
|
||||
} else {
|
||||
return false, nil, ""
|
||||
}
|
||||
}
|
||||
|
||||
// addSegments add segments to the router tree.
|
||||
func (t *Tree) addSegments(segments []string, handle Handle, wildcards []string, reg string) {
|
||||
// Fixed root route.
|
||||
if len(segments) == 0 {
|
||||
if reg != "" {
|
||||
filterCards := make([]string, 0, len(wildcards))
|
||||
for _, v := range wildcards {
|
||||
if v == ":" || v == "." {
|
||||
continue
|
||||
}
|
||||
filterCards = append(filterCards, v)
|
||||
}
|
||||
t.leaves = append(t.leaves, &leafInfo{
|
||||
handle: handle,
|
||||
wildcards: filterCards,
|
||||
regexps: regexp.MustCompile("^" + reg + "$"),
|
||||
})
|
||||
} else {
|
||||
t.leaves = append(t.leaves, &leafInfo{
|
||||
handle: handle,
|
||||
wildcards: wildcards,
|
||||
})
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
seg := segments[0]
|
||||
iswild, params, regexpStr := splitSegment(seg)
|
||||
//for the router /login/*/access match /login/2009/11/access
|
||||
if !iswild && com.IsSliceContainsStr(wildcards, ":splat") {
|
||||
iswild = true
|
||||
regexpStr = seg
|
||||
}
|
||||
if seg == "*" && len(wildcards) > 0 && reg == "" {
|
||||
iswild = true
|
||||
regexpStr = "(.+)"
|
||||
}
|
||||
if iswild {
|
||||
if t.wildcard == nil {
|
||||
t.wildcard = NewTree()
|
||||
}
|
||||
if regexpStr != "" {
|
||||
if reg == "" {
|
||||
rr := ""
|
||||
for _, w := range wildcards {
|
||||
if w == "." || w == ":" {
|
||||
continue
|
||||
}
|
||||
if w == ":splat" {
|
||||
rr = rr + "(.+)/"
|
||||
} else {
|
||||
rr = rr + "([^/]+)/"
|
||||
}
|
||||
}
|
||||
regexpStr = rr + regexpStr
|
||||
} else {
|
||||
regexpStr = "/" + regexpStr
|
||||
}
|
||||
} else if reg != "" {
|
||||
if seg == "*.*" {
|
||||
regexpStr = "/([^.]+).(.+)"
|
||||
} else {
|
||||
for _, w := range params {
|
||||
if w == "." || w == ":" {
|
||||
continue
|
||||
}
|
||||
regexpStr = "/([^/]+)" + regexpStr
|
||||
}
|
||||
}
|
||||
}
|
||||
t.wildcard.addSegments(segments[1:], handle, append(wildcards, params...), reg+regexpStr)
|
||||
} else {
|
||||
subTree, ok := t.fixroutes[seg]
|
||||
if !ok {
|
||||
subTree = NewTree()
|
||||
t.fixroutes[seg] = subTree
|
||||
}
|
||||
subTree.addSegments(segments[1:], handle, wildcards, reg)
|
||||
}
|
||||
}
|
||||
|
||||
func (t *Tree) match(segments []string, wildcardValues []string) (handle Handle, params Params) {
|
||||
// Handle leaf nodes.
|
||||
if len(segments) == 0 {
|
||||
for _, l := range t.leaves {
|
||||
if ok, pa := l.match(wildcardValues); ok {
|
||||
return l.handle, pa
|
||||
}
|
||||
}
|
||||
if t.wildcard != nil {
|
||||
for _, l := range t.wildcard.leaves {
|
||||
if ok, pa := l.match(wildcardValues); ok {
|
||||
return l.handle, pa
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
seg, segs := segments[0], segments[1:]
|
||||
|
||||
subTree, ok := t.fixroutes[seg]
|
||||
if ok {
|
||||
handle, params = subTree.match(segs, wildcardValues)
|
||||
} else if len(segs) == 0 { //.json .xml
|
||||
if subindex := strings.LastIndex(seg, "."); subindex != -1 {
|
||||
subTree, ok = t.fixroutes[seg[:subindex]]
|
||||
if ok {
|
||||
handle, params = subTree.match(segs, wildcardValues)
|
||||
if handle != nil {
|
||||
if params == nil {
|
||||
params = make(map[string]string)
|
||||
}
|
||||
params[":ext"] = seg[subindex+1:]
|
||||
return handle, params
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if handle == nil && t.wildcard != nil {
|
||||
handle, params = t.wildcard.match(segs, append(wildcardValues, seg))
|
||||
}
|
||||
if handle == nil {
|
||||
for _, l := range t.leaves {
|
||||
if ok, pa := l.match(append(wildcardValues, segments...)); ok {
|
||||
return l.handle, pa
|
||||
}
|
||||
}
|
||||
}
|
||||
return handle, params
|
||||
}
|
||||
|
||||
// Match returns Handle and params if any route is matched.
|
||||
func (t *Tree) Match(pattern string) (Handle, Params) {
|
||||
if len(pattern) == 0 || pattern[0] != '/' {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
return t.match(splitPath(pattern), nil)
|
||||
}
|
||||
112
Godeps/_workspace/src/github.com/Unknwon/macaron/tree_test.go
generated
vendored
112
Godeps/_workspace/src/github.com/Unknwon/macaron/tree_test.go
generated
vendored
@@ -1,112 +0,0 @@
|
||||
// Copyright 2014 Unknwon
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"): you may
|
||||
// not use this file except in compliance with the License. You may obtain
|
||||
// a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
// License for the specific language governing permissions and limitations
|
||||
// under the License.
|
||||
|
||||
package macaron
|
||||
|
||||
import (
|
||||
// "net/http"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
. "github.com/smartystreets/goconvey/convey"
|
||||
)
|
||||
|
||||
func Test_splitSegment(t *testing.T) {
|
||||
type result struct {
|
||||
Ok bool
|
||||
Parts []string
|
||||
Regex string
|
||||
}
|
||||
cases := map[string]result{
|
||||
"admin": result{false, nil, ""},
|
||||
":id": result{true, []string{":id"}, ""},
|
||||
"?:id": result{true, []string{":", ":id"}, ""},
|
||||
":id:int": result{true, []string{":id"}, "([0-9]+)"},
|
||||
":name:string": result{true, []string{":name"}, `([\w]+)`},
|
||||
":id([0-9]+)": result{true, []string{":id"}, "([0-9]+)"},
|
||||
":id([0-9]+)_:name": result{true, []string{":id", ":name"}, "([0-9]+)_(.+)"},
|
||||
"cms_:id_:page.html": result{true, []string{":id", ":page"}, "cms_(.+)_(.+).html"},
|
||||
"*": result{true, []string{":splat"}, ""},
|
||||
"*.*": result{true, []string{".", ":path", ":ext"}, ""},
|
||||
}
|
||||
Convey("Splits segment into parts", t, func() {
|
||||
for key, result := range cases {
|
||||
ok, parts, regex := splitSegment(key)
|
||||
So(ok, ShouldEqual, result.Ok)
|
||||
if result.Parts == nil {
|
||||
So(parts, ShouldBeNil)
|
||||
} else {
|
||||
So(parts, ShouldNotBeNil)
|
||||
So(strings.Join(parts, " "), ShouldEqual, strings.Join(result.Parts, " "))
|
||||
}
|
||||
So(regex, ShouldEqual, result.Regex)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func Test_Tree_Match(t *testing.T) {
|
||||
type result struct {
|
||||
pattern string
|
||||
reqUrl string
|
||||
params map[string]string
|
||||
}
|
||||
|
||||
cases := []result{
|
||||
{"/:id", "/123", map[string]string{":id": "123"}},
|
||||
{"/hello/?:id", "/hello", map[string]string{":id": ""}},
|
||||
{"/", "/", nil},
|
||||
{"", "", nil},
|
||||
{"/customer/login", "/customer/login", nil},
|
||||
{"/customer/login", "/customer/login.json", map[string]string{":ext": "json"}},
|
||||
{"/*", "/customer/123", map[string]string{":splat": "customer/123"}},
|
||||
{"/*", "/customer/2009/12/11", map[string]string{":splat": "customer/2009/12/11"}},
|
||||
{"/aa/*/bb", "/aa/2009/bb", map[string]string{":splat": "2009"}},
|
||||
{"/cc/*/dd", "/cc/2009/11/dd", map[string]string{":splat": "2009/11"}},
|
||||
{"/ee/:year/*/ff", "/ee/2009/11/ff", map[string]string{":year": "2009", ":splat": "11"}},
|
||||
{"/thumbnail/:size/uploads/*", "/thumbnail/100x100/uploads/items/2014/04/20/dPRCdChkUd651t1Hvs18.jpg",
|
||||
map[string]string{":size": "100x100", ":splat": "items/2014/04/20/dPRCdChkUd651t1Hvs18.jpg"}},
|
||||
{"/*.*", "/nice/api.json", map[string]string{":path": "nice/api", ":ext": "json"}},
|
||||
{"/:name/*.*", "/nice/api.json", map[string]string{":name": "nice", ":path": "api", ":ext": "json"}},
|
||||
{"/:name/test/*.*", "/nice/test/api.json", map[string]string{":name": "nice", ":path": "api", ":ext": "json"}},
|
||||
{"/dl/:width:int/:height:int/*.*", "/dl/48/48/05ac66d9bda00a3acf948c43e306fc9a.jpg",
|
||||
map[string]string{":width": "48", ":height": "48", ":ext": "jpg", ":path": "05ac66d9bda00a3acf948c43e306fc9a"}},
|
||||
{"/v1/shop/:id:int", "/v1/shop/123", map[string]string{":id": "123"}},
|
||||
{"/:year:int/:month:int/:id/:endid", "/1111/111/aaa/aaa", map[string]string{":year": "1111", ":month": "111", ":id": "aaa", ":endid": "aaa"}},
|
||||
{"/v1/shop/:id/:name", "/v1/shop/123/nike", map[string]string{":id": "123", ":name": "nike"}},
|
||||
{"/v1/shop/:id/account", "/v1/shop/123/account", map[string]string{":id": "123"}},
|
||||
{"/v1/shop/:name:string", "/v1/shop/nike", map[string]string{":name": "nike"}},
|
||||
{"/v1/shop/:id([0-9]+)", "/v1/shop//123", map[string]string{":id": "123"}},
|
||||
{"/v1/shop/:id([0-9]+)_:name", "/v1/shop/123_nike", map[string]string{":id": "123", ":name": "nike"}},
|
||||
{"/v1/shop/:id(.+)_cms.html", "/v1/shop/123_cms.html", map[string]string{":id": "123"}},
|
||||
{"/v1/shop/cms_:id(.+)_:page(.+).html", "/v1/shop/cms_123_1.html", map[string]string{":id": "123", ":page": "1"}},
|
||||
{"/v1/:v/cms/aaa_:id(.+)_:page(.+).html", "/v1/2/cms/aaa_123_1.html", map[string]string{":v": "2", ":id": "123", ":page": "1"}},
|
||||
{"/v1/:v/cms_:id(.+)_:page(.+).html", "/v1/2/cms_123_1.html", map[string]string{":v": "2", ":id": "123", ":page": "1"}},
|
||||
{"/v1/:v(.+)_cms/ttt_:id(.+)_:page(.+).html", "/v1/2_cms/ttt_123_1.html", map[string]string{":v": "2", ":id": "123", ":page": "1"}},
|
||||
}
|
||||
|
||||
Convey("Match routers in tree", t, func() {
|
||||
for _, c := range cases {
|
||||
t := NewTree()
|
||||
t.AddRouter(c.pattern, nil)
|
||||
_, params := t.Match(c.reqUrl)
|
||||
if params != nil {
|
||||
for k, v := range c.params {
|
||||
vv, ok := params[k]
|
||||
So(ok, ShouldBeTrue)
|
||||
So(vv, ShouldEqual, v)
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
202
Godeps/_workspace/src/github.com/aws/aws-sdk-go/LICENSE.txt
generated
vendored
Normal file
202
Godeps/_workspace/src/github.com/aws/aws-sdk-go/LICENSE.txt
generated
vendored
Normal file
@@ -0,0 +1,202 @@
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
3
Godeps/_workspace/src/github.com/aws/aws-sdk-go/NOTICE.txt
generated
vendored
Normal file
3
Godeps/_workspace/src/github.com/aws/aws-sdk-go/NOTICE.txt
generated
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
AWS SDK for Go
|
||||
Copyright 2015 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
Copyright 2014-2015 Stripe, Inc.
|
||||
105
Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/awserr/error.go
generated
vendored
Normal file
105
Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/awserr/error.go
generated
vendored
Normal file
@@ -0,0 +1,105 @@
|
||||
// Package awserr represents API error interface accessors for the SDK.
|
||||
package awserr
|
||||
|
||||
// An Error wraps lower level errors with code, message and an original error.
|
||||
// The underlying concrete error type may also satisfy other interfaces which
|
||||
// can be to used to obtain more specific information about the error.
|
||||
//
|
||||
// Calling Error() or String() will always include the full information about
|
||||
// an error based on its underlying type.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// output, err := s3manage.Upload(svc, input, opts)
|
||||
// if err != nil {
|
||||
// if awsErr, ok := err.(awserr.Error); ok {
|
||||
// // Get error details
|
||||
// log.Println("Error:", err.Code(), err.Message())
|
||||
//
|
||||
// // Prints out full error message, including original error if there was one.
|
||||
// log.Println("Error:", err.Error())
|
||||
//
|
||||
// // Get original error
|
||||
// if origErr := err.Err(); origErr != nil {
|
||||
// // operate on original error.
|
||||
// }
|
||||
// } else {
|
||||
// fmt.Println(err.Error())
|
||||
// }
|
||||
// }
|
||||
//
|
||||
type Error interface {
|
||||
// Satisfy the generic error interface.
|
||||
error
|
||||
|
||||
// Returns the short phrase depicting the classification of the error.
|
||||
Code() string
|
||||
|
||||
// Returns the error details message.
|
||||
Message() string
|
||||
|
||||
// Returns the original error if one was set. Nil is returned if not set.
|
||||
OrigErr() error
|
||||
}
|
||||
|
||||
// New returns an Error object described by the code, message, and origErr.
|
||||
//
|
||||
// If origErr satisfies the Error interface it will not be wrapped within a new
|
||||
// Error object and will instead be returned.
|
||||
func New(code, message string, origErr error) Error {
|
||||
if e, ok := origErr.(Error); ok && e != nil {
|
||||
return e
|
||||
}
|
||||
return newBaseError(code, message, origErr)
|
||||
}
|
||||
|
||||
// A RequestFailure is an interface to extract request failure information from
|
||||
// an Error such as the request ID of the failed request returned by a service.
|
||||
// RequestFailures may not always have a requestID value if the request failed
|
||||
// prior to reaching the service such as a connection error.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// output, err := s3manage.Upload(svc, input, opts)
|
||||
// if err != nil {
|
||||
// if reqerr, ok := err.(RequestFailure); ok {
|
||||
// log.Printf("Request failed", reqerr.Code(), reqerr.Message(), reqerr.RequestID())
|
||||
// } else {
|
||||
// log.Printf("Error:", err.Error()
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// Combined with awserr.Error:
|
||||
//
|
||||
// output, err := s3manage.Upload(svc, input, opts)
|
||||
// if err != nil {
|
||||
// if awsErr, ok := err.(awserr.Error); ok {
|
||||
// // Generic AWS Error with Code, Message, and original error (if any)
|
||||
// fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr())
|
||||
//
|
||||
// if reqErr, ok := err.(awserr.RequestFailure); ok {
|
||||
// // A service error occurred
|
||||
// fmt.Println(reqErr.StatusCode(), reqErr.RequestID())
|
||||
// }
|
||||
// } else {
|
||||
// fmt.Println(err.Error())
|
||||
// }
|
||||
// }
|
||||
//
|
||||
type RequestFailure interface {
|
||||
Error
|
||||
|
||||
// The status code of the HTTP response.
|
||||
StatusCode() int
|
||||
|
||||
// The request ID returned by the service for a request failure. This will
|
||||
// be empty if no request ID is available such as the request failed due
|
||||
// to a connection error.
|
||||
RequestID() string
|
||||
}
|
||||
|
||||
// NewRequestFailure returns a new request error wrapper for the given Error
|
||||
// provided.
|
||||
func NewRequestFailure(err Error, statusCode int, reqID string) RequestFailure {
|
||||
return newRequestError(err, statusCode, reqID)
|
||||
}
|
||||
135
Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/awserr/types.go
generated
vendored
Normal file
135
Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/awserr/types.go
generated
vendored
Normal file
@@ -0,0 +1,135 @@
|
||||
package awserr
|
||||
|
||||
import "fmt"
|
||||
|
||||
// SprintError returns a string of the formatted error code.
|
||||
//
|
||||
// Both extra and origErr are optional. If they are included their lines
|
||||
// will be added, but if they are not included their lines will be ignored.
|
||||
func SprintError(code, message, extra string, origErr error) string {
|
||||
msg := fmt.Sprintf("%s: %s", code, message)
|
||||
if extra != "" {
|
||||
msg = fmt.Sprintf("%s\n\t%s", msg, extra)
|
||||
}
|
||||
if origErr != nil {
|
||||
msg = fmt.Sprintf("%s\ncaused by: %s", msg, origErr.Error())
|
||||
}
|
||||
return msg
|
||||
}
|
||||
|
||||
// A baseError wraps the code and message which defines an error. It also
|
||||
// can be used to wrap an original error object.
|
||||
//
|
||||
// Should be used as the root for errors satisfying the awserr.Error. Also
|
||||
// for any error which does not fit into a specific error wrapper type.
|
||||
type baseError struct {
|
||||
// Classification of error
|
||||
code string
|
||||
|
||||
// Detailed information about error
|
||||
message string
|
||||
|
||||
// Optional original error this error is based off of. Allows building
|
||||
// chained errors.
|
||||
origErr error
|
||||
}
|
||||
|
||||
// newBaseError returns an error object for the code, message, and err.
|
||||
//
|
||||
// code is a short no whitespace phrase depicting the classification of
|
||||
// the error that is being created.
|
||||
//
|
||||
// message is the free flow string containing detailed information about the error.
|
||||
//
|
||||
// origErr is the error object which will be nested under the new error to be returned.
|
||||
func newBaseError(code, message string, origErr error) *baseError {
|
||||
return &baseError{
|
||||
code: code,
|
||||
message: message,
|
||||
origErr: origErr,
|
||||
}
|
||||
}
|
||||
|
||||
// Error returns the string representation of the error.
|
||||
//
|
||||
// See ErrorWithExtra for formatting.
|
||||
//
|
||||
// Satisfies the error interface.
|
||||
func (b baseError) Error() string {
|
||||
return SprintError(b.code, b.message, "", b.origErr)
|
||||
}
|
||||
|
||||
// String returns the string representation of the error.
|
||||
// Alias for Error to satisfy the stringer interface.
|
||||
func (b baseError) String() string {
|
||||
return b.Error()
|
||||
}
|
||||
|
||||
// Code returns the short phrase depicting the classification of the error.
|
||||
func (b baseError) Code() string {
|
||||
return b.code
|
||||
}
|
||||
|
||||
// Message returns the error details message.
|
||||
func (b baseError) Message() string {
|
||||
return b.message
|
||||
}
|
||||
|
||||
// OrigErr returns the original error if one was set. Nil is returned if no error
|
||||
// was set.
|
||||
func (b baseError) OrigErr() error {
|
||||
return b.origErr
|
||||
}
|
||||
|
||||
// So that the Error interface type can be included as an anonymous field
|
||||
// in the requestError struct and not conflict with the error.Error() method.
|
||||
type awsError Error
|
||||
|
||||
// A requestError wraps a request or service error.
|
||||
//
|
||||
// Composed of baseError for code, message, and original error.
|
||||
type requestError struct {
|
||||
awsError
|
||||
statusCode int
|
||||
requestID string
|
||||
}
|
||||
|
||||
// newRequestError returns a wrapped error with additional information for request
|
||||
// status code, and service requestID.
|
||||
//
|
||||
// Should be used to wrap all request which involve service requests. Even if
|
||||
// the request failed without a service response, but had an HTTP status code
|
||||
// that may be meaningful.
|
||||
//
|
||||
// Also wraps original errors via the baseError.
|
||||
func newRequestError(err Error, statusCode int, requestID string) *requestError {
|
||||
return &requestError{
|
||||
awsError: err,
|
||||
statusCode: statusCode,
|
||||
requestID: requestID,
|
||||
}
|
||||
}
|
||||
|
||||
// Error returns the string representation of the error.
|
||||
// Satisfies the error interface.
|
||||
func (r requestError) Error() string {
|
||||
extra := fmt.Sprintf("status code: %d, request id: %s",
|
||||
r.statusCode, r.requestID)
|
||||
return SprintError(r.Code(), r.Message(), extra, r.OrigErr())
|
||||
}
|
||||
|
||||
// String returns the string representation of the error.
|
||||
// Alias for Error to satisfy the stringer interface.
|
||||
func (r requestError) String() string {
|
||||
return r.Error()
|
||||
}
|
||||
|
||||
// StatusCode returns the wrapped status code for the error
|
||||
func (r requestError) StatusCode() int {
|
||||
return r.statusCode
|
||||
}
|
||||
|
||||
// RequestID returns the wrapped requestID
|
||||
func (r requestError) RequestID() string {
|
||||
return r.requestID
|
||||
}
|
||||
100
Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/awsutil/copy.go
generated
vendored
Normal file
100
Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/awsutil/copy.go
generated
vendored
Normal file
@@ -0,0 +1,100 @@
|
||||
package awsutil
|
||||
|
||||
import (
|
||||
"io"
|
||||
"reflect"
|
||||
)
|
||||
|
||||
// Copy deeply copies a src structure to dst. Useful for copying request and
|
||||
// response structures.
|
||||
//
|
||||
// Can copy between structs of different type, but will only copy fields which
|
||||
// are assignable, and exist in both structs. Fields which are not assignable,
|
||||
// or do not exist in both structs are ignored.
|
||||
func Copy(dst, src interface{}) {
|
||||
dstval := reflect.ValueOf(dst)
|
||||
if !dstval.IsValid() {
|
||||
panic("Copy dst cannot be nil")
|
||||
}
|
||||
|
||||
rcopy(dstval, reflect.ValueOf(src), true)
|
||||
}
|
||||
|
||||
// CopyOf returns a copy of src while also allocating the memory for dst.
|
||||
// src must be a pointer type or this operation will fail.
|
||||
func CopyOf(src interface{}) (dst interface{}) {
|
||||
dsti := reflect.New(reflect.TypeOf(src).Elem())
|
||||
dst = dsti.Interface()
|
||||
rcopy(dsti, reflect.ValueOf(src), true)
|
||||
return
|
||||
}
|
||||
|
||||
// rcopy performs a recursive copy of values from the source to destination.
|
||||
//
|
||||
// root is used to skip certain aspects of the copy which are not valid
|
||||
// for the root node of a object.
|
||||
func rcopy(dst, src reflect.Value, root bool) {
|
||||
if !src.IsValid() {
|
||||
return
|
||||
}
|
||||
|
||||
switch src.Kind() {
|
||||
case reflect.Ptr:
|
||||
if _, ok := src.Interface().(io.Reader); ok {
|
||||
if dst.Kind() == reflect.Ptr && dst.Elem().CanSet() {
|
||||
dst.Elem().Set(src)
|
||||
} else if dst.CanSet() {
|
||||
dst.Set(src)
|
||||
}
|
||||
} else {
|
||||
e := src.Type().Elem()
|
||||
if dst.CanSet() && !src.IsNil() {
|
||||
dst.Set(reflect.New(e))
|
||||
}
|
||||
if src.Elem().IsValid() {
|
||||
// Keep the current root state since the depth hasn't changed
|
||||
rcopy(dst.Elem(), src.Elem(), root)
|
||||
}
|
||||
}
|
||||
case reflect.Struct:
|
||||
t := dst.Type()
|
||||
for i := 0; i < t.NumField(); i++ {
|
||||
name := t.Field(i).Name
|
||||
srcVal := src.FieldByName(name)
|
||||
dstVal := dst.FieldByName(name)
|
||||
if srcVal.IsValid() && dstVal.CanSet() {
|
||||
rcopy(dstVal, srcVal, false)
|
||||
}
|
||||
}
|
||||
case reflect.Slice:
|
||||
if src.IsNil() {
|
||||
break
|
||||
}
|
||||
|
||||
s := reflect.MakeSlice(src.Type(), src.Len(), src.Cap())
|
||||
dst.Set(s)
|
||||
for i := 0; i < src.Len(); i++ {
|
||||
rcopy(dst.Index(i), src.Index(i), false)
|
||||
}
|
||||
case reflect.Map:
|
||||
if src.IsNil() {
|
||||
break
|
||||
}
|
||||
|
||||
s := reflect.MakeMap(src.Type())
|
||||
dst.Set(s)
|
||||
for _, k := range src.MapKeys() {
|
||||
v := src.MapIndex(k)
|
||||
v2 := reflect.New(v.Type()).Elem()
|
||||
rcopy(v2, v, false)
|
||||
dst.SetMapIndex(k, v2)
|
||||
}
|
||||
default:
|
||||
// Assign the value if possible. If its not assignable, the value would
|
||||
// need to be converted and the impact of that may be unexpected, or is
|
||||
// not compatible with the dst type.
|
||||
if src.Type().AssignableTo(dst.Type()) {
|
||||
dst.Set(src)
|
||||
}
|
||||
}
|
||||
}
|
||||
233
Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/awsutil/copy_test.go
generated
vendored
Normal file
233
Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/awsutil/copy_test.go
generated
vendored
Normal file
@@ -0,0 +1,233 @@
|
||||
package awsutil_test
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"testing"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws/awsutil"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func ExampleCopy() {
|
||||
type Foo struct {
|
||||
A int
|
||||
B []*string
|
||||
}
|
||||
|
||||
// Create the initial value
|
||||
str1 := "hello"
|
||||
str2 := "bye bye"
|
||||
f1 := &Foo{A: 1, B: []*string{&str1, &str2}}
|
||||
|
||||
// Do the copy
|
||||
var f2 Foo
|
||||
awsutil.Copy(&f2, f1)
|
||||
|
||||
// Print the result
|
||||
fmt.Println(awsutil.Prettify(f2))
|
||||
|
||||
// Output:
|
||||
// {
|
||||
// A: 1,
|
||||
// B: ["hello","bye bye"]
|
||||
// }
|
||||
}
|
||||
|
||||
func TestCopy(t *testing.T) {
|
||||
type Foo struct {
|
||||
A int
|
||||
B []*string
|
||||
C map[string]*int
|
||||
}
|
||||
|
||||
// Create the initial value
|
||||
str1 := "hello"
|
||||
str2 := "bye bye"
|
||||
int1 := 1
|
||||
int2 := 2
|
||||
f1 := &Foo{
|
||||
A: 1,
|
||||
B: []*string{&str1, &str2},
|
||||
C: map[string]*int{
|
||||
"A": &int1,
|
||||
"B": &int2,
|
||||
},
|
||||
}
|
||||
|
||||
// Do the copy
|
||||
var f2 Foo
|
||||
awsutil.Copy(&f2, f1)
|
||||
|
||||
// Values are equal
|
||||
assert.Equal(t, f2.A, f1.A)
|
||||
assert.Equal(t, f2.B, f1.B)
|
||||
assert.Equal(t, f2.C, f1.C)
|
||||
|
||||
// But pointers are not!
|
||||
str3 := "nothello"
|
||||
int3 := 57
|
||||
f2.A = 100
|
||||
f2.B[0] = &str3
|
||||
f2.C["B"] = &int3
|
||||
assert.NotEqual(t, f2.A, f1.A)
|
||||
assert.NotEqual(t, f2.B, f1.B)
|
||||
assert.NotEqual(t, f2.C, f1.C)
|
||||
}
|
||||
|
||||
func TestCopyNestedWithUnexported(t *testing.T) {
|
||||
type Bar struct {
|
||||
a int
|
||||
B int
|
||||
}
|
||||
type Foo struct {
|
||||
A string
|
||||
B Bar
|
||||
}
|
||||
|
||||
f1 := &Foo{A: "string", B: Bar{a: 1, B: 2}}
|
||||
|
||||
var f2 Foo
|
||||
awsutil.Copy(&f2, f1)
|
||||
|
||||
// Values match
|
||||
assert.Equal(t, f2.A, f1.A)
|
||||
assert.NotEqual(t, f2.B, f1.B)
|
||||
assert.NotEqual(t, f2.B.a, f1.B.a)
|
||||
assert.Equal(t, f2.B.B, f2.B.B)
|
||||
}
|
||||
|
||||
func TestCopyIgnoreNilMembers(t *testing.T) {
|
||||
type Foo struct {
|
||||
A *string
|
||||
B []string
|
||||
C map[string]string
|
||||
}
|
||||
|
||||
f := &Foo{}
|
||||
assert.Nil(t, f.A)
|
||||
assert.Nil(t, f.B)
|
||||
assert.Nil(t, f.C)
|
||||
|
||||
var f2 Foo
|
||||
awsutil.Copy(&f2, f)
|
||||
assert.Nil(t, f2.A)
|
||||
assert.Nil(t, f2.B)
|
||||
assert.Nil(t, f2.C)
|
||||
|
||||
fcopy := awsutil.CopyOf(f)
|
||||
f3 := fcopy.(*Foo)
|
||||
assert.Nil(t, f3.A)
|
||||
assert.Nil(t, f3.B)
|
||||
assert.Nil(t, f3.C)
|
||||
}
|
||||
|
||||
func TestCopyPrimitive(t *testing.T) {
|
||||
str := "hello"
|
||||
var s string
|
||||
awsutil.Copy(&s, &str)
|
||||
assert.Equal(t, "hello", s)
|
||||
}
|
||||
|
||||
func TestCopyNil(t *testing.T) {
|
||||
var s string
|
||||
awsutil.Copy(&s, nil)
|
||||
assert.Equal(t, "", s)
|
||||
}
|
||||
|
||||
func TestCopyReader(t *testing.T) {
|
||||
var buf io.Reader = bytes.NewReader([]byte("hello world"))
|
||||
var r io.Reader
|
||||
awsutil.Copy(&r, buf)
|
||||
b, err := ioutil.ReadAll(r)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, []byte("hello world"), b)
|
||||
|
||||
// empty bytes because this is not a deep copy
|
||||
b, err = ioutil.ReadAll(buf)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, []byte(""), b)
|
||||
}
|
||||
|
||||
func TestCopyDifferentStructs(t *testing.T) {
|
||||
type SrcFoo struct {
|
||||
A int
|
||||
B []*string
|
||||
C map[string]*int
|
||||
SrcUnique string
|
||||
SameNameDiffType int
|
||||
unexportedPtr *int
|
||||
ExportedPtr *int
|
||||
}
|
||||
type DstFoo struct {
|
||||
A int
|
||||
B []*string
|
||||
C map[string]*int
|
||||
DstUnique int
|
||||
SameNameDiffType string
|
||||
unexportedPtr *int
|
||||
ExportedPtr *int
|
||||
}
|
||||
|
||||
// Create the initial value
|
||||
str1 := "hello"
|
||||
str2 := "bye bye"
|
||||
int1 := 1
|
||||
int2 := 2
|
||||
f1 := &SrcFoo{
|
||||
A: 1,
|
||||
B: []*string{&str1, &str2},
|
||||
C: map[string]*int{
|
||||
"A": &int1,
|
||||
"B": &int2,
|
||||
},
|
||||
SrcUnique: "unique",
|
||||
SameNameDiffType: 1,
|
||||
unexportedPtr: &int1,
|
||||
ExportedPtr: &int2,
|
||||
}
|
||||
|
||||
// Do the copy
|
||||
var f2 DstFoo
|
||||
awsutil.Copy(&f2, f1)
|
||||
|
||||
// Values are equal
|
||||
assert.Equal(t, f2.A, f1.A)
|
||||
assert.Equal(t, f2.B, f1.B)
|
||||
assert.Equal(t, f2.C, f1.C)
|
||||
assert.Equal(t, "unique", f1.SrcUnique)
|
||||
assert.Equal(t, 1, f1.SameNameDiffType)
|
||||
assert.Equal(t, 0, f2.DstUnique)
|
||||
assert.Equal(t, "", f2.SameNameDiffType)
|
||||
assert.Equal(t, int1, *f1.unexportedPtr)
|
||||
assert.Nil(t, f2.unexportedPtr)
|
||||
assert.Equal(t, int2, *f1.ExportedPtr)
|
||||
assert.Equal(t, int2, *f2.ExportedPtr)
|
||||
}
|
||||
|
||||
func ExampleCopyOf() {
|
||||
type Foo struct {
|
||||
A int
|
||||
B []*string
|
||||
}
|
||||
|
||||
// Create the initial value
|
||||
str1 := "hello"
|
||||
str2 := "bye bye"
|
||||
f1 := &Foo{A: 1, B: []*string{&str1, &str2}}
|
||||
|
||||
// Do the copy
|
||||
v := awsutil.CopyOf(f1)
|
||||
var f2 *Foo = v.(*Foo)
|
||||
|
||||
// Print the result
|
||||
fmt.Println(awsutil.Prettify(f2))
|
||||
|
||||
// Output:
|
||||
// {
|
||||
// A: 1,
|
||||
// B: ["hello","bye bye"]
|
||||
// }
|
||||
}
|
||||
27
Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/awsutil/equal.go
generated
vendored
Normal file
27
Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/awsutil/equal.go
generated
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
package awsutil
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
)
|
||||
|
||||
// DeepEqual returns if the two values are deeply equal like reflect.DeepEqual.
|
||||
// In addition to this, this method will also dereference the input values if
|
||||
// possible so the DeepEqual performed will not fail if one parameter is a
|
||||
// pointer and the other is not.
|
||||
//
|
||||
// DeepEqual will not perform indirection of nested values of the input parameters.
|
||||
func DeepEqual(a, b interface{}) bool {
|
||||
ra := reflect.Indirect(reflect.ValueOf(a))
|
||||
rb := reflect.Indirect(reflect.ValueOf(b))
|
||||
|
||||
if raValid, rbValid := ra.IsValid(), rb.IsValid(); !raValid && !rbValid {
|
||||
// If the elements are both nil, and of the same type the are equal
|
||||
// If they are of different types they are not equal
|
||||
return reflect.TypeOf(a) == reflect.TypeOf(b)
|
||||
} else if raValid != rbValid {
|
||||
// Both values must be valid to be equal
|
||||
return false
|
||||
}
|
||||
|
||||
return reflect.DeepEqual(ra.Interface(), rb.Interface())
|
||||
}
|
||||
29
Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/awsutil/equal_test.go
generated
vendored
Normal file
29
Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/awsutil/equal_test.go
generated
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
package awsutil_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/aws/awsutil"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestDeepEqual(t *testing.T) {
|
||||
cases := []struct {
|
||||
a, b interface{}
|
||||
equal bool
|
||||
}{
|
||||
{"a", "a", true},
|
||||
{"a", "b", false},
|
||||
{"a", aws.String(""), false},
|
||||
{"a", nil, false},
|
||||
{"a", aws.String("a"), true},
|
||||
{(*bool)(nil), (*bool)(nil), true},
|
||||
{(*bool)(nil), (*string)(nil), false},
|
||||
{nil, nil, true},
|
||||
}
|
||||
|
||||
for i, c := range cases {
|
||||
assert.Equal(t, c.equal, awsutil.DeepEqual(c.a, c.b), "%d, a:%v b:%v, %t", i, c.a, c.b, c.equal)
|
||||
}
|
||||
}
|
||||
222
Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/awsutil/path_value.go
generated
vendored
Normal file
222
Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/awsutil/path_value.go
generated
vendored
Normal file
@@ -0,0 +1,222 @@
|
||||
package awsutil
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/jmespath/go-jmespath"
|
||||
)
|
||||
|
||||
var indexRe = regexp.MustCompile(`(.+)\[(-?\d+)?\]$`)
|
||||
|
||||
// rValuesAtPath returns a slice of values found in value v. The values
|
||||
// in v are explored recursively so all nested values are collected.
|
||||
func rValuesAtPath(v interface{}, path string, createPath, caseSensitive, nilTerm bool) []reflect.Value {
|
||||
pathparts := strings.Split(path, "||")
|
||||
if len(pathparts) > 1 {
|
||||
for _, pathpart := range pathparts {
|
||||
vals := rValuesAtPath(v, pathpart, createPath, caseSensitive, nilTerm)
|
||||
if len(vals) > 0 {
|
||||
return vals
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
values := []reflect.Value{reflect.Indirect(reflect.ValueOf(v))}
|
||||
components := strings.Split(path, ".")
|
||||
for len(values) > 0 && len(components) > 0 {
|
||||
var index *int64
|
||||
var indexStar bool
|
||||
c := strings.TrimSpace(components[0])
|
||||
if c == "" { // no actual component, illegal syntax
|
||||
return nil
|
||||
} else if caseSensitive && c != "*" && strings.ToLower(c[0:1]) == c[0:1] {
|
||||
// TODO normalize case for user
|
||||
return nil // don't support unexported fields
|
||||
}
|
||||
|
||||
// parse this component
|
||||
if m := indexRe.FindStringSubmatch(c); m != nil {
|
||||
c = m[1]
|
||||
if m[2] == "" {
|
||||
index = nil
|
||||
indexStar = true
|
||||
} else {
|
||||
i, _ := strconv.ParseInt(m[2], 10, 32)
|
||||
index = &i
|
||||
indexStar = false
|
||||
}
|
||||
}
|
||||
|
||||
nextvals := []reflect.Value{}
|
||||
for _, value := range values {
|
||||
// pull component name out of struct member
|
||||
if value.Kind() != reflect.Struct {
|
||||
continue
|
||||
}
|
||||
|
||||
if c == "*" { // pull all members
|
||||
for i := 0; i < value.NumField(); i++ {
|
||||
if f := reflect.Indirect(value.Field(i)); f.IsValid() {
|
||||
nextvals = append(nextvals, f)
|
||||
}
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
value = value.FieldByNameFunc(func(name string) bool {
|
||||
if c == name {
|
||||
return true
|
||||
} else if !caseSensitive && strings.ToLower(name) == strings.ToLower(c) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
})
|
||||
|
||||
if nilTerm && value.Kind() == reflect.Ptr && len(components[1:]) == 0 {
|
||||
if !value.IsNil() {
|
||||
value.Set(reflect.Zero(value.Type()))
|
||||
}
|
||||
return []reflect.Value{value}
|
||||
}
|
||||
|
||||
if createPath && value.Kind() == reflect.Ptr && value.IsNil() {
|
||||
// TODO if the value is the terminus it should not be created
|
||||
// if the value to be set to its position is nil.
|
||||
value.Set(reflect.New(value.Type().Elem()))
|
||||
value = value.Elem()
|
||||
} else {
|
||||
value = reflect.Indirect(value)
|
||||
}
|
||||
|
||||
if value.Kind() == reflect.Slice || value.Kind() == reflect.Map {
|
||||
if !createPath && value.IsNil() {
|
||||
value = reflect.ValueOf(nil)
|
||||
}
|
||||
}
|
||||
|
||||
if value.IsValid() {
|
||||
nextvals = append(nextvals, value)
|
||||
}
|
||||
}
|
||||
values = nextvals
|
||||
|
||||
if indexStar || index != nil {
|
||||
nextvals = []reflect.Value{}
|
||||
for _, value := range values {
|
||||
value := reflect.Indirect(value)
|
||||
if value.Kind() != reflect.Slice {
|
||||
continue
|
||||
}
|
||||
|
||||
if indexStar { // grab all indices
|
||||
for i := 0; i < value.Len(); i++ {
|
||||
idx := reflect.Indirect(value.Index(i))
|
||||
if idx.IsValid() {
|
||||
nextvals = append(nextvals, idx)
|
||||
}
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
// pull out index
|
||||
i := int(*index)
|
||||
if i >= value.Len() { // check out of bounds
|
||||
if createPath {
|
||||
// TODO resize slice
|
||||
} else {
|
||||
continue
|
||||
}
|
||||
} else if i < 0 { // support negative indexing
|
||||
i = value.Len() + i
|
||||
}
|
||||
value = reflect.Indirect(value.Index(i))
|
||||
|
||||
if value.Kind() == reflect.Slice || value.Kind() == reflect.Map {
|
||||
if !createPath && value.IsNil() {
|
||||
value = reflect.ValueOf(nil)
|
||||
}
|
||||
}
|
||||
|
||||
if value.IsValid() {
|
||||
nextvals = append(nextvals, value)
|
||||
}
|
||||
}
|
||||
values = nextvals
|
||||
}
|
||||
|
||||
components = components[1:]
|
||||
}
|
||||
return values
|
||||
}
|
||||
|
||||
// ValuesAtPath returns a list of values at the case insensitive lexical
|
||||
// path inside of a structure.
|
||||
func ValuesAtPath(i interface{}, path string) ([]interface{}, error) {
|
||||
result, err := jmespath.Search(path, i)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
v := reflect.ValueOf(result)
|
||||
if !v.IsValid() || (v.Kind() == reflect.Ptr && v.IsNil()) {
|
||||
return nil, nil
|
||||
}
|
||||
if s, ok := result.([]interface{}); ok {
|
||||
return s, err
|
||||
}
|
||||
if v.Kind() == reflect.Map && v.Len() == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
if v.Kind() == reflect.Slice {
|
||||
out := make([]interface{}, v.Len())
|
||||
for i := 0; i < v.Len(); i++ {
|
||||
out[i] = v.Index(i).Interface()
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
return []interface{}{result}, nil
|
||||
}
|
||||
|
||||
// SetValueAtPath sets a value at the case insensitive lexical path inside
|
||||
// of a structure.
|
||||
func SetValueAtPath(i interface{}, path string, v interface{}) {
|
||||
if rvals := rValuesAtPath(i, path, true, false, v == nil); rvals != nil {
|
||||
for _, rval := range rvals {
|
||||
if rval.Kind() == reflect.Ptr && rval.IsNil() {
|
||||
continue
|
||||
}
|
||||
setValue(rval, v)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func setValue(dstVal reflect.Value, src interface{}) {
|
||||
if dstVal.Kind() == reflect.Ptr {
|
||||
dstVal = reflect.Indirect(dstVal)
|
||||
}
|
||||
srcVal := reflect.ValueOf(src)
|
||||
|
||||
if !srcVal.IsValid() { // src is literal nil
|
||||
if dstVal.CanAddr() {
|
||||
// Convert to pointer so that pointer's value can be nil'ed
|
||||
// dstVal = dstVal.Addr()
|
||||
}
|
||||
dstVal.Set(reflect.Zero(dstVal.Type()))
|
||||
|
||||
} else if srcVal.Kind() == reflect.Ptr {
|
||||
if srcVal.IsNil() {
|
||||
srcVal = reflect.Zero(dstVal.Type())
|
||||
} else {
|
||||
srcVal = reflect.ValueOf(src).Elem()
|
||||
}
|
||||
dstVal.Set(srcVal)
|
||||
} else {
|
||||
dstVal.Set(srcVal)
|
||||
}
|
||||
|
||||
}
|
||||
142
Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/awsutil/path_value_test.go
generated
vendored
Normal file
142
Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/awsutil/path_value_test.go
generated
vendored
Normal file
@@ -0,0 +1,142 @@
|
||||
package awsutil_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws/awsutil"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
type Struct struct {
|
||||
A []Struct
|
||||
z []Struct
|
||||
B *Struct
|
||||
D *Struct
|
||||
C string
|
||||
E map[string]string
|
||||
}
|
||||
|
||||
var data = Struct{
|
||||
A: []Struct{{C: "value1"}, {C: "value2"}, {C: "value3"}},
|
||||
z: []Struct{{C: "value1"}, {C: "value2"}, {C: "value3"}},
|
||||
B: &Struct{B: &Struct{C: "terminal"}, D: &Struct{C: "terminal2"}},
|
||||
C: "initial",
|
||||
}
|
||||
var data2 = Struct{A: []Struct{
|
||||
{A: []Struct{{C: "1"}, {C: "1"}, {C: "1"}, {C: "1"}, {C: "1"}}},
|
||||
{A: []Struct{{C: "2"}, {C: "2"}, {C: "2"}, {C: "2"}, {C: "2"}}},
|
||||
}}
|
||||
|
||||
func TestValueAtPathSuccess(t *testing.T) {
|
||||
var testCases = []struct {
|
||||
expect []interface{}
|
||||
data interface{}
|
||||
path string
|
||||
}{
|
||||
{[]interface{}{"initial"}, data, "C"},
|
||||
{[]interface{}{"value1"}, data, "A[0].C"},
|
||||
{[]interface{}{"value2"}, data, "A[1].C"},
|
||||
{[]interface{}{"value3"}, data, "A[2].C"},
|
||||
{[]interface{}{"value3"}, data, "a[2].c"},
|
||||
{[]interface{}{"value3"}, data, "A[-1].C"},
|
||||
{[]interface{}{"value1", "value2", "value3"}, data, "A[].C"},
|
||||
{[]interface{}{"terminal"}, data, "B . B . C"},
|
||||
{[]interface{}{"initial"}, data, "A.D.X || C"},
|
||||
{[]interface{}{"initial"}, data, "A[0].B || C"},
|
||||
{[]interface{}{
|
||||
Struct{A: []Struct{{C: "1"}, {C: "1"}, {C: "1"}, {C: "1"}, {C: "1"}}},
|
||||
Struct{A: []Struct{{C: "2"}, {C: "2"}, {C: "2"}, {C: "2"}, {C: "2"}}},
|
||||
}, data2, "A"},
|
||||
}
|
||||
for i, c := range testCases {
|
||||
v, err := awsutil.ValuesAtPath(c.data, c.path)
|
||||
assert.NoError(t, err, "case %d, expected no error, %s", i, c.path)
|
||||
assert.Equal(t, c.expect, v, "case %d, %s", i, c.path)
|
||||
}
|
||||
}
|
||||
|
||||
func TestValueAtPathFailure(t *testing.T) {
|
||||
var testCases = []struct {
|
||||
expect []interface{}
|
||||
errContains string
|
||||
data interface{}
|
||||
path string
|
||||
}{
|
||||
{nil, "", data, "C.x"},
|
||||
{nil, "SyntaxError: Invalid token: tDot", data, ".x"},
|
||||
{nil, "", data, "X.Y.Z"},
|
||||
{nil, "", data, "A[100].C"},
|
||||
{nil, "", data, "A[3].C"},
|
||||
{nil, "", data, "B.B.C.Z"},
|
||||
{nil, "", data, "z[-1].C"},
|
||||
{nil, "", nil, "A.B.C"},
|
||||
{[]interface{}{}, "", Struct{}, "A"},
|
||||
{nil, "", data, "A[0].B.C"},
|
||||
{nil, "", data, "D"},
|
||||
}
|
||||
|
||||
for i, c := range testCases {
|
||||
v, err := awsutil.ValuesAtPath(c.data, c.path)
|
||||
if c.errContains != "" {
|
||||
assert.Contains(t, err.Error(), c.errContains, "case %d, expected error, %s", i, c.path)
|
||||
continue
|
||||
} else {
|
||||
assert.NoError(t, err, "case %d, expected no error, %s", i, c.path)
|
||||
}
|
||||
assert.Equal(t, c.expect, v, "case %d, %s", i, c.path)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSetValueAtPathSuccess(t *testing.T) {
|
||||
var s Struct
|
||||
awsutil.SetValueAtPath(&s, "C", "test1")
|
||||
awsutil.SetValueAtPath(&s, "B.B.C", "test2")
|
||||
awsutil.SetValueAtPath(&s, "B.D.C", "test3")
|
||||
assert.Equal(t, "test1", s.C)
|
||||
assert.Equal(t, "test2", s.B.B.C)
|
||||
assert.Equal(t, "test3", s.B.D.C)
|
||||
|
||||
awsutil.SetValueAtPath(&s, "B.*.C", "test0")
|
||||
assert.Equal(t, "test0", s.B.B.C)
|
||||
assert.Equal(t, "test0", s.B.D.C)
|
||||
|
||||
var s2 Struct
|
||||
awsutil.SetValueAtPath(&s2, "b.b.c", "test0")
|
||||
assert.Equal(t, "test0", s2.B.B.C)
|
||||
awsutil.SetValueAtPath(&s2, "A", []Struct{{}})
|
||||
assert.Equal(t, []Struct{{}}, s2.A)
|
||||
|
||||
str := "foo"
|
||||
|
||||
s3 := Struct{}
|
||||
awsutil.SetValueAtPath(&s3, "b.b.c", str)
|
||||
assert.Equal(t, "foo", s3.B.B.C)
|
||||
|
||||
s3 = Struct{B: &Struct{B: &Struct{C: str}}}
|
||||
awsutil.SetValueAtPath(&s3, "b.b.c", nil)
|
||||
assert.Equal(t, "", s3.B.B.C)
|
||||
|
||||
s3 = Struct{}
|
||||
awsutil.SetValueAtPath(&s3, "b.b.c", nil)
|
||||
assert.Equal(t, "", s3.B.B.C)
|
||||
|
||||
s3 = Struct{}
|
||||
awsutil.SetValueAtPath(&s3, "b.b.c", &str)
|
||||
assert.Equal(t, "foo", s3.B.B.C)
|
||||
|
||||
var s4 struct{ Name *string }
|
||||
awsutil.SetValueAtPath(&s4, "Name", str)
|
||||
assert.Equal(t, str, *s4.Name)
|
||||
|
||||
s4 = struct{ Name *string }{}
|
||||
awsutil.SetValueAtPath(&s4, "Name", nil)
|
||||
assert.Equal(t, (*string)(nil), s4.Name)
|
||||
|
||||
s4 = struct{ Name *string }{Name: &str}
|
||||
awsutil.SetValueAtPath(&s4, "Name", nil)
|
||||
assert.Equal(t, (*string)(nil), s4.Name)
|
||||
|
||||
s4 = struct{ Name *string }{}
|
||||
awsutil.SetValueAtPath(&s4, "Name", &str)
|
||||
assert.Equal(t, str, *s4.Name)
|
||||
}
|
||||
103
Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/awsutil/prettify.go
generated
vendored
Normal file
103
Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/awsutil/prettify.go
generated
vendored
Normal file
@@ -0,0 +1,103 @@
|
||||
package awsutil
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"reflect"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Prettify returns the string representation of a value.
|
||||
func Prettify(i interface{}) string {
|
||||
var buf bytes.Buffer
|
||||
prettify(reflect.ValueOf(i), 0, &buf)
|
||||
return buf.String()
|
||||
}
|
||||
|
||||
// prettify will recursively walk value v to build a textual
|
||||
// representation of the value.
|
||||
func prettify(v reflect.Value, indent int, buf *bytes.Buffer) {
|
||||
for v.Kind() == reflect.Ptr {
|
||||
v = v.Elem()
|
||||
}
|
||||
|
||||
switch v.Kind() {
|
||||
case reflect.Struct:
|
||||
strtype := v.Type().String()
|
||||
if strtype == "time.Time" {
|
||||
fmt.Fprintf(buf, "%s", v.Interface())
|
||||
break
|
||||
} else if strings.HasPrefix(strtype, "io.") {
|
||||
buf.WriteString("<buffer>")
|
||||
break
|
||||
}
|
||||
|
||||
buf.WriteString("{\n")
|
||||
|
||||
names := []string{}
|
||||
for i := 0; i < v.Type().NumField(); i++ {
|
||||
name := v.Type().Field(i).Name
|
||||
f := v.Field(i)
|
||||
if name[0:1] == strings.ToLower(name[0:1]) {
|
||||
continue // ignore unexported fields
|
||||
}
|
||||
if (f.Kind() == reflect.Ptr || f.Kind() == reflect.Slice || f.Kind() == reflect.Map) && f.IsNil() {
|
||||
continue // ignore unset fields
|
||||
}
|
||||
names = append(names, name)
|
||||
}
|
||||
|
||||
for i, n := range names {
|
||||
val := v.FieldByName(n)
|
||||
buf.WriteString(strings.Repeat(" ", indent+2))
|
||||
buf.WriteString(n + ": ")
|
||||
prettify(val, indent+2, buf)
|
||||
|
||||
if i < len(names)-1 {
|
||||
buf.WriteString(",\n")
|
||||
}
|
||||
}
|
||||
|
||||
buf.WriteString("\n" + strings.Repeat(" ", indent) + "}")
|
||||
case reflect.Slice:
|
||||
nl, id, id2 := "", "", ""
|
||||
if v.Len() > 3 {
|
||||
nl, id, id2 = "\n", strings.Repeat(" ", indent), strings.Repeat(" ", indent+2)
|
||||
}
|
||||
buf.WriteString("[" + nl)
|
||||
for i := 0; i < v.Len(); i++ {
|
||||
buf.WriteString(id2)
|
||||
prettify(v.Index(i), indent+2, buf)
|
||||
|
||||
if i < v.Len()-1 {
|
||||
buf.WriteString("," + nl)
|
||||
}
|
||||
}
|
||||
|
||||
buf.WriteString(nl + id + "]")
|
||||
case reflect.Map:
|
||||
buf.WriteString("{\n")
|
||||
|
||||
for i, k := range v.MapKeys() {
|
||||
buf.WriteString(strings.Repeat(" ", indent+2))
|
||||
buf.WriteString(k.String() + ": ")
|
||||
prettify(v.MapIndex(k), indent+2, buf)
|
||||
|
||||
if i < v.Len()-1 {
|
||||
buf.WriteString(",\n")
|
||||
}
|
||||
}
|
||||
|
||||
buf.WriteString("\n" + strings.Repeat(" ", indent) + "}")
|
||||
default:
|
||||
format := "%v"
|
||||
switch v.Interface().(type) {
|
||||
case string:
|
||||
format = "%q"
|
||||
case io.ReadSeeker, io.Reader:
|
||||
format = "buffer(%p)"
|
||||
}
|
||||
fmt.Fprintf(buf, format, v.Interface())
|
||||
}
|
||||
}
|
||||
89
Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/awsutil/string_value.go
generated
vendored
Normal file
89
Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/awsutil/string_value.go
generated
vendored
Normal file
@@ -0,0 +1,89 @@
|
||||
package awsutil
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// StringValue returns the string representation of a value.
|
||||
func StringValue(i interface{}) string {
|
||||
var buf bytes.Buffer
|
||||
stringValue(reflect.ValueOf(i), 0, &buf)
|
||||
return buf.String()
|
||||
}
|
||||
|
||||
func stringValue(v reflect.Value, indent int, buf *bytes.Buffer) {
|
||||
for v.Kind() == reflect.Ptr {
|
||||
v = v.Elem()
|
||||
}
|
||||
|
||||
switch v.Kind() {
|
||||
case reflect.Struct:
|
||||
buf.WriteString("{\n")
|
||||
|
||||
names := []string{}
|
||||
for i := 0; i < v.Type().NumField(); i++ {
|
||||
name := v.Type().Field(i).Name
|
||||
f := v.Field(i)
|
||||
if name[0:1] == strings.ToLower(name[0:1]) {
|
||||
continue // ignore unexported fields
|
||||
}
|
||||
if (f.Kind() == reflect.Ptr || f.Kind() == reflect.Slice) && f.IsNil() {
|
||||
continue // ignore unset fields
|
||||
}
|
||||
names = append(names, name)
|
||||
}
|
||||
|
||||
for i, n := range names {
|
||||
val := v.FieldByName(n)
|
||||
buf.WriteString(strings.Repeat(" ", indent+2))
|
||||
buf.WriteString(n + ": ")
|
||||
stringValue(val, indent+2, buf)
|
||||
|
||||
if i < len(names)-1 {
|
||||
buf.WriteString(",\n")
|
||||
}
|
||||
}
|
||||
|
||||
buf.WriteString("\n" + strings.Repeat(" ", indent) + "}")
|
||||
case reflect.Slice:
|
||||
nl, id, id2 := "", "", ""
|
||||
if v.Len() > 3 {
|
||||
nl, id, id2 = "\n", strings.Repeat(" ", indent), strings.Repeat(" ", indent+2)
|
||||
}
|
||||
buf.WriteString("[" + nl)
|
||||
for i := 0; i < v.Len(); i++ {
|
||||
buf.WriteString(id2)
|
||||
stringValue(v.Index(i), indent+2, buf)
|
||||
|
||||
if i < v.Len()-1 {
|
||||
buf.WriteString("," + nl)
|
||||
}
|
||||
}
|
||||
|
||||
buf.WriteString(nl + id + "]")
|
||||
case reflect.Map:
|
||||
buf.WriteString("{\n")
|
||||
|
||||
for i, k := range v.MapKeys() {
|
||||
buf.WriteString(strings.Repeat(" ", indent+2))
|
||||
buf.WriteString(k.String() + ": ")
|
||||
stringValue(v.MapIndex(k), indent+2, buf)
|
||||
|
||||
if i < v.Len()-1 {
|
||||
buf.WriteString(",\n")
|
||||
}
|
||||
}
|
||||
|
||||
buf.WriteString("\n" + strings.Repeat(" ", indent) + "}")
|
||||
default:
|
||||
format := "%v"
|
||||
switch v.Interface().(type) {
|
||||
case string:
|
||||
format = "%q"
|
||||
}
|
||||
fmt.Fprintf(buf, format, v.Interface())
|
||||
}
|
||||
}
|
||||
120
Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/client/client.go
generated
vendored
Normal file
120
Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/client/client.go
generated
vendored
Normal file
@@ -0,0 +1,120 @@
|
||||
package client
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http/httputil"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/aws/client/metadata"
|
||||
"github.com/aws/aws-sdk-go/aws/request"
|
||||
)
|
||||
|
||||
// A Config provides configuration to a service client instance.
|
||||
type Config struct {
|
||||
Config *aws.Config
|
||||
Handlers request.Handlers
|
||||
Endpoint, SigningRegion string
|
||||
}
|
||||
|
||||
// ConfigProvider provides a generic way for a service client to receive
|
||||
// the ClientConfig without circular dependencies.
|
||||
type ConfigProvider interface {
|
||||
ClientConfig(serviceName string, cfgs ...*aws.Config) Config
|
||||
}
|
||||
|
||||
// A Client implements the base client request and response handling
|
||||
// used by all service clients.
|
||||
type Client struct {
|
||||
request.Retryer
|
||||
metadata.ClientInfo
|
||||
|
||||
Config aws.Config
|
||||
Handlers request.Handlers
|
||||
}
|
||||
|
||||
// New will return a pointer to a new initialized service client.
|
||||
func New(cfg aws.Config, info metadata.ClientInfo, handlers request.Handlers, options ...func(*Client)) *Client {
|
||||
svc := &Client{
|
||||
Config: cfg,
|
||||
ClientInfo: info,
|
||||
Handlers: handlers,
|
||||
}
|
||||
|
||||
switch retryer, ok := cfg.Retryer.(request.Retryer); {
|
||||
case ok:
|
||||
svc.Retryer = retryer
|
||||
case cfg.Retryer != nil && cfg.Logger != nil:
|
||||
s := fmt.Sprintf("WARNING: %T does not implement request.Retryer; using DefaultRetryer instead", cfg.Retryer)
|
||||
cfg.Logger.Log(s)
|
||||
fallthrough
|
||||
default:
|
||||
maxRetries := aws.IntValue(cfg.MaxRetries)
|
||||
if cfg.MaxRetries == nil || maxRetries == aws.UseServiceDefaultRetries {
|
||||
maxRetries = 3
|
||||
}
|
||||
svc.Retryer = DefaultRetryer{NumMaxRetries: maxRetries}
|
||||
}
|
||||
|
||||
svc.AddDebugHandlers()
|
||||
|
||||
for _, option := range options {
|
||||
option(svc)
|
||||
}
|
||||
|
||||
return svc
|
||||
}
|
||||
|
||||
// NewRequest returns a new Request pointer for the service API
|
||||
// operation and parameters.
|
||||
func (c *Client) NewRequest(operation *request.Operation, params interface{}, data interface{}) *request.Request {
|
||||
return request.New(c.Config, c.ClientInfo, c.Handlers, c.Retryer, operation, params, data)
|
||||
}
|
||||
|
||||
// AddDebugHandlers injects debug logging handlers into the service to log request
|
||||
// debug information.
|
||||
func (c *Client) AddDebugHandlers() {
|
||||
if !c.Config.LogLevel.AtLeast(aws.LogDebug) {
|
||||
return
|
||||
}
|
||||
|
||||
c.Handlers.Send.PushFront(logRequest)
|
||||
c.Handlers.Send.PushBack(logResponse)
|
||||
}
|
||||
|
||||
const logReqMsg = `DEBUG: Request %s/%s Details:
|
||||
---[ REQUEST POST-SIGN ]-----------------------------
|
||||
%s
|
||||
-----------------------------------------------------`
|
||||
|
||||
func logRequest(r *request.Request) {
|
||||
logBody := r.Config.LogLevel.Matches(aws.LogDebugWithHTTPBody)
|
||||
dumpedBody, _ := httputil.DumpRequestOut(r.HTTPRequest, logBody)
|
||||
|
||||
if logBody {
|
||||
// Reset the request body because dumpRequest will re-wrap the r.HTTPRequest's
|
||||
// Body as a NoOpCloser and will not be reset after read by the HTTP
|
||||
// client reader.
|
||||
r.Body.Seek(r.BodyStart, 0)
|
||||
r.HTTPRequest.Body = ioutil.NopCloser(r.Body)
|
||||
}
|
||||
|
||||
r.Config.Logger.Log(fmt.Sprintf(logReqMsg, r.ClientInfo.ServiceName, r.Operation.Name, string(dumpedBody)))
|
||||
}
|
||||
|
||||
const logRespMsg = `DEBUG: Response %s/%s Details:
|
||||
---[ RESPONSE ]--------------------------------------
|
||||
%s
|
||||
-----------------------------------------------------`
|
||||
|
||||
func logResponse(r *request.Request) {
|
||||
var msg = "no reponse data"
|
||||
if r.HTTPResponse != nil {
|
||||
logBody := r.Config.LogLevel.Matches(aws.LogDebugWithHTTPBody)
|
||||
dumpedBody, _ := httputil.DumpResponse(r.HTTPResponse, logBody)
|
||||
msg = string(dumpedBody)
|
||||
} else if r.Error != nil {
|
||||
msg = r.Error.Error()
|
||||
}
|
||||
r.Config.Logger.Log(fmt.Sprintf(logRespMsg, r.ClientInfo.ServiceName, r.Operation.Name, msg))
|
||||
}
|
||||
45
Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/client/default_retryer.go
generated
vendored
Normal file
45
Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/client/default_retryer.go
generated
vendored
Normal file
@@ -0,0 +1,45 @@
|
||||
package client
|
||||
|
||||
import (
|
||||
"math"
|
||||
"math/rand"
|
||||
"time"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws/request"
|
||||
)
|
||||
|
||||
// DefaultRetryer implements basic retry logic using exponential backoff for
|
||||
// most services. If you want to implement custom retry logic, implement the
|
||||
// request.Retryer interface or create a structure type that composes this
|
||||
// struct and override the specific methods. For example, to override only
|
||||
// the MaxRetries method:
|
||||
//
|
||||
// type retryer struct {
|
||||
// service.DefaultRetryer
|
||||
// }
|
||||
//
|
||||
// // This implementation always has 100 max retries
|
||||
// func (d retryer) MaxRetries() uint { return 100 }
|
||||
type DefaultRetryer struct {
|
||||
NumMaxRetries int
|
||||
}
|
||||
|
||||
// MaxRetries returns the number of maximum returns the service will use to make
|
||||
// an individual API request.
|
||||
func (d DefaultRetryer) MaxRetries() int {
|
||||
return d.NumMaxRetries
|
||||
}
|
||||
|
||||
// RetryRules returns the delay duration before retrying this request again
|
||||
func (d DefaultRetryer) RetryRules(r *request.Request) time.Duration {
|
||||
delay := int(math.Pow(2, float64(r.RetryCount))) * (rand.Intn(30) + 30)
|
||||
return time.Duration(delay) * time.Millisecond
|
||||
}
|
||||
|
||||
// ShouldRetry returns if the request should be retried.
|
||||
func (d DefaultRetryer) ShouldRetry(r *request.Request) bool {
|
||||
if r.HTTPResponse.StatusCode >= 500 {
|
||||
return true
|
||||
}
|
||||
return r.IsErrorRetryable()
|
||||
}
|
||||
12
Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/client/metadata/client_info.go
generated
vendored
Normal file
12
Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/client/metadata/client_info.go
generated
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
package metadata
|
||||
|
||||
// ClientInfo wraps immutable data from the client.Client structure.
|
||||
type ClientInfo struct {
|
||||
ServiceName string
|
||||
APIVersion string
|
||||
Endpoint string
|
||||
SigningName string
|
||||
SigningRegion string
|
||||
JSONVersion string
|
||||
TargetPrefix string
|
||||
}
|
||||
270
Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/config.go
generated
vendored
Normal file
270
Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/config.go
generated
vendored
Normal file
@@ -0,0 +1,270 @@
|
||||
package aws
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws/credentials"
|
||||
)
|
||||
|
||||
// UseServiceDefaultRetries instructs the config to use the service's own default
|
||||
// number of retries. This will be the default action if Config.MaxRetries
|
||||
// is nil also.
|
||||
const UseServiceDefaultRetries = -1
|
||||
|
||||
// RequestRetryer is an alias for a type that implements the request.Retryer interface.
|
||||
type RequestRetryer interface{}
|
||||
|
||||
// A Config provides service configuration for service clients. By default,
|
||||
// all clients will use the {defaults.DefaultConfig} structure.
|
||||
type Config struct {
|
||||
// The credentials object to use when signing requests. Defaults to
|
||||
// a chain of credential providers to search for credentials in environment
|
||||
// variables, shared credential file, and EC2 Instance Roles.
|
||||
Credentials *credentials.Credentials
|
||||
|
||||
// An optional endpoint URL (hostname only or fully qualified URI)
|
||||
// that overrides the default generated endpoint for a client. Set this
|
||||
// to `""` to use the default generated endpoint.
|
||||
//
|
||||
// @note You must still provide a `Region` value when specifying an
|
||||
// endpoint for a client.
|
||||
Endpoint *string
|
||||
|
||||
// The region to send requests to. This parameter is required and must
|
||||
// be configured globally or on a per-client basis unless otherwise
|
||||
// noted. A full list of regions is found in the "Regions and Endpoints"
|
||||
// document.
|
||||
//
|
||||
// @see http://docs.aws.amazon.com/general/latest/gr/rande.html
|
||||
// AWS Regions and Endpoints
|
||||
Region *string
|
||||
|
||||
// Set this to `true` to disable SSL when sending requests. Defaults
|
||||
// to `false`.
|
||||
DisableSSL *bool
|
||||
|
||||
// The HTTP client to use when sending requests. Defaults to
|
||||
// `http.DefaultClient`.
|
||||
HTTPClient *http.Client
|
||||
|
||||
// An integer value representing the logging level. The default log level
|
||||
// is zero (LogOff), which represents no logging. To enable logging set
|
||||
// to a LogLevel Value.
|
||||
LogLevel *LogLevelType
|
||||
|
||||
// The logger writer interface to write logging messages to. Defaults to
|
||||
// standard out.
|
||||
Logger Logger
|
||||
|
||||
// The maximum number of times that a request will be retried for failures.
|
||||
// Defaults to -1, which defers the max retry setting to the service specific
|
||||
// configuration.
|
||||
MaxRetries *int
|
||||
|
||||
// Retryer guides how HTTP requests should be retried in case of recoverable failures.
|
||||
//
|
||||
// When nil or the value does not implement the request.Retryer interface,
|
||||
// the request.DefaultRetryer will be used.
|
||||
//
|
||||
// When both Retryer and MaxRetries are non-nil, the former is used and
|
||||
// the latter ignored.
|
||||
//
|
||||
// To set the Retryer field in a type-safe manner and with chaining, use
|
||||
// the request.WithRetryer helper function:
|
||||
//
|
||||
// cfg := request.WithRetryer(aws.NewConfig(), myRetryer)
|
||||
//
|
||||
Retryer RequestRetryer
|
||||
|
||||
// Disables semantic parameter validation, which validates input for missing
|
||||
// required fields and/or other semantic request input errors.
|
||||
DisableParamValidation *bool
|
||||
|
||||
// Disables the computation of request and response checksums, e.g.,
|
||||
// CRC32 checksums in Amazon DynamoDB.
|
||||
DisableComputeChecksums *bool
|
||||
|
||||
// Set this to `true` to force the request to use path-style addressing,
|
||||
// i.e., `http://s3.amazonaws.com/BUCKET/KEY`. By default, the S3 client will
|
||||
// use virtual hosted bucket addressing when possible
|
||||
// (`http://BUCKET.s3.amazonaws.com/KEY`).
|
||||
//
|
||||
// @note This configuration option is specific to the Amazon S3 service.
|
||||
// @see http://docs.aws.amazon.com/AmazonS3/latest/dev/VirtualHosting.html
|
||||
// Amazon S3: Virtual Hosting of Buckets
|
||||
S3ForcePathStyle *bool
|
||||
|
||||
SleepDelay func(time.Duration)
|
||||
}
|
||||
|
||||
// NewConfig returns a new Config pointer that can be chained with builder methods to
|
||||
// set multiple configuration values inline without using pointers.
|
||||
//
|
||||
// svc := s3.New(aws.NewConfig().WithRegion("us-west-2").WithMaxRetries(10))
|
||||
//
|
||||
func NewConfig() *Config {
|
||||
return &Config{}
|
||||
}
|
||||
|
||||
// WithCredentials sets a config Credentials value returning a Config pointer
|
||||
// for chaining.
|
||||
func (c *Config) WithCredentials(creds *credentials.Credentials) *Config {
|
||||
c.Credentials = creds
|
||||
return c
|
||||
}
|
||||
|
||||
// WithEndpoint sets a config Endpoint value returning a Config pointer for
|
||||
// chaining.
|
||||
func (c *Config) WithEndpoint(endpoint string) *Config {
|
||||
c.Endpoint = &endpoint
|
||||
return c
|
||||
}
|
||||
|
||||
// WithRegion sets a config Region value returning a Config pointer for
|
||||
// chaining.
|
||||
func (c *Config) WithRegion(region string) *Config {
|
||||
c.Region = ®ion
|
||||
return c
|
||||
}
|
||||
|
||||
// WithDisableSSL sets a config DisableSSL value returning a Config pointer
|
||||
// for chaining.
|
||||
func (c *Config) WithDisableSSL(disable bool) *Config {
|
||||
c.DisableSSL = &disable
|
||||
return c
|
||||
}
|
||||
|
||||
// WithHTTPClient sets a config HTTPClient value returning a Config pointer
|
||||
// for chaining.
|
||||
func (c *Config) WithHTTPClient(client *http.Client) *Config {
|
||||
c.HTTPClient = client
|
||||
return c
|
||||
}
|
||||
|
||||
// WithMaxRetries sets a config MaxRetries value returning a Config pointer
|
||||
// for chaining.
|
||||
func (c *Config) WithMaxRetries(max int) *Config {
|
||||
c.MaxRetries = &max
|
||||
return c
|
||||
}
|
||||
|
||||
// WithDisableParamValidation sets a config DisableParamValidation value
|
||||
// returning a Config pointer for chaining.
|
||||
func (c *Config) WithDisableParamValidation(disable bool) *Config {
|
||||
c.DisableParamValidation = &disable
|
||||
return c
|
||||
}
|
||||
|
||||
// WithDisableComputeChecksums sets a config DisableComputeChecksums value
|
||||
// returning a Config pointer for chaining.
|
||||
func (c *Config) WithDisableComputeChecksums(disable bool) *Config {
|
||||
c.DisableComputeChecksums = &disable
|
||||
return c
|
||||
}
|
||||
|
||||
// WithLogLevel sets a config LogLevel value returning a Config pointer for
|
||||
// chaining.
|
||||
func (c *Config) WithLogLevel(level LogLevelType) *Config {
|
||||
c.LogLevel = &level
|
||||
return c
|
||||
}
|
||||
|
||||
// WithLogger sets a config Logger value returning a Config pointer for
|
||||
// chaining.
|
||||
func (c *Config) WithLogger(logger Logger) *Config {
|
||||
c.Logger = logger
|
||||
return c
|
||||
}
|
||||
|
||||
// WithS3ForcePathStyle sets a config S3ForcePathStyle value returning a Config
|
||||
// pointer for chaining.
|
||||
func (c *Config) WithS3ForcePathStyle(force bool) *Config {
|
||||
c.S3ForcePathStyle = &force
|
||||
return c
|
||||
}
|
||||
|
||||
// WithSleepDelay overrides the function used to sleep while waiting for the
|
||||
// next retry. Defaults to time.Sleep.
|
||||
func (c *Config) WithSleepDelay(fn func(time.Duration)) *Config {
|
||||
c.SleepDelay = fn
|
||||
return c
|
||||
}
|
||||
|
||||
// MergeIn merges the passed in configs into the existing config object.
|
||||
func (c *Config) MergeIn(cfgs ...*Config) {
|
||||
for _, other := range cfgs {
|
||||
mergeInConfig(c, other)
|
||||
}
|
||||
}
|
||||
|
||||
func mergeInConfig(dst *Config, other *Config) {
|
||||
if other == nil {
|
||||
return
|
||||
}
|
||||
|
||||
if other.Credentials != nil {
|
||||
dst.Credentials = other.Credentials
|
||||
}
|
||||
|
||||
if other.Endpoint != nil {
|
||||
dst.Endpoint = other.Endpoint
|
||||
}
|
||||
|
||||
if other.Region != nil {
|
||||
dst.Region = other.Region
|
||||
}
|
||||
|
||||
if other.DisableSSL != nil {
|
||||
dst.DisableSSL = other.DisableSSL
|
||||
}
|
||||
|
||||
if other.HTTPClient != nil {
|
||||
dst.HTTPClient = other.HTTPClient
|
||||
}
|
||||
|
||||
if other.LogLevel != nil {
|
||||
dst.LogLevel = other.LogLevel
|
||||
}
|
||||
|
||||
if other.Logger != nil {
|
||||
dst.Logger = other.Logger
|
||||
}
|
||||
|
||||
if other.MaxRetries != nil {
|
||||
dst.MaxRetries = other.MaxRetries
|
||||
}
|
||||
|
||||
if other.Retryer != nil {
|
||||
dst.Retryer = other.Retryer
|
||||
}
|
||||
|
||||
if other.DisableParamValidation != nil {
|
||||
dst.DisableParamValidation = other.DisableParamValidation
|
||||
}
|
||||
|
||||
if other.DisableComputeChecksums != nil {
|
||||
dst.DisableComputeChecksums = other.DisableComputeChecksums
|
||||
}
|
||||
|
||||
if other.S3ForcePathStyle != nil {
|
||||
dst.S3ForcePathStyle = other.S3ForcePathStyle
|
||||
}
|
||||
|
||||
if other.SleepDelay != nil {
|
||||
dst.SleepDelay = other.SleepDelay
|
||||
}
|
||||
}
|
||||
|
||||
// Copy will return a shallow copy of the Config object. If any additional
|
||||
// configurations are provided they will be merged into the new config returned.
|
||||
func (c *Config) Copy(cfgs ...*Config) *Config {
|
||||
dst := &Config{}
|
||||
dst.MergeIn(c)
|
||||
|
||||
for _, cfg := range cfgs {
|
||||
dst.MergeIn(cfg)
|
||||
}
|
||||
|
||||
return dst
|
||||
}
|
||||
86
Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/config_test.go
generated
vendored
Normal file
86
Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/config_test.go
generated
vendored
Normal file
@@ -0,0 +1,86 @@
|
||||
package aws
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws/credentials"
|
||||
)
|
||||
|
||||
var testCredentials = credentials.NewStaticCredentials("AKID", "SECRET", "SESSION")
|
||||
|
||||
var copyTestConfig = Config{
|
||||
Credentials: testCredentials,
|
||||
Endpoint: String("CopyTestEndpoint"),
|
||||
Region: String("COPY_TEST_AWS_REGION"),
|
||||
DisableSSL: Bool(true),
|
||||
HTTPClient: http.DefaultClient,
|
||||
LogLevel: LogLevel(LogDebug),
|
||||
Logger: NewDefaultLogger(),
|
||||
MaxRetries: Int(3),
|
||||
DisableParamValidation: Bool(true),
|
||||
DisableComputeChecksums: Bool(true),
|
||||
S3ForcePathStyle: Bool(true),
|
||||
}
|
||||
|
||||
func TestCopy(t *testing.T) {
|
||||
want := copyTestConfig
|
||||
got := copyTestConfig.Copy()
|
||||
if !reflect.DeepEqual(*got, want) {
|
||||
t.Errorf("Copy() = %+v", got)
|
||||
t.Errorf(" want %+v", want)
|
||||
}
|
||||
|
||||
got.Region = String("other")
|
||||
if got.Region == want.Region {
|
||||
t.Errorf("Expect setting copy values not not reflect in source")
|
||||
}
|
||||
}
|
||||
|
||||
func TestCopyReturnsNewInstance(t *testing.T) {
|
||||
want := copyTestConfig
|
||||
got := copyTestConfig.Copy()
|
||||
if got == &want {
|
||||
t.Errorf("Copy() = %p; want different instance as source %p", got, &want)
|
||||
}
|
||||
}
|
||||
|
||||
var mergeTestZeroValueConfig = Config{}
|
||||
|
||||
var mergeTestConfig = Config{
|
||||
Credentials: testCredentials,
|
||||
Endpoint: String("MergeTestEndpoint"),
|
||||
Region: String("MERGE_TEST_AWS_REGION"),
|
||||
DisableSSL: Bool(true),
|
||||
HTTPClient: http.DefaultClient,
|
||||
LogLevel: LogLevel(LogDebug),
|
||||
Logger: NewDefaultLogger(),
|
||||
MaxRetries: Int(10),
|
||||
DisableParamValidation: Bool(true),
|
||||
DisableComputeChecksums: Bool(true),
|
||||
S3ForcePathStyle: Bool(true),
|
||||
}
|
||||
|
||||
var mergeTests = []struct {
|
||||
cfg *Config
|
||||
in *Config
|
||||
want *Config
|
||||
}{
|
||||
{&Config{}, nil, &Config{}},
|
||||
{&Config{}, &mergeTestZeroValueConfig, &Config{}},
|
||||
{&Config{}, &mergeTestConfig, &mergeTestConfig},
|
||||
}
|
||||
|
||||
func TestMerge(t *testing.T) {
|
||||
for i, tt := range mergeTests {
|
||||
got := tt.cfg.Copy()
|
||||
got.MergeIn(tt.in)
|
||||
if !reflect.DeepEqual(got, tt.want) {
|
||||
t.Errorf("Config %d %+v", i, tt.cfg)
|
||||
t.Errorf(" Merge(%+v)", tt.in)
|
||||
t.Errorf(" got %+v", got)
|
||||
t.Errorf(" want %+v", tt.want)
|
||||
}
|
||||
}
|
||||
}
|
||||
357
Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/convert_types.go
generated
vendored
Normal file
357
Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/convert_types.go
generated
vendored
Normal file
@@ -0,0 +1,357 @@
|
||||
package aws
|
||||
|
||||
import "time"
|
||||
|
||||
// String returns a pointer to of the string value passed in.
|
||||
func String(v string) *string {
|
||||
return &v
|
||||
}
|
||||
|
||||
// StringValue returns the value of the string pointer passed in or
|
||||
// "" if the pointer is nil.
|
||||
func StringValue(v *string) string {
|
||||
if v != nil {
|
||||
return *v
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// StringSlice converts a slice of string values into a slice of
|
||||
// string pointers
|
||||
func StringSlice(src []string) []*string {
|
||||
dst := make([]*string, len(src))
|
||||
for i := 0; i < len(src); i++ {
|
||||
dst[i] = &(src[i])
|
||||
}
|
||||
return dst
|
||||
}
|
||||
|
||||
// StringValueSlice converts a slice of string pointers into a slice of
|
||||
// string values
|
||||
func StringValueSlice(src []*string) []string {
|
||||
dst := make([]string, len(src))
|
||||
for i := 0; i < len(src); i++ {
|
||||
if src[i] != nil {
|
||||
dst[i] = *(src[i])
|
||||
}
|
||||
}
|
||||
return dst
|
||||
}
|
||||
|
||||
// StringMap converts a string map of string values into a string
|
||||
// map of string pointers
|
||||
func StringMap(src map[string]string) map[string]*string {
|
||||
dst := make(map[string]*string)
|
||||
for k, val := range src {
|
||||
v := val
|
||||
dst[k] = &v
|
||||
}
|
||||
return dst
|
||||
}
|
||||
|
||||
// StringValueMap converts a string map of string pointers into a string
|
||||
// map of string values
|
||||
func StringValueMap(src map[string]*string) map[string]string {
|
||||
dst := make(map[string]string)
|
||||
for k, val := range src {
|
||||
if val != nil {
|
||||
dst[k] = *val
|
||||
}
|
||||
}
|
||||
return dst
|
||||
}
|
||||
|
||||
// Bool returns a pointer to of the bool value passed in.
|
||||
func Bool(v bool) *bool {
|
||||
return &v
|
||||
}
|
||||
|
||||
// BoolValue returns the value of the bool pointer passed in or
|
||||
// false if the pointer is nil.
|
||||
func BoolValue(v *bool) bool {
|
||||
if v != nil {
|
||||
return *v
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// BoolSlice converts a slice of bool values into a slice of
|
||||
// bool pointers
|
||||
func BoolSlice(src []bool) []*bool {
|
||||
dst := make([]*bool, len(src))
|
||||
for i := 0; i < len(src); i++ {
|
||||
dst[i] = &(src[i])
|
||||
}
|
||||
return dst
|
||||
}
|
||||
|
||||
// BoolValueSlice converts a slice of bool pointers into a slice of
|
||||
// bool values
|
||||
func BoolValueSlice(src []*bool) []bool {
|
||||
dst := make([]bool, len(src))
|
||||
for i := 0; i < len(src); i++ {
|
||||
if src[i] != nil {
|
||||
dst[i] = *(src[i])
|
||||
}
|
||||
}
|
||||
return dst
|
||||
}
|
||||
|
||||
// BoolMap converts a string map of bool values into a string
|
||||
// map of bool pointers
|
||||
func BoolMap(src map[string]bool) map[string]*bool {
|
||||
dst := make(map[string]*bool)
|
||||
for k, val := range src {
|
||||
v := val
|
||||
dst[k] = &v
|
||||
}
|
||||
return dst
|
||||
}
|
||||
|
||||
// BoolValueMap converts a string map of bool pointers into a string
|
||||
// map of bool values
|
||||
func BoolValueMap(src map[string]*bool) map[string]bool {
|
||||
dst := make(map[string]bool)
|
||||
for k, val := range src {
|
||||
if val != nil {
|
||||
dst[k] = *val
|
||||
}
|
||||
}
|
||||
return dst
|
||||
}
|
||||
|
||||
// Int returns a pointer to of the int value passed in.
|
||||
func Int(v int) *int {
|
||||
return &v
|
||||
}
|
||||
|
||||
// IntValue returns the value of the int pointer passed in or
|
||||
// 0 if the pointer is nil.
|
||||
func IntValue(v *int) int {
|
||||
if v != nil {
|
||||
return *v
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
// IntSlice converts a slice of int values into a slice of
|
||||
// int pointers
|
||||
func IntSlice(src []int) []*int {
|
||||
dst := make([]*int, len(src))
|
||||
for i := 0; i < len(src); i++ {
|
||||
dst[i] = &(src[i])
|
||||
}
|
||||
return dst
|
||||
}
|
||||
|
||||
// IntValueSlice converts a slice of int pointers into a slice of
|
||||
// int values
|
||||
func IntValueSlice(src []*int) []int {
|
||||
dst := make([]int, len(src))
|
||||
for i := 0; i < len(src); i++ {
|
||||
if src[i] != nil {
|
||||
dst[i] = *(src[i])
|
||||
}
|
||||
}
|
||||
return dst
|
||||
}
|
||||
|
||||
// IntMap converts a string map of int values into a string
|
||||
// map of int pointers
|
||||
func IntMap(src map[string]int) map[string]*int {
|
||||
dst := make(map[string]*int)
|
||||
for k, val := range src {
|
||||
v := val
|
||||
dst[k] = &v
|
||||
}
|
||||
return dst
|
||||
}
|
||||
|
||||
// IntValueMap converts a string map of int pointers into a string
|
||||
// map of int values
|
||||
func IntValueMap(src map[string]*int) map[string]int {
|
||||
dst := make(map[string]int)
|
||||
for k, val := range src {
|
||||
if val != nil {
|
||||
dst[k] = *val
|
||||
}
|
||||
}
|
||||
return dst
|
||||
}
|
||||
|
||||
// Int64 returns a pointer to of the int64 value passed in.
|
||||
func Int64(v int64) *int64 {
|
||||
return &v
|
||||
}
|
||||
|
||||
// Int64Value returns the value of the int64 pointer passed in or
|
||||
// 0 if the pointer is nil.
|
||||
func Int64Value(v *int64) int64 {
|
||||
if v != nil {
|
||||
return *v
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
// Int64Slice converts a slice of int64 values into a slice of
|
||||
// int64 pointers
|
||||
func Int64Slice(src []int64) []*int64 {
|
||||
dst := make([]*int64, len(src))
|
||||
for i := 0; i < len(src); i++ {
|
||||
dst[i] = &(src[i])
|
||||
}
|
||||
return dst
|
||||
}
|
||||
|
||||
// Int64ValueSlice converts a slice of int64 pointers into a slice of
|
||||
// int64 values
|
||||
func Int64ValueSlice(src []*int64) []int64 {
|
||||
dst := make([]int64, len(src))
|
||||
for i := 0; i < len(src); i++ {
|
||||
if src[i] != nil {
|
||||
dst[i] = *(src[i])
|
||||
}
|
||||
}
|
||||
return dst
|
||||
}
|
||||
|
||||
// Int64Map converts a string map of int64 values into a string
|
||||
// map of int64 pointers
|
||||
func Int64Map(src map[string]int64) map[string]*int64 {
|
||||
dst := make(map[string]*int64)
|
||||
for k, val := range src {
|
||||
v := val
|
||||
dst[k] = &v
|
||||
}
|
||||
return dst
|
||||
}
|
||||
|
||||
// Int64ValueMap converts a string map of int64 pointers into a string
|
||||
// map of int64 values
|
||||
func Int64ValueMap(src map[string]*int64) map[string]int64 {
|
||||
dst := make(map[string]int64)
|
||||
for k, val := range src {
|
||||
if val != nil {
|
||||
dst[k] = *val
|
||||
}
|
||||
}
|
||||
return dst
|
||||
}
|
||||
|
||||
// Float64 returns a pointer to of the float64 value passed in.
|
||||
func Float64(v float64) *float64 {
|
||||
return &v
|
||||
}
|
||||
|
||||
// Float64Value returns the value of the float64 pointer passed in or
|
||||
// 0 if the pointer is nil.
|
||||
func Float64Value(v *float64) float64 {
|
||||
if v != nil {
|
||||
return *v
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
// Float64Slice converts a slice of float64 values into a slice of
|
||||
// float64 pointers
|
||||
func Float64Slice(src []float64) []*float64 {
|
||||
dst := make([]*float64, len(src))
|
||||
for i := 0; i < len(src); i++ {
|
||||
dst[i] = &(src[i])
|
||||
}
|
||||
return dst
|
||||
}
|
||||
|
||||
// Float64ValueSlice converts a slice of float64 pointers into a slice of
|
||||
// float64 values
|
||||
func Float64ValueSlice(src []*float64) []float64 {
|
||||
dst := make([]float64, len(src))
|
||||
for i := 0; i < len(src); i++ {
|
||||
if src[i] != nil {
|
||||
dst[i] = *(src[i])
|
||||
}
|
||||
}
|
||||
return dst
|
||||
}
|
||||
|
||||
// Float64Map converts a string map of float64 values into a string
|
||||
// map of float64 pointers
|
||||
func Float64Map(src map[string]float64) map[string]*float64 {
|
||||
dst := make(map[string]*float64)
|
||||
for k, val := range src {
|
||||
v := val
|
||||
dst[k] = &v
|
||||
}
|
||||
return dst
|
||||
}
|
||||
|
||||
// Float64ValueMap converts a string map of float64 pointers into a string
|
||||
// map of float64 values
|
||||
func Float64ValueMap(src map[string]*float64) map[string]float64 {
|
||||
dst := make(map[string]float64)
|
||||
for k, val := range src {
|
||||
if val != nil {
|
||||
dst[k] = *val
|
||||
}
|
||||
}
|
||||
return dst
|
||||
}
|
||||
|
||||
// Time returns a pointer to of the time.Time value passed in.
|
||||
func Time(v time.Time) *time.Time {
|
||||
return &v
|
||||
}
|
||||
|
||||
// TimeValue returns the value of the time.Time pointer passed in or
|
||||
// time.Time{} if the pointer is nil.
|
||||
func TimeValue(v *time.Time) time.Time {
|
||||
if v != nil {
|
||||
return *v
|
||||
}
|
||||
return time.Time{}
|
||||
}
|
||||
|
||||
// TimeSlice converts a slice of time.Time values into a slice of
|
||||
// time.Time pointers
|
||||
func TimeSlice(src []time.Time) []*time.Time {
|
||||
dst := make([]*time.Time, len(src))
|
||||
for i := 0; i < len(src); i++ {
|
||||
dst[i] = &(src[i])
|
||||
}
|
||||
return dst
|
||||
}
|
||||
|
||||
// TimeValueSlice converts a slice of time.Time pointers into a slice of
|
||||
// time.Time values
|
||||
func TimeValueSlice(src []*time.Time) []time.Time {
|
||||
dst := make([]time.Time, len(src))
|
||||
for i := 0; i < len(src); i++ {
|
||||
if src[i] != nil {
|
||||
dst[i] = *(src[i])
|
||||
}
|
||||
}
|
||||
return dst
|
||||
}
|
||||
|
||||
// TimeMap converts a string map of time.Time values into a string
|
||||
// map of time.Time pointers
|
||||
func TimeMap(src map[string]time.Time) map[string]*time.Time {
|
||||
dst := make(map[string]*time.Time)
|
||||
for k, val := range src {
|
||||
v := val
|
||||
dst[k] = &v
|
||||
}
|
||||
return dst
|
||||
}
|
||||
|
||||
// TimeValueMap converts a string map of time.Time pointers into a string
|
||||
// map of time.Time values
|
||||
func TimeValueMap(src map[string]*time.Time) map[string]time.Time {
|
||||
dst := make(map[string]time.Time)
|
||||
for k, val := range src {
|
||||
if val != nil {
|
||||
dst[k] = *val
|
||||
}
|
||||
}
|
||||
return dst
|
||||
}
|
||||
437
Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/convert_types_test.go
generated
vendored
Normal file
437
Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/convert_types_test.go
generated
vendored
Normal file
@@ -0,0 +1,437 @@
|
||||
package aws
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
var testCasesStringSlice = [][]string{
|
||||
{"a", "b", "c", "d", "e"},
|
||||
{"a", "b", "", "", "e"},
|
||||
}
|
||||
|
||||
func TestStringSlice(t *testing.T) {
|
||||
for idx, in := range testCasesStringSlice {
|
||||
if in == nil {
|
||||
continue
|
||||
}
|
||||
out := StringSlice(in)
|
||||
assert.Len(t, out, len(in), "Unexpected len at idx %d", idx)
|
||||
for i := range out {
|
||||
assert.Equal(t, in[i], *(out[i]), "Unexpected value at idx %d", idx)
|
||||
}
|
||||
|
||||
out2 := StringValueSlice(out)
|
||||
assert.Len(t, out2, len(in), "Unexpected len at idx %d", idx)
|
||||
assert.Equal(t, in, out2, "Unexpected value at idx %d", idx)
|
||||
}
|
||||
}
|
||||
|
||||
var testCasesStringValueSlice = [][]*string{
|
||||
{String("a"), String("b"), nil, String("c")},
|
||||
}
|
||||
|
||||
func TestStringValueSlice(t *testing.T) {
|
||||
for idx, in := range testCasesStringValueSlice {
|
||||
if in == nil {
|
||||
continue
|
||||
}
|
||||
out := StringValueSlice(in)
|
||||
assert.Len(t, out, len(in), "Unexpected len at idx %d", idx)
|
||||
for i := range out {
|
||||
if in[i] == nil {
|
||||
assert.Empty(t, out[i], "Unexpected value at idx %d", idx)
|
||||
} else {
|
||||
assert.Equal(t, *(in[i]), out[i], "Unexpected value at idx %d", idx)
|
||||
}
|
||||
}
|
||||
|
||||
out2 := StringSlice(out)
|
||||
assert.Len(t, out2, len(in), "Unexpected len at idx %d", idx)
|
||||
for i := range out2 {
|
||||
if in[i] == nil {
|
||||
assert.Empty(t, *(out2[i]), "Unexpected value at idx %d", idx)
|
||||
} else {
|
||||
assert.Equal(t, in[i], out2[i], "Unexpected value at idx %d", idx)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var testCasesStringMap = []map[string]string{
|
||||
{"a": "1", "b": "2", "c": "3"},
|
||||
}
|
||||
|
||||
func TestStringMap(t *testing.T) {
|
||||
for idx, in := range testCasesStringMap {
|
||||
if in == nil {
|
||||
continue
|
||||
}
|
||||
out := StringMap(in)
|
||||
assert.Len(t, out, len(in), "Unexpected len at idx %d", idx)
|
||||
for i := range out {
|
||||
assert.Equal(t, in[i], *(out[i]), "Unexpected value at idx %d", idx)
|
||||
}
|
||||
|
||||
out2 := StringValueMap(out)
|
||||
assert.Len(t, out2, len(in), "Unexpected len at idx %d", idx)
|
||||
assert.Equal(t, in, out2, "Unexpected value at idx %d", idx)
|
||||
}
|
||||
}
|
||||
|
||||
var testCasesBoolSlice = [][]bool{
|
||||
{true, true, false, false},
|
||||
}
|
||||
|
||||
func TestBoolSlice(t *testing.T) {
|
||||
for idx, in := range testCasesBoolSlice {
|
||||
if in == nil {
|
||||
continue
|
||||
}
|
||||
out := BoolSlice(in)
|
||||
assert.Len(t, out, len(in), "Unexpected len at idx %d", idx)
|
||||
for i := range out {
|
||||
assert.Equal(t, in[i], *(out[i]), "Unexpected value at idx %d", idx)
|
||||
}
|
||||
|
||||
out2 := BoolValueSlice(out)
|
||||
assert.Len(t, out2, len(in), "Unexpected len at idx %d", idx)
|
||||
assert.Equal(t, in, out2, "Unexpected value at idx %d", idx)
|
||||
}
|
||||
}
|
||||
|
||||
var testCasesBoolValueSlice = [][]*bool{}
|
||||
|
||||
func TestBoolValueSlice(t *testing.T) {
|
||||
for idx, in := range testCasesBoolValueSlice {
|
||||
if in == nil {
|
||||
continue
|
||||
}
|
||||
out := BoolValueSlice(in)
|
||||
assert.Len(t, out, len(in), "Unexpected len at idx %d", idx)
|
||||
for i := range out {
|
||||
if in[i] == nil {
|
||||
assert.Empty(t, out[i], "Unexpected value at idx %d", idx)
|
||||
} else {
|
||||
assert.Equal(t, *(in[i]), out[i], "Unexpected value at idx %d", idx)
|
||||
}
|
||||
}
|
||||
|
||||
out2 := BoolSlice(out)
|
||||
assert.Len(t, out2, len(in), "Unexpected len at idx %d", idx)
|
||||
for i := range out2 {
|
||||
if in[i] == nil {
|
||||
assert.Empty(t, *(out2[i]), "Unexpected value at idx %d", idx)
|
||||
} else {
|
||||
assert.Equal(t, in[i], out2[i], "Unexpected value at idx %d", idx)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var testCasesBoolMap = []map[string]bool{
|
||||
{"a": true, "b": false, "c": true},
|
||||
}
|
||||
|
||||
func TestBoolMap(t *testing.T) {
|
||||
for idx, in := range testCasesBoolMap {
|
||||
if in == nil {
|
||||
continue
|
||||
}
|
||||
out := BoolMap(in)
|
||||
assert.Len(t, out, len(in), "Unexpected len at idx %d", idx)
|
||||
for i := range out {
|
||||
assert.Equal(t, in[i], *(out[i]), "Unexpected value at idx %d", idx)
|
||||
}
|
||||
|
||||
out2 := BoolValueMap(out)
|
||||
assert.Len(t, out2, len(in), "Unexpected len at idx %d", idx)
|
||||
assert.Equal(t, in, out2, "Unexpected value at idx %d", idx)
|
||||
}
|
||||
}
|
||||
|
||||
var testCasesIntSlice = [][]int{
|
||||
{1, 2, 3, 4},
|
||||
}
|
||||
|
||||
func TestIntSlice(t *testing.T) {
|
||||
for idx, in := range testCasesIntSlice {
|
||||
if in == nil {
|
||||
continue
|
||||
}
|
||||
out := IntSlice(in)
|
||||
assert.Len(t, out, len(in), "Unexpected len at idx %d", idx)
|
||||
for i := range out {
|
||||
assert.Equal(t, in[i], *(out[i]), "Unexpected value at idx %d", idx)
|
||||
}
|
||||
|
||||
out2 := IntValueSlice(out)
|
||||
assert.Len(t, out2, len(in), "Unexpected len at idx %d", idx)
|
||||
assert.Equal(t, in, out2, "Unexpected value at idx %d", idx)
|
||||
}
|
||||
}
|
||||
|
||||
var testCasesIntValueSlice = [][]*int{}
|
||||
|
||||
func TestIntValueSlice(t *testing.T) {
|
||||
for idx, in := range testCasesIntValueSlice {
|
||||
if in == nil {
|
||||
continue
|
||||
}
|
||||
out := IntValueSlice(in)
|
||||
assert.Len(t, out, len(in), "Unexpected len at idx %d", idx)
|
||||
for i := range out {
|
||||
if in[i] == nil {
|
||||
assert.Empty(t, out[i], "Unexpected value at idx %d", idx)
|
||||
} else {
|
||||
assert.Equal(t, *(in[i]), out[i], "Unexpected value at idx %d", idx)
|
||||
}
|
||||
}
|
||||
|
||||
out2 := IntSlice(out)
|
||||
assert.Len(t, out2, len(in), "Unexpected len at idx %d", idx)
|
||||
for i := range out2 {
|
||||
if in[i] == nil {
|
||||
assert.Empty(t, *(out2[i]), "Unexpected value at idx %d", idx)
|
||||
} else {
|
||||
assert.Equal(t, in[i], out2[i], "Unexpected value at idx %d", idx)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var testCasesIntMap = []map[string]int{
|
||||
{"a": 3, "b": 2, "c": 1},
|
||||
}
|
||||
|
||||
func TestIntMap(t *testing.T) {
|
||||
for idx, in := range testCasesIntMap {
|
||||
if in == nil {
|
||||
continue
|
||||
}
|
||||
out := IntMap(in)
|
||||
assert.Len(t, out, len(in), "Unexpected len at idx %d", idx)
|
||||
for i := range out {
|
||||
assert.Equal(t, in[i], *(out[i]), "Unexpected value at idx %d", idx)
|
||||
}
|
||||
|
||||
out2 := IntValueMap(out)
|
||||
assert.Len(t, out2, len(in), "Unexpected len at idx %d", idx)
|
||||
assert.Equal(t, in, out2, "Unexpected value at idx %d", idx)
|
||||
}
|
||||
}
|
||||
|
||||
var testCasesInt64Slice = [][]int64{
|
||||
{1, 2, 3, 4},
|
||||
}
|
||||
|
||||
func TestInt64Slice(t *testing.T) {
|
||||
for idx, in := range testCasesInt64Slice {
|
||||
if in == nil {
|
||||
continue
|
||||
}
|
||||
out := Int64Slice(in)
|
||||
assert.Len(t, out, len(in), "Unexpected len at idx %d", idx)
|
||||
for i := range out {
|
||||
assert.Equal(t, in[i], *(out[i]), "Unexpected value at idx %d", idx)
|
||||
}
|
||||
|
||||
out2 := Int64ValueSlice(out)
|
||||
assert.Len(t, out2, len(in), "Unexpected len at idx %d", idx)
|
||||
assert.Equal(t, in, out2, "Unexpected value at idx %d", idx)
|
||||
}
|
||||
}
|
||||
|
||||
var testCasesInt64ValueSlice = [][]*int64{}
|
||||
|
||||
func TestInt64ValueSlice(t *testing.T) {
|
||||
for idx, in := range testCasesInt64ValueSlice {
|
||||
if in == nil {
|
||||
continue
|
||||
}
|
||||
out := Int64ValueSlice(in)
|
||||
assert.Len(t, out, len(in), "Unexpected len at idx %d", idx)
|
||||
for i := range out {
|
||||
if in[i] == nil {
|
||||
assert.Empty(t, out[i], "Unexpected value at idx %d", idx)
|
||||
} else {
|
||||
assert.Equal(t, *(in[i]), out[i], "Unexpected value at idx %d", idx)
|
||||
}
|
||||
}
|
||||
|
||||
out2 := Int64Slice(out)
|
||||
assert.Len(t, out2, len(in), "Unexpected len at idx %d", idx)
|
||||
for i := range out2 {
|
||||
if in[i] == nil {
|
||||
assert.Empty(t, *(out2[i]), "Unexpected value at idx %d", idx)
|
||||
} else {
|
||||
assert.Equal(t, in[i], out2[i], "Unexpected value at idx %d", idx)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var testCasesInt64Map = []map[string]int64{
|
||||
{"a": 3, "b": 2, "c": 1},
|
||||
}
|
||||
|
||||
func TestInt64Map(t *testing.T) {
|
||||
for idx, in := range testCasesInt64Map {
|
||||
if in == nil {
|
||||
continue
|
||||
}
|
||||
out := Int64Map(in)
|
||||
assert.Len(t, out, len(in), "Unexpected len at idx %d", idx)
|
||||
for i := range out {
|
||||
assert.Equal(t, in[i], *(out[i]), "Unexpected value at idx %d", idx)
|
||||
}
|
||||
|
||||
out2 := Int64ValueMap(out)
|
||||
assert.Len(t, out2, len(in), "Unexpected len at idx %d", idx)
|
||||
assert.Equal(t, in, out2, "Unexpected value at idx %d", idx)
|
||||
}
|
||||
}
|
||||
|
||||
var testCasesFloat64Slice = [][]float64{
|
||||
{1, 2, 3, 4},
|
||||
}
|
||||
|
||||
func TestFloat64Slice(t *testing.T) {
|
||||
for idx, in := range testCasesFloat64Slice {
|
||||
if in == nil {
|
||||
continue
|
||||
}
|
||||
out := Float64Slice(in)
|
||||
assert.Len(t, out, len(in), "Unexpected len at idx %d", idx)
|
||||
for i := range out {
|
||||
assert.Equal(t, in[i], *(out[i]), "Unexpected value at idx %d", idx)
|
||||
}
|
||||
|
||||
out2 := Float64ValueSlice(out)
|
||||
assert.Len(t, out2, len(in), "Unexpected len at idx %d", idx)
|
||||
assert.Equal(t, in, out2, "Unexpected value at idx %d", idx)
|
||||
}
|
||||
}
|
||||
|
||||
var testCasesFloat64ValueSlice = [][]*float64{}
|
||||
|
||||
func TestFloat64ValueSlice(t *testing.T) {
|
||||
for idx, in := range testCasesFloat64ValueSlice {
|
||||
if in == nil {
|
||||
continue
|
||||
}
|
||||
out := Float64ValueSlice(in)
|
||||
assert.Len(t, out, len(in), "Unexpected len at idx %d", idx)
|
||||
for i := range out {
|
||||
if in[i] == nil {
|
||||
assert.Empty(t, out[i], "Unexpected value at idx %d", idx)
|
||||
} else {
|
||||
assert.Equal(t, *(in[i]), out[i], "Unexpected value at idx %d", idx)
|
||||
}
|
||||
}
|
||||
|
||||
out2 := Float64Slice(out)
|
||||
assert.Len(t, out2, len(in), "Unexpected len at idx %d", idx)
|
||||
for i := range out2 {
|
||||
if in[i] == nil {
|
||||
assert.Empty(t, *(out2[i]), "Unexpected value at idx %d", idx)
|
||||
} else {
|
||||
assert.Equal(t, in[i], out2[i], "Unexpected value at idx %d", idx)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var testCasesFloat64Map = []map[string]float64{
|
||||
{"a": 3, "b": 2, "c": 1},
|
||||
}
|
||||
|
||||
func TestFloat64Map(t *testing.T) {
|
||||
for idx, in := range testCasesFloat64Map {
|
||||
if in == nil {
|
||||
continue
|
||||
}
|
||||
out := Float64Map(in)
|
||||
assert.Len(t, out, len(in), "Unexpected len at idx %d", idx)
|
||||
for i := range out {
|
||||
assert.Equal(t, in[i], *(out[i]), "Unexpected value at idx %d", idx)
|
||||
}
|
||||
|
||||
out2 := Float64ValueMap(out)
|
||||
assert.Len(t, out2, len(in), "Unexpected len at idx %d", idx)
|
||||
assert.Equal(t, in, out2, "Unexpected value at idx %d", idx)
|
||||
}
|
||||
}
|
||||
|
||||
var testCasesTimeSlice = [][]time.Time{
|
||||
{time.Now(), time.Now().AddDate(100, 0, 0)},
|
||||
}
|
||||
|
||||
func TestTimeSlice(t *testing.T) {
|
||||
for idx, in := range testCasesTimeSlice {
|
||||
if in == nil {
|
||||
continue
|
||||
}
|
||||
out := TimeSlice(in)
|
||||
assert.Len(t, out, len(in), "Unexpected len at idx %d", idx)
|
||||
for i := range out {
|
||||
assert.Equal(t, in[i], *(out[i]), "Unexpected value at idx %d", idx)
|
||||
}
|
||||
|
||||
out2 := TimeValueSlice(out)
|
||||
assert.Len(t, out2, len(in), "Unexpected len at idx %d", idx)
|
||||
assert.Equal(t, in, out2, "Unexpected value at idx %d", idx)
|
||||
}
|
||||
}
|
||||
|
||||
var testCasesTimeValueSlice = [][]*time.Time{}
|
||||
|
||||
func TestTimeValueSlice(t *testing.T) {
|
||||
for idx, in := range testCasesTimeValueSlice {
|
||||
if in == nil {
|
||||
continue
|
||||
}
|
||||
out := TimeValueSlice(in)
|
||||
assert.Len(t, out, len(in), "Unexpected len at idx %d", idx)
|
||||
for i := range out {
|
||||
if in[i] == nil {
|
||||
assert.Empty(t, out[i], "Unexpected value at idx %d", idx)
|
||||
} else {
|
||||
assert.Equal(t, *(in[i]), out[i], "Unexpected value at idx %d", idx)
|
||||
}
|
||||
}
|
||||
|
||||
out2 := TimeSlice(out)
|
||||
assert.Len(t, out2, len(in), "Unexpected len at idx %d", idx)
|
||||
for i := range out2 {
|
||||
if in[i] == nil {
|
||||
assert.Empty(t, *(out2[i]), "Unexpected value at idx %d", idx)
|
||||
} else {
|
||||
assert.Equal(t, in[i], out2[i], "Unexpected value at idx %d", idx)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var testCasesTimeMap = []map[string]time.Time{
|
||||
{"a": time.Now().AddDate(-100, 0, 0), "b": time.Now()},
|
||||
}
|
||||
|
||||
func TestTimeMap(t *testing.T) {
|
||||
for idx, in := range testCasesTimeMap {
|
||||
if in == nil {
|
||||
continue
|
||||
}
|
||||
out := TimeMap(in)
|
||||
assert.Len(t, out, len(in), "Unexpected len at idx %d", idx)
|
||||
for i := range out {
|
||||
assert.Equal(t, in[i], *(out[i]), "Unexpected value at idx %d", idx)
|
||||
}
|
||||
|
||||
out2 := TimeValueMap(out)
|
||||
assert.Len(t, out2, len(in), "Unexpected len at idx %d", idx)
|
||||
assert.Equal(t, in, out2, "Unexpected value at idx %d", idx)
|
||||
}
|
||||
}
|
||||
139
Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/corehandlers/handlers.go
generated
vendored
Normal file
139
Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/corehandlers/handlers.go
generated
vendored
Normal file
@@ -0,0 +1,139 @@
|
||||
package corehandlers
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"regexp"
|
||||
"runtime"
|
||||
"strconv"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/aws/awserr"
|
||||
"github.com/aws/aws-sdk-go/aws/request"
|
||||
)
|
||||
|
||||
// Interface for matching types which also have a Len method.
|
||||
type lener interface {
|
||||
Len() int
|
||||
}
|
||||
|
||||
// BuildContentLengthHandler builds the content length of a request based on the body,
|
||||
// or will use the HTTPRequest.Header's "Content-Length" if defined. If unable
|
||||
// to determine request body length and no "Content-Length" was specified it will panic.
|
||||
var BuildContentLengthHandler = request.NamedHandler{Name: "core.BuildContentLengthHandler", Fn: func(r *request.Request) {
|
||||
if slength := r.HTTPRequest.Header.Get("Content-Length"); slength != "" {
|
||||
length, _ := strconv.ParseInt(slength, 10, 64)
|
||||
r.HTTPRequest.ContentLength = length
|
||||
return
|
||||
}
|
||||
|
||||
var length int64
|
||||
switch body := r.Body.(type) {
|
||||
case nil:
|
||||
length = 0
|
||||
case lener:
|
||||
length = int64(body.Len())
|
||||
case io.Seeker:
|
||||
r.BodyStart, _ = body.Seek(0, 1)
|
||||
end, _ := body.Seek(0, 2)
|
||||
body.Seek(r.BodyStart, 0) // make sure to seek back to original location
|
||||
length = end - r.BodyStart
|
||||
default:
|
||||
panic("Cannot get length of body, must provide `ContentLength`")
|
||||
}
|
||||
|
||||
r.HTTPRequest.ContentLength = length
|
||||
r.HTTPRequest.Header.Set("Content-Length", fmt.Sprintf("%d", length))
|
||||
}}
|
||||
|
||||
// SDKVersionUserAgentHandler is a request handler for adding the SDK Version to the user agent.
|
||||
var SDKVersionUserAgentHandler = request.NamedHandler{
|
||||
Name: "core.SDKVersionUserAgentHandler",
|
||||
Fn: request.MakeAddToUserAgentHandler(aws.SDKName, aws.SDKVersion,
|
||||
runtime.Version(), runtime.GOOS, runtime.GOARCH),
|
||||
}
|
||||
|
||||
var reStatusCode = regexp.MustCompile(`^(\d{3})`)
|
||||
|
||||
// SendHandler is a request handler to send service request using HTTP client.
|
||||
var SendHandler = request.NamedHandler{Name: "core.SendHandler", Fn: func(r *request.Request) {
|
||||
var err error
|
||||
r.HTTPResponse, err = r.Config.HTTPClient.Do(r.HTTPRequest)
|
||||
if err != nil {
|
||||
// Capture the case where url.Error is returned for error processing
|
||||
// response. e.g. 301 without location header comes back as string
|
||||
// error and r.HTTPResponse is nil. Other url redirect errors will
|
||||
// comeback in a similar method.
|
||||
if e, ok := err.(*url.Error); ok && e.Err != nil {
|
||||
if s := reStatusCode.FindStringSubmatch(e.Err.Error()); s != nil {
|
||||
code, _ := strconv.ParseInt(s[1], 10, 64)
|
||||
r.HTTPResponse = &http.Response{
|
||||
StatusCode: int(code),
|
||||
Status: http.StatusText(int(code)),
|
||||
Body: ioutil.NopCloser(bytes.NewReader([]byte{})),
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
if r.HTTPResponse == nil {
|
||||
// Add a dummy request response object to ensure the HTTPResponse
|
||||
// value is consistent.
|
||||
r.HTTPResponse = &http.Response{
|
||||
StatusCode: int(0),
|
||||
Status: http.StatusText(int(0)),
|
||||
Body: ioutil.NopCloser(bytes.NewReader([]byte{})),
|
||||
}
|
||||
}
|
||||
// Catch all other request errors.
|
||||
r.Error = awserr.New("RequestError", "send request failed", err)
|
||||
r.Retryable = aws.Bool(true) // network errors are retryable
|
||||
}
|
||||
}}
|
||||
|
||||
// ValidateResponseHandler is a request handler to validate service response.
|
||||
var ValidateResponseHandler = request.NamedHandler{Name: "core.ValidateResponseHandler", Fn: func(r *request.Request) {
|
||||
if r.HTTPResponse.StatusCode == 0 || r.HTTPResponse.StatusCode >= 300 {
|
||||
// this may be replaced by an UnmarshalError handler
|
||||
r.Error = awserr.New("UnknownError", "unknown error", nil)
|
||||
}
|
||||
}}
|
||||
|
||||
// AfterRetryHandler performs final checks to determine if the request should
|
||||
// be retried and how long to delay.
|
||||
var AfterRetryHandler = request.NamedHandler{Name: "core.AfterRetryHandler", Fn: func(r *request.Request) {
|
||||
// If one of the other handlers already set the retry state
|
||||
// we don't want to override it based on the service's state
|
||||
if r.Retryable == nil {
|
||||
r.Retryable = aws.Bool(r.ShouldRetry(r))
|
||||
}
|
||||
|
||||
if r.WillRetry() {
|
||||
r.RetryDelay = r.RetryRules(r)
|
||||
r.Config.SleepDelay(r.RetryDelay)
|
||||
|
||||
// when the expired token exception occurs the credentials
|
||||
// need to be expired locally so that the next request to
|
||||
// get credentials will trigger a credentials refresh.
|
||||
if r.IsErrorExpired() {
|
||||
r.Config.Credentials.Expire()
|
||||
}
|
||||
|
||||
r.RetryCount++
|
||||
r.Error = nil
|
||||
}
|
||||
}}
|
||||
|
||||
// ValidateEndpointHandler is a request handler to validate a request had the
|
||||
// appropriate Region and Endpoint set. Will set r.Error if the endpoint or
|
||||
// region is not valid.
|
||||
var ValidateEndpointHandler = request.NamedHandler{Name: "core.ValidateEndpointHandler", Fn: func(r *request.Request) {
|
||||
if r.ClientInfo.SigningRegion == "" && aws.StringValue(r.Config.Region) == "" {
|
||||
r.Error = aws.ErrMissingRegion
|
||||
} else if r.ClientInfo.Endpoint == "" {
|
||||
r.Error = aws.ErrMissingEndpoint
|
||||
}
|
||||
}}
|
||||
113
Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/corehandlers/handlers_test.go
generated
vendored
Normal file
113
Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/corehandlers/handlers_test.go
generated
vendored
Normal file
@@ -0,0 +1,113 @@
|
||||
package corehandlers_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/aws/awserr"
|
||||
"github.com/aws/aws-sdk-go/aws/corehandlers"
|
||||
"github.com/aws/aws-sdk-go/aws/credentials"
|
||||
"github.com/aws/aws-sdk-go/aws/request"
|
||||
"github.com/aws/aws-sdk-go/awstesting"
|
||||
)
|
||||
|
||||
func TestValidateEndpointHandler(t *testing.T) {
|
||||
os.Clearenv()
|
||||
|
||||
svc := awstesting.NewClient(aws.NewConfig().WithRegion("us-west-2"))
|
||||
svc.Handlers.Clear()
|
||||
svc.Handlers.Validate.PushBackNamed(corehandlers.ValidateEndpointHandler)
|
||||
|
||||
req := svc.NewRequest(&request.Operation{Name: "Operation"}, nil, nil)
|
||||
err := req.Build()
|
||||
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
||||
func TestValidateEndpointHandlerErrorRegion(t *testing.T) {
|
||||
os.Clearenv()
|
||||
|
||||
svc := awstesting.NewClient()
|
||||
svc.Handlers.Clear()
|
||||
svc.Handlers.Validate.PushBackNamed(corehandlers.ValidateEndpointHandler)
|
||||
|
||||
req := svc.NewRequest(&request.Operation{Name: "Operation"}, nil, nil)
|
||||
err := req.Build()
|
||||
|
||||
assert.Error(t, err)
|
||||
assert.Equal(t, aws.ErrMissingRegion, err)
|
||||
}
|
||||
|
||||
type mockCredsProvider struct {
|
||||
expired bool
|
||||
retrieveCalled bool
|
||||
}
|
||||
|
||||
func (m *mockCredsProvider) Retrieve() (credentials.Value, error) {
|
||||
m.retrieveCalled = true
|
||||
return credentials.Value{}, nil
|
||||
}
|
||||
|
||||
func (m *mockCredsProvider) IsExpired() bool {
|
||||
return m.expired
|
||||
}
|
||||
|
||||
func TestAfterRetryRefreshCreds(t *testing.T) {
|
||||
os.Clearenv()
|
||||
credProvider := &mockCredsProvider{}
|
||||
|
||||
svc := awstesting.NewClient(&aws.Config{
|
||||
Credentials: credentials.NewCredentials(credProvider),
|
||||
MaxRetries: aws.Int(1),
|
||||
})
|
||||
|
||||
svc.Handlers.Clear()
|
||||
svc.Handlers.ValidateResponse.PushBack(func(r *request.Request) {
|
||||
r.Error = awserr.New("UnknownError", "", nil)
|
||||
r.HTTPResponse = &http.Response{StatusCode: 400}
|
||||
})
|
||||
svc.Handlers.UnmarshalError.PushBack(func(r *request.Request) {
|
||||
r.Error = awserr.New("ExpiredTokenException", "", nil)
|
||||
})
|
||||
svc.Handlers.AfterRetry.PushBackNamed(corehandlers.AfterRetryHandler)
|
||||
|
||||
assert.True(t, svc.Config.Credentials.IsExpired(), "Expect to start out expired")
|
||||
assert.False(t, credProvider.retrieveCalled)
|
||||
|
||||
req := svc.NewRequest(&request.Operation{Name: "Operation"}, nil, nil)
|
||||
req.Send()
|
||||
|
||||
assert.True(t, svc.Config.Credentials.IsExpired())
|
||||
assert.False(t, credProvider.retrieveCalled)
|
||||
|
||||
_, err := svc.Config.Credentials.Get()
|
||||
assert.NoError(t, err)
|
||||
assert.True(t, credProvider.retrieveCalled)
|
||||
}
|
||||
|
||||
type testSendHandlerTransport struct{}
|
||||
|
||||
func (t *testSendHandlerTransport) RoundTrip(r *http.Request) (*http.Response, error) {
|
||||
return nil, fmt.Errorf("mock error")
|
||||
}
|
||||
|
||||
func TestSendHandlerError(t *testing.T) {
|
||||
svc := awstesting.NewClient(&aws.Config{
|
||||
HTTPClient: &http.Client{
|
||||
Transport: &testSendHandlerTransport{},
|
||||
},
|
||||
})
|
||||
svc.Handlers.Clear()
|
||||
svc.Handlers.Send.PushBackNamed(corehandlers.SendHandler)
|
||||
r := svc.NewRequest(&request.Operation{Name: "Operation"}, nil, nil)
|
||||
|
||||
r.Send()
|
||||
|
||||
assert.Error(t, r.Error)
|
||||
assert.NotNil(t, r.HTTPResponse)
|
||||
}
|
||||
144
Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/corehandlers/param_validator.go
generated
vendored
Normal file
144
Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/corehandlers/param_validator.go
generated
vendored
Normal file
@@ -0,0 +1,144 @@
|
||||
package corehandlers
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws/awserr"
|
||||
"github.com/aws/aws-sdk-go/aws/request"
|
||||
)
|
||||
|
||||
// ValidateParametersHandler is a request handler to validate the input parameters.
|
||||
// Validating parameters only has meaning if done prior to the request being sent.
|
||||
var ValidateParametersHandler = request.NamedHandler{Name: "core.ValidateParametersHandler", Fn: func(r *request.Request) {
|
||||
if r.ParamsFilled() {
|
||||
v := validator{errors: []string{}}
|
||||
v.validateAny(reflect.ValueOf(r.Params), "")
|
||||
|
||||
if count := len(v.errors); count > 0 {
|
||||
format := "%d validation errors:\n- %s"
|
||||
msg := fmt.Sprintf(format, count, strings.Join(v.errors, "\n- "))
|
||||
r.Error = awserr.New("InvalidParameter", msg, nil)
|
||||
}
|
||||
}
|
||||
}}
|
||||
|
||||
// A validator validates values. Collects validations errors which occurs.
|
||||
type validator struct {
|
||||
errors []string
|
||||
}
|
||||
|
||||
// validateAny will validate any struct, slice or map type. All validations
|
||||
// are also performed recursively for nested types.
|
||||
func (v *validator) validateAny(value reflect.Value, path string) {
|
||||
value = reflect.Indirect(value)
|
||||
if !value.IsValid() {
|
||||
return
|
||||
}
|
||||
|
||||
switch value.Kind() {
|
||||
case reflect.Struct:
|
||||
v.validateStruct(value, path)
|
||||
case reflect.Slice:
|
||||
for i := 0; i < value.Len(); i++ {
|
||||
v.validateAny(value.Index(i), path+fmt.Sprintf("[%d]", i))
|
||||
}
|
||||
case reflect.Map:
|
||||
for _, n := range value.MapKeys() {
|
||||
v.validateAny(value.MapIndex(n), path+fmt.Sprintf("[%q]", n.String()))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// validateStruct will validate the struct value's fields. If the structure has
|
||||
// nested types those types will be validated also.
|
||||
func (v *validator) validateStruct(value reflect.Value, path string) {
|
||||
prefix := "."
|
||||
if path == "" {
|
||||
prefix = ""
|
||||
}
|
||||
|
||||
for i := 0; i < value.Type().NumField(); i++ {
|
||||
f := value.Type().Field(i)
|
||||
if strings.ToLower(f.Name[0:1]) == f.Name[0:1] {
|
||||
continue
|
||||
}
|
||||
fvalue := value.FieldByName(f.Name)
|
||||
|
||||
err := validateField(f, fvalue, validateFieldRequired, validateFieldMin)
|
||||
if err != nil {
|
||||
v.errors = append(v.errors, fmt.Sprintf("%s: %s", err.Error(), path+prefix+f.Name))
|
||||
continue
|
||||
}
|
||||
|
||||
v.validateAny(fvalue, path+prefix+f.Name)
|
||||
}
|
||||
}
|
||||
|
||||
type validatorFunc func(f reflect.StructField, fvalue reflect.Value) error
|
||||
|
||||
func validateField(f reflect.StructField, fvalue reflect.Value, funcs ...validatorFunc) error {
|
||||
for _, fn := range funcs {
|
||||
if err := fn(f, fvalue); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Validates that a field has a valid value provided for required fields.
|
||||
func validateFieldRequired(f reflect.StructField, fvalue reflect.Value) error {
|
||||
if f.Tag.Get("required") == "" {
|
||||
return nil
|
||||
}
|
||||
|
||||
switch fvalue.Kind() {
|
||||
case reflect.Ptr, reflect.Slice, reflect.Map:
|
||||
if fvalue.IsNil() {
|
||||
return fmt.Errorf("missing required parameter")
|
||||
}
|
||||
default:
|
||||
if !fvalue.IsValid() {
|
||||
return fmt.Errorf("missing required parameter")
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Validates that if a value is provided for a field, that value must be at
|
||||
// least a minimum length.
|
||||
func validateFieldMin(f reflect.StructField, fvalue reflect.Value) error {
|
||||
minStr := f.Tag.Get("min")
|
||||
if minStr == "" {
|
||||
return nil
|
||||
}
|
||||
min, _ := strconv.ParseInt(minStr, 10, 64)
|
||||
|
||||
kind := fvalue.Kind()
|
||||
if kind == reflect.Ptr {
|
||||
if fvalue.IsNil() {
|
||||
return nil
|
||||
}
|
||||
fvalue = fvalue.Elem()
|
||||
}
|
||||
|
||||
switch fvalue.Kind() {
|
||||
case reflect.String:
|
||||
if int64(fvalue.Len()) < min {
|
||||
return fmt.Errorf("field too short, minimum length %d", min)
|
||||
}
|
||||
case reflect.Slice, reflect.Map:
|
||||
if fvalue.IsNil() {
|
||||
return nil
|
||||
}
|
||||
if int64(fvalue.Len()) < min {
|
||||
return fmt.Errorf("field too short, minimum length %d", min)
|
||||
}
|
||||
|
||||
// TODO min can also apply to number minimum value.
|
||||
|
||||
}
|
||||
return nil
|
||||
}
|
||||
134
Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/corehandlers/param_validator_test.go
generated
vendored
Normal file
134
Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/corehandlers/param_validator_test.go
generated
vendored
Normal file
@@ -0,0 +1,134 @@
|
||||
package corehandlers_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/aws/awserr"
|
||||
"github.com/aws/aws-sdk-go/aws/client"
|
||||
"github.com/aws/aws-sdk-go/aws/client/metadata"
|
||||
"github.com/aws/aws-sdk-go/aws/corehandlers"
|
||||
"github.com/aws/aws-sdk-go/aws/request"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
var testSvc = func() *client.Client {
|
||||
s := &client.Client{
|
||||
Config: aws.Config{},
|
||||
ClientInfo: metadata.ClientInfo{
|
||||
ServiceName: "mock-service",
|
||||
APIVersion: "2015-01-01",
|
||||
},
|
||||
}
|
||||
return s
|
||||
}()
|
||||
|
||||
type StructShape struct {
|
||||
RequiredList []*ConditionalStructShape `required:"true"`
|
||||
RequiredMap map[string]*ConditionalStructShape `required:"true"`
|
||||
RequiredBool *bool `required:"true"`
|
||||
OptionalStruct *ConditionalStructShape
|
||||
|
||||
hiddenParameter *string
|
||||
|
||||
metadataStructureShape
|
||||
}
|
||||
|
||||
type metadataStructureShape struct {
|
||||
SDKShapeTraits bool
|
||||
}
|
||||
|
||||
type ConditionalStructShape struct {
|
||||
Name *string `required:"true"`
|
||||
SDKShapeTraits bool
|
||||
}
|
||||
|
||||
func TestNoErrors(t *testing.T) {
|
||||
input := &StructShape{
|
||||
RequiredList: []*ConditionalStructShape{},
|
||||
RequiredMap: map[string]*ConditionalStructShape{
|
||||
"key1": {Name: aws.String("Name")},
|
||||
"key2": {Name: aws.String("Name")},
|
||||
},
|
||||
RequiredBool: aws.Bool(true),
|
||||
OptionalStruct: &ConditionalStructShape{Name: aws.String("Name")},
|
||||
}
|
||||
|
||||
req := testSvc.NewRequest(&request.Operation{}, input, nil)
|
||||
corehandlers.ValidateParametersHandler.Fn(req)
|
||||
require.NoError(t, req.Error)
|
||||
}
|
||||
|
||||
func TestMissingRequiredParameters(t *testing.T) {
|
||||
input := &StructShape{}
|
||||
req := testSvc.NewRequest(&request.Operation{}, input, nil)
|
||||
corehandlers.ValidateParametersHandler.Fn(req)
|
||||
|
||||
require.Error(t, req.Error)
|
||||
assert.Equal(t, "InvalidParameter", req.Error.(awserr.Error).Code())
|
||||
assert.Equal(t, "3 validation errors:\n- missing required parameter: RequiredList\n- missing required parameter: RequiredMap\n- missing required parameter: RequiredBool", req.Error.(awserr.Error).Message())
|
||||
}
|
||||
|
||||
func TestNestedMissingRequiredParameters(t *testing.T) {
|
||||
input := &StructShape{
|
||||
RequiredList: []*ConditionalStructShape{{}},
|
||||
RequiredMap: map[string]*ConditionalStructShape{
|
||||
"key1": {Name: aws.String("Name")},
|
||||
"key2": {},
|
||||
},
|
||||
RequiredBool: aws.Bool(true),
|
||||
OptionalStruct: &ConditionalStructShape{},
|
||||
}
|
||||
|
||||
req := testSvc.NewRequest(&request.Operation{}, input, nil)
|
||||
corehandlers.ValidateParametersHandler.Fn(req)
|
||||
|
||||
require.Error(t, req.Error)
|
||||
assert.Equal(t, "InvalidParameter", req.Error.(awserr.Error).Code())
|
||||
assert.Equal(t, "3 validation errors:\n- missing required parameter: RequiredList[0].Name\n- missing required parameter: RequiredMap[\"key2\"].Name\n- missing required parameter: OptionalStruct.Name", req.Error.(awserr.Error).Message())
|
||||
}
|
||||
|
||||
type testInput struct {
|
||||
StringField string `min:"5"`
|
||||
PtrStrField *string `min:"2"`
|
||||
ListField []string `min:"3"`
|
||||
MapField map[string]string `min:"4"`
|
||||
}
|
||||
|
||||
var testsFieldMin = []struct {
|
||||
err awserr.Error
|
||||
in testInput
|
||||
}{
|
||||
{
|
||||
err: awserr.New("InvalidParameter", "1 validation errors:\n- field too short, minimum length 5: StringField", nil),
|
||||
in: testInput{StringField: "abcd"},
|
||||
},
|
||||
{
|
||||
err: awserr.New("InvalidParameter", "2 validation errors:\n- field too short, minimum length 5: StringField\n- field too short, minimum length 3: ListField", nil),
|
||||
in: testInput{StringField: "abcd", ListField: []string{"a", "b"}},
|
||||
},
|
||||
{
|
||||
err: awserr.New("InvalidParameter", "3 validation errors:\n- field too short, minimum length 5: StringField\n- field too short, minimum length 3: ListField\n- field too short, minimum length 4: MapField", nil),
|
||||
in: testInput{StringField: "abcd", ListField: []string{"a", "b"}, MapField: map[string]string{"a": "a", "b": "b"}},
|
||||
},
|
||||
{
|
||||
err: awserr.New("InvalidParameter", "1 validation errors:\n- field too short, minimum length 2: PtrStrField", nil),
|
||||
in: testInput{StringField: "abcde", PtrStrField: aws.String("v")},
|
||||
},
|
||||
{
|
||||
err: nil,
|
||||
in: testInput{StringField: "abcde", PtrStrField: aws.String("value"),
|
||||
ListField: []string{"a", "b", "c"}, MapField: map[string]string{"a": "a", "b": "b", "c": "c", "d": "d"}},
|
||||
},
|
||||
}
|
||||
|
||||
func TestValidateFieldMinParameter(t *testing.T) {
|
||||
for i, c := range testsFieldMin {
|
||||
req := testSvc.NewRequest(&request.Operation{}, &c.in, nil)
|
||||
corehandlers.ValidateParametersHandler.Fn(req)
|
||||
|
||||
require.Equal(t, c.err, req.Error, "%d case failed", i)
|
||||
}
|
||||
}
|
||||
85
Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/credentials/chain_provider.go
generated
vendored
Normal file
85
Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/credentials/chain_provider.go
generated
vendored
Normal file
@@ -0,0 +1,85 @@
|
||||
package credentials
|
||||
|
||||
import (
|
||||
"github.com/aws/aws-sdk-go/aws/awserr"
|
||||
)
|
||||
|
||||
var (
|
||||
// ErrNoValidProvidersFoundInChain Is returned when there are no valid
|
||||
// providers in the ChainProvider.
|
||||
//
|
||||
// @readonly
|
||||
ErrNoValidProvidersFoundInChain = awserr.New("NoCredentialProviders", "no valid providers in chain", nil)
|
||||
)
|
||||
|
||||
// A ChainProvider will search for a provider which returns credentials
|
||||
// and cache that provider until Retrieve is called again.
|
||||
//
|
||||
// The ChainProvider provides a way of chaining multiple providers together
|
||||
// which will pick the first available using priority order of the Providers
|
||||
// in the list.
|
||||
//
|
||||
// If none of the Providers retrieve valid credentials Value, ChainProvider's
|
||||
// Retrieve() will return the error ErrNoValidProvidersFoundInChain.
|
||||
//
|
||||
// If a Provider is found which returns valid credentials Value ChainProvider
|
||||
// will cache that Provider for all calls to IsExpired(), until Retrieve is
|
||||
// called again.
|
||||
//
|
||||
// Example of ChainProvider to be used with an EnvProvider and EC2RoleProvider.
|
||||
// In this example EnvProvider will first check if any credentials are available
|
||||
// vai the environment variables. If there are none ChainProvider will check
|
||||
// the next Provider in the list, EC2RoleProvider in this case. If EC2RoleProvider
|
||||
// does not return any credentials ChainProvider will return the error
|
||||
// ErrNoValidProvidersFoundInChain
|
||||
//
|
||||
// creds := NewChainCredentials(
|
||||
// []Provider{
|
||||
// &EnvProvider{},
|
||||
// &EC2RoleProvider{},
|
||||
// })
|
||||
//
|
||||
// // Usage of ChainCredentials with aws.Config
|
||||
// svc := ec2.New(&aws.Config{Credentials: creds})
|
||||
//
|
||||
type ChainProvider struct {
|
||||
Providers []Provider
|
||||
curr Provider
|
||||
}
|
||||
|
||||
// NewChainCredentials returns a pointer to a new Credentials object
|
||||
// wrapping a chain of providers.
|
||||
func NewChainCredentials(providers []Provider) *Credentials {
|
||||
return NewCredentials(&ChainProvider{
|
||||
Providers: append([]Provider{}, providers...),
|
||||
})
|
||||
}
|
||||
|
||||
// Retrieve returns the credentials value or error if no provider returned
|
||||
// without error.
|
||||
//
|
||||
// If a provider is found it will be cached and any calls to IsExpired()
|
||||
// will return the expired state of the cached provider.
|
||||
func (c *ChainProvider) Retrieve() (Value, error) {
|
||||
for _, p := range c.Providers {
|
||||
if creds, err := p.Retrieve(); err == nil {
|
||||
c.curr = p
|
||||
return creds, nil
|
||||
}
|
||||
}
|
||||
c.curr = nil
|
||||
|
||||
// TODO better error reporting. maybe report error for each failed retrieve?
|
||||
|
||||
return Value{}, ErrNoValidProvidersFoundInChain
|
||||
}
|
||||
|
||||
// IsExpired will returned the expired state of the currently cached provider
|
||||
// if there is one. If there is no current provider, true will be returned.
|
||||
func (c *ChainProvider) IsExpired() bool {
|
||||
if c.curr != nil {
|
||||
return c.curr.IsExpired()
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
73
Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/credentials/chain_provider_test.go
generated
vendored
Normal file
73
Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/credentials/chain_provider_test.go
generated
vendored
Normal file
@@ -0,0 +1,73 @@
|
||||
package credentials
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws/awserr"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestChainProviderGet(t *testing.T) {
|
||||
p := &ChainProvider{
|
||||
Providers: []Provider{
|
||||
&stubProvider{err: awserr.New("FirstError", "first provider error", nil)},
|
||||
&stubProvider{err: awserr.New("SecondError", "second provider error", nil)},
|
||||
&stubProvider{
|
||||
creds: Value{
|
||||
AccessKeyID: "AKID",
|
||||
SecretAccessKey: "SECRET",
|
||||
SessionToken: "",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
creds, err := p.Retrieve()
|
||||
assert.Nil(t, err, "Expect no error")
|
||||
assert.Equal(t, "AKID", creds.AccessKeyID, "Expect access key ID to match")
|
||||
assert.Equal(t, "SECRET", creds.SecretAccessKey, "Expect secret access key to match")
|
||||
assert.Empty(t, creds.SessionToken, "Expect session token to be empty")
|
||||
}
|
||||
|
||||
func TestChainProviderIsExpired(t *testing.T) {
|
||||
stubProvider := &stubProvider{expired: true}
|
||||
p := &ChainProvider{
|
||||
Providers: []Provider{
|
||||
stubProvider,
|
||||
},
|
||||
}
|
||||
|
||||
assert.True(t, p.IsExpired(), "Expect expired to be true before any Retrieve")
|
||||
_, err := p.Retrieve()
|
||||
assert.Nil(t, err, "Expect no error")
|
||||
assert.False(t, p.IsExpired(), "Expect not expired after retrieve")
|
||||
|
||||
stubProvider.expired = true
|
||||
assert.True(t, p.IsExpired(), "Expect return of expired provider")
|
||||
|
||||
_, err = p.Retrieve()
|
||||
assert.False(t, p.IsExpired(), "Expect not expired after retrieve")
|
||||
}
|
||||
|
||||
func TestChainProviderWithNoProvider(t *testing.T) {
|
||||
p := &ChainProvider{
|
||||
Providers: []Provider{},
|
||||
}
|
||||
|
||||
assert.True(t, p.IsExpired(), "Expect expired with no providers")
|
||||
_, err := p.Retrieve()
|
||||
assert.Equal(t, ErrNoValidProvidersFoundInChain, err, "Expect no providers error returned")
|
||||
}
|
||||
|
||||
func TestChainProviderWithNoValidProvider(t *testing.T) {
|
||||
p := &ChainProvider{
|
||||
Providers: []Provider{
|
||||
&stubProvider{err: awserr.New("FirstError", "first provider error", nil)},
|
||||
&stubProvider{err: awserr.New("SecondError", "second provider error", nil)},
|
||||
},
|
||||
}
|
||||
|
||||
assert.True(t, p.IsExpired(), "Expect expired with no providers")
|
||||
_, err := p.Retrieve()
|
||||
assert.Equal(t, ErrNoValidProvidersFoundInChain, err, "Expect no providers error returned")
|
||||
}
|
||||
220
Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/credentials/credentials.go
generated
vendored
Normal file
220
Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/credentials/credentials.go
generated
vendored
Normal file
@@ -0,0 +1,220 @@
|
||||
// Package credentials provides credential retrieval and management
|
||||
//
|
||||
// The Credentials is the primary method of getting access to and managing
|
||||
// credentials Values. Using dependency injection retrieval of the credential
|
||||
// values is handled by a object which satisfies the Provider interface.
|
||||
//
|
||||
// By default the Credentials.Get() will cache the successful result of a
|
||||
// Provider's Retrieve() until Provider.IsExpired() returns true. At which
|
||||
// point Credentials will call Provider's Retrieve() to get new credential Value.
|
||||
//
|
||||
// The Provider is responsible for determining when credentials Value have expired.
|
||||
// It is also important to note that Credentials will always call Retrieve the
|
||||
// first time Credentials.Get() is called.
|
||||
//
|
||||
// Example of using the environment variable credentials.
|
||||
//
|
||||
// creds := NewEnvCredentials()
|
||||
//
|
||||
// // Retrieve the credentials value
|
||||
// credValue, err := creds.Get()
|
||||
// if err != nil {
|
||||
// // handle error
|
||||
// }
|
||||
//
|
||||
// Example of forcing credentials to expire and be refreshed on the next Get().
|
||||
// This may be helpful to proactively expire credentials and refresh them sooner
|
||||
// than they would naturally expire on their own.
|
||||
//
|
||||
// creds := NewCredentials(&EC2RoleProvider{})
|
||||
// creds.Expire()
|
||||
// credsValue, err := creds.Get()
|
||||
// // New credentials will be retrieved instead of from cache.
|
||||
//
|
||||
//
|
||||
// Custom Provider
|
||||
//
|
||||
// Each Provider built into this package also provides a helper method to generate
|
||||
// a Credentials pointer setup with the provider. To use a custom Provider just
|
||||
// create a type which satisfies the Provider interface and pass it to the
|
||||
// NewCredentials method.
|
||||
//
|
||||
// type MyProvider struct{}
|
||||
// func (m *MyProvider) Retrieve() (Value, error) {...}
|
||||
// func (m *MyProvider) IsExpired() bool {...}
|
||||
//
|
||||
// creds := NewCredentials(&MyProvider{})
|
||||
// credValue, err := creds.Get()
|
||||
//
|
||||
package credentials
|
||||
|
||||
import (
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
// AnonymousCredentials is an empty Credential object that can be used as
|
||||
// dummy placeholder credentials for requests that do not need signed.
|
||||
//
|
||||
// This Credentials can be used to configure a service to not sign requests
|
||||
// when making service API calls. For example, when accessing public
|
||||
// s3 buckets.
|
||||
//
|
||||
// svc := s3.New(&aws.Config{Credentials: AnonymousCredentials})
|
||||
// // Access public S3 buckets.
|
||||
//
|
||||
// @readonly
|
||||
var AnonymousCredentials = NewStaticCredentials("", "", "")
|
||||
|
||||
// A Value is the AWS credentials value for individual credential fields.
|
||||
type Value struct {
|
||||
// AWS Access key ID
|
||||
AccessKeyID string
|
||||
|
||||
// AWS Secret Access Key
|
||||
SecretAccessKey string
|
||||
|
||||
// AWS Session Token
|
||||
SessionToken string
|
||||
}
|
||||
|
||||
// A Provider is the interface for any component which will provide credentials
|
||||
// Value. A provider is required to manage its own Expired state, and what to
|
||||
// be expired means.
|
||||
//
|
||||
// The Provider should not need to implement its own mutexes, because
|
||||
// that will be managed by Credentials.
|
||||
type Provider interface {
|
||||
// Refresh returns nil if it successfully retrieved the value.
|
||||
// Error is returned if the value were not obtainable, or empty.
|
||||
Retrieve() (Value, error)
|
||||
|
||||
// IsExpired returns if the credentials are no longer valid, and need
|
||||
// to be retrieved.
|
||||
IsExpired() bool
|
||||
}
|
||||
|
||||
// A Expiry provides shared expiration logic to be used by credentials
|
||||
// providers to implement expiry functionality.
|
||||
//
|
||||
// The best method to use this struct is as an anonymous field within the
|
||||
// provider's struct.
|
||||
//
|
||||
// Example:
|
||||
// type EC2RoleProvider struct {
|
||||
// Expiry
|
||||
// ...
|
||||
// }
|
||||
type Expiry struct {
|
||||
// The date/time when to expire on
|
||||
expiration time.Time
|
||||
|
||||
// If set will be used by IsExpired to determine the current time.
|
||||
// Defaults to time.Now if CurrentTime is not set. Available for testing
|
||||
// to be able to mock out the current time.
|
||||
CurrentTime func() time.Time
|
||||
}
|
||||
|
||||
// SetExpiration sets the expiration IsExpired will check when called.
|
||||
//
|
||||
// If window is greater than 0 the expiration time will be reduced by the
|
||||
// window value.
|
||||
//
|
||||
// Using a window is helpful to trigger credentials to expire sooner than
|
||||
// the expiration time given to ensure no requests are made with expired
|
||||
// tokens.
|
||||
func (e *Expiry) SetExpiration(expiration time.Time, window time.Duration) {
|
||||
e.expiration = expiration
|
||||
if window > 0 {
|
||||
e.expiration = e.expiration.Add(-window)
|
||||
}
|
||||
}
|
||||
|
||||
// IsExpired returns if the credentials are expired.
|
||||
func (e *Expiry) IsExpired() bool {
|
||||
if e.CurrentTime == nil {
|
||||
e.CurrentTime = time.Now
|
||||
}
|
||||
return e.expiration.Before(e.CurrentTime())
|
||||
}
|
||||
|
||||
// A Credentials provides synchronous safe retrieval of AWS credentials Value.
|
||||
// Credentials will cache the credentials value until they expire. Once the value
|
||||
// expires the next Get will attempt to retrieve valid credentials.
|
||||
//
|
||||
// Credentials is safe to use across multiple goroutines and will manage the
|
||||
// synchronous state so the Providers do not need to implement their own
|
||||
// synchronization.
|
||||
//
|
||||
// The first Credentials.Get() will always call Provider.Retrieve() to get the
|
||||
// first instance of the credentials Value. All calls to Get() after that
|
||||
// will return the cached credentials Value until IsExpired() returns true.
|
||||
type Credentials struct {
|
||||
creds Value
|
||||
forceRefresh bool
|
||||
m sync.Mutex
|
||||
|
||||
provider Provider
|
||||
}
|
||||
|
||||
// NewCredentials returns a pointer to a new Credentials with the provider set.
|
||||
func NewCredentials(provider Provider) *Credentials {
|
||||
return &Credentials{
|
||||
provider: provider,
|
||||
forceRefresh: true,
|
||||
}
|
||||
}
|
||||
|
||||
// Get returns the credentials value, or error if the credentials Value failed
|
||||
// to be retrieved.
|
||||
//
|
||||
// Will return the cached credentials Value if it has not expired. If the
|
||||
// credentials Value has expired the Provider's Retrieve() will be called
|
||||
// to refresh the credentials.
|
||||
//
|
||||
// If Credentials.Expire() was called the credentials Value will be force
|
||||
// expired, and the next call to Get() will cause them to be refreshed.
|
||||
func (c *Credentials) Get() (Value, error) {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
|
||||
if c.isExpired() {
|
||||
creds, err := c.provider.Retrieve()
|
||||
if err != nil {
|
||||
return Value{}, err
|
||||
}
|
||||
c.creds = creds
|
||||
c.forceRefresh = false
|
||||
}
|
||||
|
||||
return c.creds, nil
|
||||
}
|
||||
|
||||
// Expire expires the credentials and forces them to be retrieved on the
|
||||
// next call to Get().
|
||||
//
|
||||
// This will override the Provider's expired state, and force Credentials
|
||||
// to call the Provider's Retrieve().
|
||||
func (c *Credentials) Expire() {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
|
||||
c.forceRefresh = true
|
||||
}
|
||||
|
||||
// IsExpired returns if the credentials are no longer valid, and need
|
||||
// to be retrieved.
|
||||
//
|
||||
// If the Credentials were forced to be expired with Expire() this will
|
||||
// reflect that override.
|
||||
func (c *Credentials) IsExpired() bool {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
|
||||
return c.isExpired()
|
||||
}
|
||||
|
||||
// isExpired helper method wrapping the definition of expired credentials.
|
||||
func (c *Credentials) isExpired() bool {
|
||||
return c.forceRefresh || c.provider.IsExpired()
|
||||
}
|
||||
62
Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/credentials/credentials_test.go
generated
vendored
Normal file
62
Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/credentials/credentials_test.go
generated
vendored
Normal file
@@ -0,0 +1,62 @@
|
||||
package credentials
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws/awserr"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
type stubProvider struct {
|
||||
creds Value
|
||||
expired bool
|
||||
err error
|
||||
}
|
||||
|
||||
func (s *stubProvider) Retrieve() (Value, error) {
|
||||
s.expired = false
|
||||
return s.creds, s.err
|
||||
}
|
||||
func (s *stubProvider) IsExpired() bool {
|
||||
return s.expired
|
||||
}
|
||||
|
||||
func TestCredentialsGet(t *testing.T) {
|
||||
c := NewCredentials(&stubProvider{
|
||||
creds: Value{
|
||||
AccessKeyID: "AKID",
|
||||
SecretAccessKey: "SECRET",
|
||||
SessionToken: "",
|
||||
},
|
||||
expired: true,
|
||||
})
|
||||
|
||||
creds, err := c.Get()
|
||||
assert.Nil(t, err, "Expected no error")
|
||||
assert.Equal(t, "AKID", creds.AccessKeyID, "Expect access key ID to match")
|
||||
assert.Equal(t, "SECRET", creds.SecretAccessKey, "Expect secret access key to match")
|
||||
assert.Empty(t, creds.SessionToken, "Expect session token to be empty")
|
||||
}
|
||||
|
||||
func TestCredentialsGetWithError(t *testing.T) {
|
||||
c := NewCredentials(&stubProvider{err: awserr.New("provider error", "", nil), expired: true})
|
||||
|
||||
_, err := c.Get()
|
||||
assert.Equal(t, "provider error", err.(awserr.Error).Code(), "Expected provider error")
|
||||
}
|
||||
|
||||
func TestCredentialsExpire(t *testing.T) {
|
||||
stub := &stubProvider{}
|
||||
c := NewCredentials(stub)
|
||||
|
||||
stub.expired = false
|
||||
assert.True(t, c.IsExpired(), "Expected to start out expired")
|
||||
c.Expire()
|
||||
assert.True(t, c.IsExpired(), "Expected to be expired")
|
||||
|
||||
c.forceRefresh = false
|
||||
assert.False(t, c.IsExpired(), "Expected not to be expired")
|
||||
|
||||
stub.expired = true
|
||||
assert.True(t, c.IsExpired(), "Expected to be expired")
|
||||
}
|
||||
173
Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/credentials/ec2rolecreds/ec2_role_provider.go
generated
vendored
Normal file
173
Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/credentials/ec2rolecreds/ec2_role_provider.go
generated
vendored
Normal file
@@ -0,0 +1,173 @@
|
||||
package ec2rolecreds
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"path"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws/awserr"
|
||||
"github.com/aws/aws-sdk-go/aws/client"
|
||||
"github.com/aws/aws-sdk-go/aws/credentials"
|
||||
"github.com/aws/aws-sdk-go/aws/ec2metadata"
|
||||
)
|
||||
|
||||
// A EC2RoleProvider retrieves credentials from the EC2 service, and keeps track if
|
||||
// those credentials are expired.
|
||||
//
|
||||
// Example how to configure the EC2RoleProvider with custom http Client, Endpoint
|
||||
// or ExpiryWindow
|
||||
//
|
||||
// p := &ec2rolecreds.EC2RoleProvider{
|
||||
// // Pass in a custom timeout to be used when requesting
|
||||
// // IAM EC2 Role credentials.
|
||||
// Client: &http.Client{
|
||||
// Timeout: 10 * time.Second,
|
||||
// },
|
||||
// // Do not use early expiry of credentials. If a non zero value is
|
||||
// // specified the credentials will be expired early
|
||||
// ExpiryWindow: 0,
|
||||
// }
|
||||
type EC2RoleProvider struct {
|
||||
credentials.Expiry
|
||||
|
||||
// Required EC2Metadata client to use when connecting to EC2 metadata service.
|
||||
Client *ec2metadata.EC2Metadata
|
||||
|
||||
// ExpiryWindow will allow the credentials to trigger refreshing prior to
|
||||
// the credentials actually expiring. This is beneficial so race conditions
|
||||
// with expiring credentials do not cause request to fail unexpectedly
|
||||
// due to ExpiredTokenException exceptions.
|
||||
//
|
||||
// So a ExpiryWindow of 10s would cause calls to IsExpired() to return true
|
||||
// 10 seconds before the credentials are actually expired.
|
||||
//
|
||||
// If ExpiryWindow is 0 or less it will be ignored.
|
||||
ExpiryWindow time.Duration
|
||||
}
|
||||
|
||||
// NewCredentials returns a pointer to a new Credentials object wrapping
|
||||
// the EC2RoleProvider. Takes a ConfigProvider to create a EC2Metadata client.
|
||||
// The ConfigProvider is satisfied by the session.Session type.
|
||||
func NewCredentials(c client.ConfigProvider, options ...func(*EC2RoleProvider)) *credentials.Credentials {
|
||||
p := &EC2RoleProvider{
|
||||
Client: ec2metadata.New(c),
|
||||
}
|
||||
|
||||
for _, option := range options {
|
||||
option(p)
|
||||
}
|
||||
|
||||
return credentials.NewCredentials(p)
|
||||
}
|
||||
|
||||
// NewCredentialsWithClient returns a pointer to a new Credentials object wrapping
|
||||
// the EC2RoleProvider. Takes a EC2Metadata client to use when connecting to EC2
|
||||
// metadata service.
|
||||
func NewCredentialsWithClient(client *ec2metadata.EC2Metadata, options ...func(*EC2RoleProvider)) *credentials.Credentials {
|
||||
p := &EC2RoleProvider{
|
||||
Client: client,
|
||||
}
|
||||
|
||||
for _, option := range options {
|
||||
option(p)
|
||||
}
|
||||
|
||||
return credentials.NewCredentials(p)
|
||||
}
|
||||
|
||||
// Retrieve retrieves credentials from the EC2 service.
|
||||
// Error will be returned if the request fails, or unable to extract
|
||||
// the desired credentials.
|
||||
func (m *EC2RoleProvider) Retrieve() (credentials.Value, error) {
|
||||
credsList, err := requestCredList(m.Client)
|
||||
if err != nil {
|
||||
return credentials.Value{}, err
|
||||
}
|
||||
|
||||
if len(credsList) == 0 {
|
||||
return credentials.Value{}, awserr.New("EmptyEC2RoleList", "empty EC2 Role list", nil)
|
||||
}
|
||||
credsName := credsList[0]
|
||||
|
||||
roleCreds, err := requestCred(m.Client, credsName)
|
||||
if err != nil {
|
||||
return credentials.Value{}, err
|
||||
}
|
||||
|
||||
m.SetExpiration(roleCreds.Expiration, m.ExpiryWindow)
|
||||
|
||||
return credentials.Value{
|
||||
AccessKeyID: roleCreds.AccessKeyID,
|
||||
SecretAccessKey: roleCreds.SecretAccessKey,
|
||||
SessionToken: roleCreds.Token,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// A ec2RoleCredRespBody provides the shape for unmarshalling credential
|
||||
// request responses.
|
||||
type ec2RoleCredRespBody struct {
|
||||
// Success State
|
||||
Expiration time.Time
|
||||
AccessKeyID string
|
||||
SecretAccessKey string
|
||||
Token string
|
||||
|
||||
// Error state
|
||||
Code string
|
||||
Message string
|
||||
}
|
||||
|
||||
const iamSecurityCredsPath = "/iam/security-credentials"
|
||||
|
||||
// requestCredList requests a list of credentials from the EC2 service.
|
||||
// If there are no credentials, or there is an error making or receiving the request
|
||||
func requestCredList(client *ec2metadata.EC2Metadata) ([]string, error) {
|
||||
resp, err := client.GetMetadata(iamSecurityCredsPath)
|
||||
if err != nil {
|
||||
return nil, awserr.New("EC2RoleRequestError", "failed to list EC2 Roles", err)
|
||||
}
|
||||
|
||||
credsList := []string{}
|
||||
s := bufio.NewScanner(strings.NewReader(resp))
|
||||
for s.Scan() {
|
||||
credsList = append(credsList, s.Text())
|
||||
}
|
||||
|
||||
if err := s.Err(); err != nil {
|
||||
return nil, awserr.New("SerializationError", "failed to read list of EC2 Roles", err)
|
||||
}
|
||||
|
||||
return credsList, nil
|
||||
}
|
||||
|
||||
// requestCred requests the credentials for a specific credentials from the EC2 service.
|
||||
//
|
||||
// If the credentials cannot be found, or there is an error reading the response
|
||||
// and error will be returned.
|
||||
func requestCred(client *ec2metadata.EC2Metadata, credsName string) (ec2RoleCredRespBody, error) {
|
||||
resp, err := client.GetMetadata(path.Join(iamSecurityCredsPath, credsName))
|
||||
if err != nil {
|
||||
return ec2RoleCredRespBody{},
|
||||
awserr.New("EC2RoleRequestError",
|
||||
fmt.Sprintf("failed to get %s EC2 Role credentials", credsName),
|
||||
err)
|
||||
}
|
||||
|
||||
respCreds := ec2RoleCredRespBody{}
|
||||
if err := json.NewDecoder(strings.NewReader(resp)).Decode(&respCreds); err != nil {
|
||||
return ec2RoleCredRespBody{},
|
||||
awserr.New("SerializationError",
|
||||
fmt.Sprintf("failed to decode %s EC2 Role credentials", credsName),
|
||||
err)
|
||||
}
|
||||
|
||||
if respCreds.Code != "Success" {
|
||||
// If an error code was returned something failed requesting the role.
|
||||
return ec2RoleCredRespBody{}, awserr.New(respCreds.Code, respCreds.Message, nil)
|
||||
}
|
||||
|
||||
return respCreds, nil
|
||||
}
|
||||
159
Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/credentials/ec2rolecreds/ec2_role_provider_test.go
generated
vendored
Normal file
159
Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/credentials/ec2rolecreds/ec2_role_provider_test.go
generated
vendored
Normal file
@@ -0,0 +1,159 @@
|
||||
package ec2rolecreds_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/aws/awserr"
|
||||
"github.com/aws/aws-sdk-go/aws/credentials/ec2rolecreds"
|
||||
"github.com/aws/aws-sdk-go/aws/ec2metadata"
|
||||
"github.com/aws/aws-sdk-go/aws/session"
|
||||
)
|
||||
|
||||
const credsRespTmpl = `{
|
||||
"Code": "Success",
|
||||
"Type": "AWS-HMAC",
|
||||
"AccessKeyId" : "accessKey",
|
||||
"SecretAccessKey" : "secret",
|
||||
"Token" : "token",
|
||||
"Expiration" : "%s",
|
||||
"LastUpdated" : "2009-11-23T0:00:00Z"
|
||||
}`
|
||||
|
||||
const credsFailRespTmpl = `{
|
||||
"Code": "ErrorCode",
|
||||
"Message": "ErrorMsg",
|
||||
"LastUpdated": "2009-11-23T0:00:00Z"
|
||||
}`
|
||||
|
||||
func initTestServer(expireOn string, failAssume bool) *httptest.Server {
|
||||
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
if r.URL.Path == "/latest/meta-data/iam/security-credentials" {
|
||||
fmt.Fprintln(w, "RoleName")
|
||||
} else if r.URL.Path == "/latest/meta-data/iam/security-credentials/RoleName" {
|
||||
if failAssume {
|
||||
fmt.Fprintf(w, credsFailRespTmpl)
|
||||
} else {
|
||||
fmt.Fprintf(w, credsRespTmpl, expireOn)
|
||||
}
|
||||
} else {
|
||||
http.Error(w, "bad request", http.StatusBadRequest)
|
||||
}
|
||||
}))
|
||||
|
||||
return server
|
||||
}
|
||||
|
||||
func TestEC2RoleProvider(t *testing.T) {
|
||||
server := initTestServer("2014-12-16T01:51:37Z", false)
|
||||
defer server.Close()
|
||||
|
||||
p := &ec2rolecreds.EC2RoleProvider{
|
||||
Client: ec2metadata.New(session.New(), &aws.Config{Endpoint: aws.String(server.URL + "/latest")}),
|
||||
}
|
||||
|
||||
creds, err := p.Retrieve()
|
||||
assert.Nil(t, err, "Expect no error, %v", err)
|
||||
|
||||
assert.Equal(t, "accessKey", creds.AccessKeyID, "Expect access key ID to match")
|
||||
assert.Equal(t, "secret", creds.SecretAccessKey, "Expect secret access key to match")
|
||||
assert.Equal(t, "token", creds.SessionToken, "Expect session token to match")
|
||||
}
|
||||
|
||||
func TestEC2RoleProviderFailAssume(t *testing.T) {
|
||||
server := initTestServer("2014-12-16T01:51:37Z", true)
|
||||
defer server.Close()
|
||||
|
||||
p := &ec2rolecreds.EC2RoleProvider{
|
||||
Client: ec2metadata.New(session.New(), &aws.Config{Endpoint: aws.String(server.URL + "/latest")}),
|
||||
}
|
||||
|
||||
creds, err := p.Retrieve()
|
||||
assert.Error(t, err, "Expect error")
|
||||
|
||||
e := err.(awserr.Error)
|
||||
assert.Equal(t, "ErrorCode", e.Code())
|
||||
assert.Equal(t, "ErrorMsg", e.Message())
|
||||
assert.Nil(t, e.OrigErr())
|
||||
|
||||
assert.Equal(t, "", creds.AccessKeyID, "Expect access key ID to match")
|
||||
assert.Equal(t, "", creds.SecretAccessKey, "Expect secret access key to match")
|
||||
assert.Equal(t, "", creds.SessionToken, "Expect session token to match")
|
||||
}
|
||||
|
||||
func TestEC2RoleProviderIsExpired(t *testing.T) {
|
||||
server := initTestServer("2014-12-16T01:51:37Z", false)
|
||||
defer server.Close()
|
||||
|
||||
p := &ec2rolecreds.EC2RoleProvider{
|
||||
Client: ec2metadata.New(session.New(), &aws.Config{Endpoint: aws.String(server.URL + "/latest")}),
|
||||
}
|
||||
p.CurrentTime = func() time.Time {
|
||||
return time.Date(2014, 12, 15, 21, 26, 0, 0, time.UTC)
|
||||
}
|
||||
|
||||
assert.True(t, p.IsExpired(), "Expect creds to be expired before retrieve.")
|
||||
|
||||
_, err := p.Retrieve()
|
||||
assert.Nil(t, err, "Expect no error, %v", err)
|
||||
|
||||
assert.False(t, p.IsExpired(), "Expect creds to not be expired after retrieve.")
|
||||
|
||||
p.CurrentTime = func() time.Time {
|
||||
return time.Date(3014, 12, 15, 21, 26, 0, 0, time.UTC)
|
||||
}
|
||||
|
||||
assert.True(t, p.IsExpired(), "Expect creds to be expired.")
|
||||
}
|
||||
|
||||
func TestEC2RoleProviderExpiryWindowIsExpired(t *testing.T) {
|
||||
server := initTestServer("2014-12-16T01:51:37Z", false)
|
||||
defer server.Close()
|
||||
|
||||
p := &ec2rolecreds.EC2RoleProvider{
|
||||
Client: ec2metadata.New(session.New(), &aws.Config{Endpoint: aws.String(server.URL + "/latest")}),
|
||||
ExpiryWindow: time.Hour * 1,
|
||||
}
|
||||
p.CurrentTime = func() time.Time {
|
||||
return time.Date(2014, 12, 15, 0, 51, 37, 0, time.UTC)
|
||||
}
|
||||
|
||||
assert.True(t, p.IsExpired(), "Expect creds to be expired before retrieve.")
|
||||
|
||||
_, err := p.Retrieve()
|
||||
assert.Nil(t, err, "Expect no error, %v", err)
|
||||
|
||||
assert.False(t, p.IsExpired(), "Expect creds to not be expired after retrieve.")
|
||||
|
||||
p.CurrentTime = func() time.Time {
|
||||
return time.Date(2014, 12, 16, 0, 55, 37, 0, time.UTC)
|
||||
}
|
||||
|
||||
assert.True(t, p.IsExpired(), "Expect creds to be expired.")
|
||||
}
|
||||
|
||||
func BenchmarkEC3RoleProvider(b *testing.B) {
|
||||
server := initTestServer("2014-12-16T01:51:37Z", false)
|
||||
defer server.Close()
|
||||
|
||||
p := &ec2rolecreds.EC2RoleProvider{
|
||||
Client: ec2metadata.New(session.New(), &aws.Config{Endpoint: aws.String(server.URL + "/latest")}),
|
||||
}
|
||||
_, err := p.Retrieve()
|
||||
if err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
if _, err := p.Retrieve(); err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
73
Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/credentials/env_provider.go
generated
vendored
Normal file
73
Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/credentials/env_provider.go
generated
vendored
Normal file
@@ -0,0 +1,73 @@
|
||||
package credentials
|
||||
|
||||
import (
|
||||
"os"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws/awserr"
|
||||
)
|
||||
|
||||
var (
|
||||
// ErrAccessKeyIDNotFound is returned when the AWS Access Key ID can't be
|
||||
// found in the process's environment.
|
||||
//
|
||||
// @readonly
|
||||
ErrAccessKeyIDNotFound = awserr.New("EnvAccessKeyNotFound", "AWS_ACCESS_KEY_ID or AWS_ACCESS_KEY not found in environment", nil)
|
||||
|
||||
// ErrSecretAccessKeyNotFound is returned when the AWS Secret Access Key
|
||||
// can't be found in the process's environment.
|
||||
//
|
||||
// @readonly
|
||||
ErrSecretAccessKeyNotFound = awserr.New("EnvSecretNotFound", "AWS_SECRET_ACCESS_KEY or AWS_SECRET_KEY not found in environment", nil)
|
||||
)
|
||||
|
||||
// A EnvProvider retrieves credentials from the environment variables of the
|
||||
// running process. Environment credentials never expire.
|
||||
//
|
||||
// Environment variables used:
|
||||
//
|
||||
// * Access Key ID: AWS_ACCESS_KEY_ID or AWS_ACCESS_KEY
|
||||
// * Secret Access Key: AWS_SECRET_ACCESS_KEY or AWS_SECRET_KEY
|
||||
type EnvProvider struct {
|
||||
retrieved bool
|
||||
}
|
||||
|
||||
// NewEnvCredentials returns a pointer to a new Credentials object
|
||||
// wrapping the environment variable provider.
|
||||
func NewEnvCredentials() *Credentials {
|
||||
return NewCredentials(&EnvProvider{})
|
||||
}
|
||||
|
||||
// Retrieve retrieves the keys from the environment.
|
||||
func (e *EnvProvider) Retrieve() (Value, error) {
|
||||
e.retrieved = false
|
||||
|
||||
id := os.Getenv("AWS_ACCESS_KEY_ID")
|
||||
if id == "" {
|
||||
id = os.Getenv("AWS_ACCESS_KEY")
|
||||
}
|
||||
|
||||
secret := os.Getenv("AWS_SECRET_ACCESS_KEY")
|
||||
if secret == "" {
|
||||
secret = os.Getenv("AWS_SECRET_KEY")
|
||||
}
|
||||
|
||||
if id == "" {
|
||||
return Value{}, ErrAccessKeyIDNotFound
|
||||
}
|
||||
|
||||
if secret == "" {
|
||||
return Value{}, ErrSecretAccessKeyNotFound
|
||||
}
|
||||
|
||||
e.retrieved = true
|
||||
return Value{
|
||||
AccessKeyID: id,
|
||||
SecretAccessKey: secret,
|
||||
SessionToken: os.Getenv("AWS_SESSION_TOKEN"),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// IsExpired returns if the credentials have been retrieved.
|
||||
func (e *EnvProvider) IsExpired() bool {
|
||||
return !e.retrieved
|
||||
}
|
||||
70
Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/credentials/env_provider_test.go
generated
vendored
Normal file
70
Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/credentials/env_provider_test.go
generated
vendored
Normal file
@@ -0,0 +1,70 @@
|
||||
package credentials
|
||||
|
||||
import (
|
||||
"github.com/stretchr/testify/assert"
|
||||
"os"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestEnvProviderRetrieve(t *testing.T) {
|
||||
os.Clearenv()
|
||||
os.Setenv("AWS_ACCESS_KEY_ID", "access")
|
||||
os.Setenv("AWS_SECRET_ACCESS_KEY", "secret")
|
||||
os.Setenv("AWS_SESSION_TOKEN", "token")
|
||||
|
||||
e := EnvProvider{}
|
||||
creds, err := e.Retrieve()
|
||||
assert.Nil(t, err, "Expect no error")
|
||||
|
||||
assert.Equal(t, "access", creds.AccessKeyID, "Expect access key ID to match")
|
||||
assert.Equal(t, "secret", creds.SecretAccessKey, "Expect secret access key to match")
|
||||
assert.Equal(t, "token", creds.SessionToken, "Expect session token to match")
|
||||
}
|
||||
|
||||
func TestEnvProviderIsExpired(t *testing.T) {
|
||||
os.Clearenv()
|
||||
os.Setenv("AWS_ACCESS_KEY_ID", "access")
|
||||
os.Setenv("AWS_SECRET_ACCESS_KEY", "secret")
|
||||
os.Setenv("AWS_SESSION_TOKEN", "token")
|
||||
|
||||
e := EnvProvider{}
|
||||
|
||||
assert.True(t, e.IsExpired(), "Expect creds to be expired before retrieve.")
|
||||
|
||||
_, err := e.Retrieve()
|
||||
assert.Nil(t, err, "Expect no error")
|
||||
|
||||
assert.False(t, e.IsExpired(), "Expect creds to not be expired after retrieve.")
|
||||
}
|
||||
|
||||
func TestEnvProviderNoAccessKeyID(t *testing.T) {
|
||||
os.Clearenv()
|
||||
os.Setenv("AWS_SECRET_ACCESS_KEY", "secret")
|
||||
|
||||
e := EnvProvider{}
|
||||
creds, err := e.Retrieve()
|
||||
assert.Equal(t, ErrAccessKeyIDNotFound, err, "ErrAccessKeyIDNotFound expected, but was %#v error: %#v", creds, err)
|
||||
}
|
||||
|
||||
func TestEnvProviderNoSecretAccessKey(t *testing.T) {
|
||||
os.Clearenv()
|
||||
os.Setenv("AWS_ACCESS_KEY_ID", "access")
|
||||
|
||||
e := EnvProvider{}
|
||||
creds, err := e.Retrieve()
|
||||
assert.Equal(t, ErrSecretAccessKeyNotFound, err, "ErrSecretAccessKeyNotFound expected, but was %#v error: %#v", creds, err)
|
||||
}
|
||||
|
||||
func TestEnvProviderAlternateNames(t *testing.T) {
|
||||
os.Clearenv()
|
||||
os.Setenv("AWS_ACCESS_KEY", "access")
|
||||
os.Setenv("AWS_SECRET_KEY", "secret")
|
||||
|
||||
e := EnvProvider{}
|
||||
creds, err := e.Retrieve()
|
||||
assert.Nil(t, err, "Expect no error")
|
||||
|
||||
assert.Equal(t, "access", creds.AccessKeyID, "Expected access key ID")
|
||||
assert.Equal(t, "secret", creds.SecretAccessKey, "Expected secret access key")
|
||||
assert.Empty(t, creds.SessionToken, "Expected no token")
|
||||
}
|
||||
12
Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/credentials/example.ini
generated
vendored
Normal file
12
Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/credentials/example.ini
generated
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
[default]
|
||||
aws_access_key_id = accessKey
|
||||
aws_secret_access_key = secret
|
||||
aws_session_token = token
|
||||
|
||||
[no_token]
|
||||
aws_access_key_id = accessKey
|
||||
aws_secret_access_key = secret
|
||||
|
||||
[with_colon]
|
||||
aws_access_key_id: accessKey
|
||||
aws_secret_access_key: secret
|
||||
147
Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/credentials/shared_credentials_provider.go
generated
vendored
Normal file
147
Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/credentials/shared_credentials_provider.go
generated
vendored
Normal file
@@ -0,0 +1,147 @@
|
||||
package credentials
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/go-ini/ini"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws/awserr"
|
||||
)
|
||||
|
||||
var (
|
||||
// ErrSharedCredentialsHomeNotFound is emitted when the user directory cannot be found.
|
||||
//
|
||||
// @readonly
|
||||
ErrSharedCredentialsHomeNotFound = awserr.New("UserHomeNotFound", "user home directory not found.", nil)
|
||||
)
|
||||
|
||||
// A SharedCredentialsProvider retrieves credentials from the current user's home
|
||||
// directory, and keeps track if those credentials are expired.
|
||||
//
|
||||
// Profile ini file example: $HOME/.aws/credentials
|
||||
type SharedCredentialsProvider struct {
|
||||
// Path to the shared credentials file.
|
||||
//
|
||||
// If empty will look for "AWS_SHARED_CREDENTIALS_FILE" env variable. If the
|
||||
// env value is empty will default to current user's home directory.
|
||||
// Linux/OSX: "$HOME/.aws/credentials"
|
||||
// Windows: "%USERPROFILE%\.aws\credentials"
|
||||
Filename string
|
||||
|
||||
// AWS Profile to extract credentials from the shared credentials file. If empty
|
||||
// will default to environment variable "AWS_PROFILE" or "default" if
|
||||
// environment variable is also not set.
|
||||
Profile string
|
||||
|
||||
// retrieved states if the credentials have been successfully retrieved.
|
||||
retrieved bool
|
||||
}
|
||||
|
||||
// NewSharedCredentials returns a pointer to a new Credentials object
|
||||
// wrapping the Profile file provider.
|
||||
func NewSharedCredentials(filename, profile string) *Credentials {
|
||||
return NewCredentials(&SharedCredentialsProvider{
|
||||
Filename: filename,
|
||||
Profile: profile,
|
||||
})
|
||||
}
|
||||
|
||||
// Retrieve reads and extracts the shared credentials from the current
|
||||
// users home directory.
|
||||
func (p *SharedCredentialsProvider) Retrieve() (Value, error) {
|
||||
p.retrieved = false
|
||||
|
||||
filename, err := p.filename()
|
||||
if err != nil {
|
||||
return Value{}, err
|
||||
}
|
||||
|
||||
creds, err := loadProfile(filename, p.profile())
|
||||
if err != nil {
|
||||
return Value{}, err
|
||||
}
|
||||
|
||||
p.retrieved = true
|
||||
return creds, nil
|
||||
}
|
||||
|
||||
// IsExpired returns if the shared credentials have expired.
|
||||
func (p *SharedCredentialsProvider) IsExpired() bool {
|
||||
return !p.retrieved
|
||||
}
|
||||
|
||||
// loadProfiles loads from the file pointed to by shared credentials filename for profile.
|
||||
// The credentials retrieved from the profile will be returned or error. Error will be
|
||||
// returned if it fails to read from the file, or the data is invalid.
|
||||
func loadProfile(filename, profile string) (Value, error) {
|
||||
config, err := ini.Load(filename)
|
||||
if err != nil {
|
||||
return Value{}, awserr.New("SharedCredsLoad", "failed to load shared credentials file", err)
|
||||
}
|
||||
iniProfile, err := config.GetSection(profile)
|
||||
if err != nil {
|
||||
return Value{}, awserr.New("SharedCredsLoad", "failed to get profile", err)
|
||||
}
|
||||
|
||||
id, err := iniProfile.GetKey("aws_access_key_id")
|
||||
if err != nil {
|
||||
return Value{}, awserr.New("SharedCredsAccessKey",
|
||||
fmt.Sprintf("shared credentials %s in %s did not contain aws_access_key_id", profile, filename),
|
||||
err)
|
||||
}
|
||||
|
||||
secret, err := iniProfile.GetKey("aws_secret_access_key")
|
||||
if err != nil {
|
||||
return Value{}, awserr.New("SharedCredsSecret",
|
||||
fmt.Sprintf("shared credentials %s in %s did not contain aws_secret_access_key", profile, filename),
|
||||
nil)
|
||||
}
|
||||
|
||||
// Default to empty string if not found
|
||||
token := iniProfile.Key("aws_session_token")
|
||||
|
||||
return Value{
|
||||
AccessKeyID: id.String(),
|
||||
SecretAccessKey: secret.String(),
|
||||
SessionToken: token.String(),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// filename returns the filename to use to read AWS shared credentials.
|
||||
//
|
||||
// Will return an error if the user's home directory path cannot be found.
|
||||
func (p *SharedCredentialsProvider) filename() (string, error) {
|
||||
if p.Filename == "" {
|
||||
if p.Filename = os.Getenv("AWS_SHARED_CREDENTIALS_FILE"); p.Filename != "" {
|
||||
return p.Filename, nil
|
||||
}
|
||||
|
||||
homeDir := os.Getenv("HOME") // *nix
|
||||
if homeDir == "" { // Windows
|
||||
homeDir = os.Getenv("USERPROFILE")
|
||||
}
|
||||
if homeDir == "" {
|
||||
return "", ErrSharedCredentialsHomeNotFound
|
||||
}
|
||||
|
||||
p.Filename = filepath.Join(homeDir, ".aws", "credentials")
|
||||
}
|
||||
|
||||
return p.Filename, nil
|
||||
}
|
||||
|
||||
// profile returns the AWS shared credentials profile. If empty will read
|
||||
// environment variable "AWS_PROFILE". If that is not set profile will
|
||||
// return "default".
|
||||
func (p *SharedCredentialsProvider) profile() string {
|
||||
if p.Profile == "" {
|
||||
p.Profile = os.Getenv("AWS_PROFILE")
|
||||
}
|
||||
if p.Profile == "" {
|
||||
p.Profile = "default"
|
||||
}
|
||||
|
||||
return p.Profile
|
||||
}
|
||||
100
Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/credentials/shared_credentials_provider_test.go
generated
vendored
Normal file
100
Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/credentials/shared_credentials_provider_test.go
generated
vendored
Normal file
@@ -0,0 +1,100 @@
|
||||
package credentials
|
||||
|
||||
import (
|
||||
"github.com/stretchr/testify/assert"
|
||||
"os"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestSharedCredentialsProvider(t *testing.T) {
|
||||
os.Clearenv()
|
||||
|
||||
p := SharedCredentialsProvider{Filename: "example.ini", Profile: ""}
|
||||
creds, err := p.Retrieve()
|
||||
assert.Nil(t, err, "Expect no error")
|
||||
|
||||
assert.Equal(t, "accessKey", creds.AccessKeyID, "Expect access key ID to match")
|
||||
assert.Equal(t, "secret", creds.SecretAccessKey, "Expect secret access key to match")
|
||||
assert.Equal(t, "token", creds.SessionToken, "Expect session token to match")
|
||||
}
|
||||
|
||||
func TestSharedCredentialsProviderIsExpired(t *testing.T) {
|
||||
os.Clearenv()
|
||||
|
||||
p := SharedCredentialsProvider{Filename: "example.ini", Profile: ""}
|
||||
|
||||
assert.True(t, p.IsExpired(), "Expect creds to be expired before retrieve")
|
||||
|
||||
_, err := p.Retrieve()
|
||||
assert.Nil(t, err, "Expect no error")
|
||||
|
||||
assert.False(t, p.IsExpired(), "Expect creds to not be expired after retrieve")
|
||||
}
|
||||
|
||||
func TestSharedCredentialsProviderWithAWS_SHARED_CREDENTIALS_FILE(t *testing.T) {
|
||||
os.Clearenv()
|
||||
os.Setenv("AWS_SHARED_CREDENTIALS_FILE", "example.ini")
|
||||
p := SharedCredentialsProvider{}
|
||||
creds, err := p.Retrieve()
|
||||
|
||||
assert.Nil(t, err, "Expect no error")
|
||||
|
||||
assert.Equal(t, "accessKey", creds.AccessKeyID, "Expect access key ID to match")
|
||||
assert.Equal(t, "secret", creds.SecretAccessKey, "Expect secret access key to match")
|
||||
assert.Equal(t, "token", creds.SessionToken, "Expect session token to match")
|
||||
}
|
||||
|
||||
func TestSharedCredentialsProviderWithAWS_PROFILE(t *testing.T) {
|
||||
os.Clearenv()
|
||||
os.Setenv("AWS_PROFILE", "no_token")
|
||||
|
||||
p := SharedCredentialsProvider{Filename: "example.ini", Profile: ""}
|
||||
creds, err := p.Retrieve()
|
||||
assert.Nil(t, err, "Expect no error")
|
||||
|
||||
assert.Equal(t, "accessKey", creds.AccessKeyID, "Expect access key ID to match")
|
||||
assert.Equal(t, "secret", creds.SecretAccessKey, "Expect secret access key to match")
|
||||
assert.Empty(t, creds.SessionToken, "Expect no token")
|
||||
}
|
||||
|
||||
func TestSharedCredentialsProviderWithoutTokenFromProfile(t *testing.T) {
|
||||
os.Clearenv()
|
||||
|
||||
p := SharedCredentialsProvider{Filename: "example.ini", Profile: "no_token"}
|
||||
creds, err := p.Retrieve()
|
||||
assert.Nil(t, err, "Expect no error")
|
||||
|
||||
assert.Equal(t, "accessKey", creds.AccessKeyID, "Expect access key ID to match")
|
||||
assert.Equal(t, "secret", creds.SecretAccessKey, "Expect secret access key to match")
|
||||
assert.Empty(t, creds.SessionToken, "Expect no token")
|
||||
}
|
||||
|
||||
func TestSharedCredentialsProviderColonInCredFile(t *testing.T) {
|
||||
os.Clearenv()
|
||||
|
||||
p := SharedCredentialsProvider{Filename: "example.ini", Profile: "with_colon"}
|
||||
creds, err := p.Retrieve()
|
||||
assert.Nil(t, err, "Expect no error")
|
||||
|
||||
assert.Equal(t, "accessKey", creds.AccessKeyID, "Expect access key ID to match")
|
||||
assert.Equal(t, "secret", creds.SecretAccessKey, "Expect secret access key to match")
|
||||
assert.Empty(t, creds.SessionToken, "Expect no token")
|
||||
}
|
||||
|
||||
func BenchmarkSharedCredentialsProvider(b *testing.B) {
|
||||
os.Clearenv()
|
||||
|
||||
p := SharedCredentialsProvider{Filename: "example.ini", Profile: ""}
|
||||
_, err := p.Retrieve()
|
||||
if err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
_, err := p.Retrieve()
|
||||
if err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
44
Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/credentials/static_provider.go
generated
vendored
Normal file
44
Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/credentials/static_provider.go
generated
vendored
Normal file
@@ -0,0 +1,44 @@
|
||||
package credentials
|
||||
|
||||
import (
|
||||
"github.com/aws/aws-sdk-go/aws/awserr"
|
||||
)
|
||||
|
||||
var (
|
||||
// ErrStaticCredentialsEmpty is emitted when static credentials are empty.
|
||||
//
|
||||
// @readonly
|
||||
ErrStaticCredentialsEmpty = awserr.New("EmptyStaticCreds", "static credentials are empty", nil)
|
||||
)
|
||||
|
||||
// A StaticProvider is a set of credentials which are set pragmatically,
|
||||
// and will never expire.
|
||||
type StaticProvider struct {
|
||||
Value
|
||||
}
|
||||
|
||||
// NewStaticCredentials returns a pointer to a new Credentials object
|
||||
// wrapping a static credentials value provider.
|
||||
func NewStaticCredentials(id, secret, token string) *Credentials {
|
||||
return NewCredentials(&StaticProvider{Value: Value{
|
||||
AccessKeyID: id,
|
||||
SecretAccessKey: secret,
|
||||
SessionToken: token,
|
||||
}})
|
||||
}
|
||||
|
||||
// Retrieve returns the credentials or error if the credentials are invalid.
|
||||
func (s *StaticProvider) Retrieve() (Value, error) {
|
||||
if s.AccessKeyID == "" || s.SecretAccessKey == "" {
|
||||
return Value{}, ErrStaticCredentialsEmpty
|
||||
}
|
||||
|
||||
return s.Value, nil
|
||||
}
|
||||
|
||||
// IsExpired returns if the credentials are expired.
|
||||
//
|
||||
// For StaticProvider, the credentials never expired.
|
||||
func (s *StaticProvider) IsExpired() bool {
|
||||
return false
|
||||
}
|
||||
34
Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/credentials/static_provider_test.go
generated
vendored
Normal file
34
Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/credentials/static_provider_test.go
generated
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
package credentials
|
||||
|
||||
import (
|
||||
"github.com/stretchr/testify/assert"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestStaticProviderGet(t *testing.T) {
|
||||
s := StaticProvider{
|
||||
Value: Value{
|
||||
AccessKeyID: "AKID",
|
||||
SecretAccessKey: "SECRET",
|
||||
SessionToken: "",
|
||||
},
|
||||
}
|
||||
|
||||
creds, err := s.Retrieve()
|
||||
assert.Nil(t, err, "Expect no error")
|
||||
assert.Equal(t, "AKID", creds.AccessKeyID, "Expect access key ID to match")
|
||||
assert.Equal(t, "SECRET", creds.SecretAccessKey, "Expect secret access key to match")
|
||||
assert.Empty(t, creds.SessionToken, "Expect no session token")
|
||||
}
|
||||
|
||||
func TestStaticProviderIsExpired(t *testing.T) {
|
||||
s := StaticProvider{
|
||||
Value: Value{
|
||||
AccessKeyID: "AKID",
|
||||
SecretAccessKey: "SECRET",
|
||||
SessionToken: "",
|
||||
},
|
||||
}
|
||||
|
||||
assert.False(t, s.IsExpired(), "Expect static credentials to never expire")
|
||||
}
|
||||
130
Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/credentials/stscreds/assume_role_provider.go
generated
vendored
Normal file
130
Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/credentials/stscreds/assume_role_provider.go
generated
vendored
Normal file
@@ -0,0 +1,130 @@
|
||||
// Package stscreds are credential Providers to retrieve STS AWS credentials.
|
||||
//
|
||||
// STS provides multiple ways to retrieve credentials which can be used when making
|
||||
// future AWS service API operation calls.
|
||||
package stscreds
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/aws/client"
|
||||
"github.com/aws/aws-sdk-go/aws/credentials"
|
||||
"github.com/aws/aws-sdk-go/service/sts"
|
||||
)
|
||||
|
||||
// AssumeRoler represents the minimal subset of the STS client API used by this provider.
|
||||
type AssumeRoler interface {
|
||||
AssumeRole(input *sts.AssumeRoleInput) (*sts.AssumeRoleOutput, error)
|
||||
}
|
||||
|
||||
// DefaultDuration is the default amount of time in minutes that the credentials
|
||||
// will be valid for.
|
||||
var DefaultDuration = time.Duration(15) * time.Minute
|
||||
|
||||
// AssumeRoleProvider retrieves temporary credentials from the STS service, and
|
||||
// keeps track of their expiration time. This provider must be used explicitly,
|
||||
// as it is not included in the credentials chain.
|
||||
type AssumeRoleProvider struct {
|
||||
credentials.Expiry
|
||||
|
||||
// STS client to make assume role request with.
|
||||
Client AssumeRoler
|
||||
|
||||
// Role to be assumed.
|
||||
RoleARN string
|
||||
|
||||
// Session name, if you wish to reuse the credentials elsewhere.
|
||||
RoleSessionName string
|
||||
|
||||
// Expiry duration of the STS credentials. Defaults to 15 minutes if not set.
|
||||
Duration time.Duration
|
||||
|
||||
// Optional ExternalID to pass along, defaults to nil if not set.
|
||||
ExternalID *string
|
||||
|
||||
// ExpiryWindow will allow the credentials to trigger refreshing prior to
|
||||
// the credentials actually expiring. This is beneficial so race conditions
|
||||
// with expiring credentials do not cause request to fail unexpectedly
|
||||
// due to ExpiredTokenException exceptions.
|
||||
//
|
||||
// So a ExpiryWindow of 10s would cause calls to IsExpired() to return true
|
||||
// 10 seconds before the credentials are actually expired.
|
||||
//
|
||||
// If ExpiryWindow is 0 or less it will be ignored.
|
||||
ExpiryWindow time.Duration
|
||||
}
|
||||
|
||||
// NewCredentials returns a pointer to a new Credentials object wrapping the
|
||||
// AssumeRoleProvider. The credentials will expire every 15 minutes and the
|
||||
// role will be named after a nanosecond timestamp of this operation.
|
||||
//
|
||||
// Takes a Config provider to create the STS client. The ConfigProvider is
|
||||
// satisfied by the session.Session type.
|
||||
func NewCredentials(c client.ConfigProvider, roleARN string, options ...func(*AssumeRoleProvider)) *credentials.Credentials {
|
||||
p := &AssumeRoleProvider{
|
||||
Client: sts.New(c),
|
||||
RoleARN: roleARN,
|
||||
Duration: DefaultDuration,
|
||||
}
|
||||
|
||||
for _, option := range options {
|
||||
option(p)
|
||||
}
|
||||
|
||||
return credentials.NewCredentials(p)
|
||||
}
|
||||
|
||||
// NewCredentialsWithClient returns a pointer to a new Credentials object wrapping the
|
||||
// AssumeRoleProvider. The credentials will expire every 15 minutes and the
|
||||
// role will be named after a nanosecond timestamp of this operation.
|
||||
//
|
||||
// Takes an AssumeRoler which can be satisfiede by the STS client.
|
||||
func NewCredentialsWithClient(svc AssumeRoler, roleARN string, options ...func(*AssumeRoleProvider)) *credentials.Credentials {
|
||||
p := &AssumeRoleProvider{
|
||||
Client: svc,
|
||||
RoleARN: roleARN,
|
||||
Duration: DefaultDuration,
|
||||
}
|
||||
|
||||
for _, option := range options {
|
||||
option(p)
|
||||
}
|
||||
|
||||
return credentials.NewCredentials(p)
|
||||
}
|
||||
|
||||
// Retrieve generates a new set of temporary credentials using STS.
|
||||
func (p *AssumeRoleProvider) Retrieve() (credentials.Value, error) {
|
||||
|
||||
// Apply defaults where parameters are not set.
|
||||
if p.RoleSessionName == "" {
|
||||
// Try to work out a role name that will hopefully end up unique.
|
||||
p.RoleSessionName = fmt.Sprintf("%d", time.Now().UTC().UnixNano())
|
||||
}
|
||||
if p.Duration == 0 {
|
||||
// Expire as often as AWS permits.
|
||||
p.Duration = DefaultDuration
|
||||
}
|
||||
|
||||
roleOutput, err := p.Client.AssumeRole(&sts.AssumeRoleInput{
|
||||
DurationSeconds: aws.Int64(int64(p.Duration / time.Second)),
|
||||
RoleArn: aws.String(p.RoleARN),
|
||||
RoleSessionName: aws.String(p.RoleSessionName),
|
||||
ExternalId: p.ExternalID,
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return credentials.Value{}, err
|
||||
}
|
||||
|
||||
// We will proactively generate new credentials before they expire.
|
||||
p.SetExpiration(*roleOutput.Credentials.Expiration, p.ExpiryWindow)
|
||||
|
||||
return credentials.Value{
|
||||
AccessKeyID: *roleOutput.Credentials.AccessKeyId,
|
||||
SecretAccessKey: *roleOutput.Credentials.SecretAccessKey,
|
||||
SessionToken: *roleOutput.Credentials.SessionToken,
|
||||
}, nil
|
||||
}
|
||||
56
Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/credentials/stscreds/assume_role_provider_test.go
generated
vendored
Normal file
56
Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/credentials/stscreds/assume_role_provider_test.go
generated
vendored
Normal file
@@ -0,0 +1,56 @@
|
||||
package stscreds
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/service/sts"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
type stubSTS struct {
|
||||
}
|
||||
|
||||
func (s *stubSTS) AssumeRole(input *sts.AssumeRoleInput) (*sts.AssumeRoleOutput, error) {
|
||||
expiry := time.Now().Add(60 * time.Minute)
|
||||
return &sts.AssumeRoleOutput{
|
||||
Credentials: &sts.Credentials{
|
||||
// Just reflect the role arn to the provider.
|
||||
AccessKeyId: input.RoleArn,
|
||||
SecretAccessKey: aws.String("assumedSecretAccessKey"),
|
||||
SessionToken: aws.String("assumedSessionToken"),
|
||||
Expiration: &expiry,
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
func TestAssumeRoleProvider(t *testing.T) {
|
||||
stub := &stubSTS{}
|
||||
p := &AssumeRoleProvider{
|
||||
Client: stub,
|
||||
RoleARN: "roleARN",
|
||||
}
|
||||
|
||||
creds, err := p.Retrieve()
|
||||
assert.Nil(t, err, "Expect no error")
|
||||
|
||||
assert.Equal(t, "roleARN", creds.AccessKeyID, "Expect access key ID to be reflected role ARN")
|
||||
assert.Equal(t, "assumedSecretAccessKey", creds.SecretAccessKey, "Expect secret access key to match")
|
||||
assert.Equal(t, "assumedSessionToken", creds.SessionToken, "Expect session token to match")
|
||||
}
|
||||
|
||||
func BenchmarkAssumeRoleProvider(b *testing.B) {
|
||||
stub := &stubSTS{}
|
||||
p := &AssumeRoleProvider{
|
||||
Client: stub,
|
||||
RoleARN: "roleARN",
|
||||
}
|
||||
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
if _, err := p.Retrieve(); err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
76
Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/defaults/defaults.go
generated
vendored
Normal file
76
Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/defaults/defaults.go
generated
vendored
Normal file
@@ -0,0 +1,76 @@
|
||||
// Package defaults is a collection of helpers to retrieve the SDK's default
|
||||
// configuration and handlers.
|
||||
package defaults
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/aws/corehandlers"
|
||||
"github.com/aws/aws-sdk-go/aws/credentials"
|
||||
"github.com/aws/aws-sdk-go/aws/credentials/ec2rolecreds"
|
||||
"github.com/aws/aws-sdk-go/aws/ec2metadata"
|
||||
"github.com/aws/aws-sdk-go/aws/request"
|
||||
"github.com/aws/aws-sdk-go/private/endpoints"
|
||||
)
|
||||
|
||||
// A Defaults provides a collection of default values for SDK clients.
|
||||
type Defaults struct {
|
||||
Config *aws.Config
|
||||
Handlers request.Handlers
|
||||
}
|
||||
|
||||
// Get returns the SDK's default values with Config and handlers pre-configured.
|
||||
func Get() Defaults {
|
||||
cfg := Config()
|
||||
handlers := Handlers()
|
||||
cfg.Credentials = CredChain(cfg, handlers)
|
||||
|
||||
return Defaults{
|
||||
Config: cfg,
|
||||
Handlers: handlers,
|
||||
}
|
||||
}
|
||||
|
||||
// Config returns the default configuration.
|
||||
func Config() *aws.Config {
|
||||
return aws.NewConfig().
|
||||
WithCredentials(credentials.AnonymousCredentials).
|
||||
WithRegion(os.Getenv("AWS_REGION")).
|
||||
WithHTTPClient(http.DefaultClient).
|
||||
WithMaxRetries(aws.UseServiceDefaultRetries).
|
||||
WithLogger(aws.NewDefaultLogger()).
|
||||
WithLogLevel(aws.LogOff).
|
||||
WithSleepDelay(time.Sleep)
|
||||
}
|
||||
|
||||
// Handlers returns the default request handlers.
|
||||
func Handlers() request.Handlers {
|
||||
var handlers request.Handlers
|
||||
|
||||
handlers.Validate.PushBackNamed(corehandlers.ValidateEndpointHandler)
|
||||
handlers.Build.PushBackNamed(corehandlers.SDKVersionUserAgentHandler)
|
||||
handlers.Sign.PushBackNamed(corehandlers.BuildContentLengthHandler)
|
||||
handlers.Send.PushBackNamed(corehandlers.SendHandler)
|
||||
handlers.AfterRetry.PushBackNamed(corehandlers.AfterRetryHandler)
|
||||
handlers.ValidateResponse.PushBackNamed(corehandlers.ValidateResponseHandler)
|
||||
|
||||
return handlers
|
||||
}
|
||||
|
||||
// CredChain returns the default credential chain.
|
||||
func CredChain(cfg *aws.Config, handlers request.Handlers) *credentials.Credentials {
|
||||
endpoint, signingRegion := endpoints.EndpointForRegion(ec2metadata.ServiceName, *cfg.Region, true)
|
||||
|
||||
return credentials.NewChainCredentials(
|
||||
[]credentials.Provider{
|
||||
&credentials.EnvProvider{},
|
||||
&credentials.SharedCredentialsProvider{Filename: "", Profile: ""},
|
||||
&ec2rolecreds.EC2RoleProvider{
|
||||
Client: ec2metadata.NewClient(*cfg, handlers, endpoint, signingRegion),
|
||||
ExpiryWindow: 5 * time.Minute,
|
||||
},
|
||||
})
|
||||
}
|
||||
43
Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/ec2metadata/api.go
generated
vendored
Normal file
43
Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/ec2metadata/api.go
generated
vendored
Normal file
@@ -0,0 +1,43 @@
|
||||
package ec2metadata
|
||||
|
||||
import (
|
||||
"path"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws/request"
|
||||
)
|
||||
|
||||
// GetMetadata uses the path provided to request
|
||||
func (c *EC2Metadata) GetMetadata(p string) (string, error) {
|
||||
op := &request.Operation{
|
||||
Name: "GetMetadata",
|
||||
HTTPMethod: "GET",
|
||||
HTTPPath: path.Join("/", "meta-data", p),
|
||||
}
|
||||
|
||||
output := &metadataOutput{}
|
||||
req := c.NewRequest(op, nil, output)
|
||||
|
||||
return output.Content, req.Send()
|
||||
}
|
||||
|
||||
// Region returns the region the instance is running in.
|
||||
func (c *EC2Metadata) Region() (string, error) {
|
||||
resp, err := c.GetMetadata("placement/availability-zone")
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
// returns region without the suffix. Eg: us-west-2a becomes us-west-2
|
||||
return resp[:len(resp)-1], nil
|
||||
}
|
||||
|
||||
// Available returns if the application has access to the EC2 Metadata service.
|
||||
// Can be used to determine if application is running within an EC2 Instance and
|
||||
// the metadata service is available.
|
||||
func (c *EC2Metadata) Available() bool {
|
||||
if _, err := c.GetMetadata("instance-id"); err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
101
Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/ec2metadata/api_test.go
generated
vendored
Normal file
101
Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/ec2metadata/api_test.go
generated
vendored
Normal file
@@ -0,0 +1,101 @@
|
||||
package ec2metadata_test
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"path"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/aws/awserr"
|
||||
"github.com/aws/aws-sdk-go/aws/ec2metadata"
|
||||
"github.com/aws/aws-sdk-go/aws/request"
|
||||
"github.com/aws/aws-sdk-go/aws/session"
|
||||
)
|
||||
|
||||
func initTestServer(path string, resp string) *httptest.Server {
|
||||
return httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
if r.RequestURI != path {
|
||||
http.Error(w, "not found", http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
|
||||
w.Write([]byte(resp))
|
||||
}))
|
||||
}
|
||||
|
||||
func TestEndpoint(t *testing.T) {
|
||||
c := ec2metadata.New(session.New())
|
||||
op := &request.Operation{
|
||||
Name: "GetMetadata",
|
||||
HTTPMethod: "GET",
|
||||
HTTPPath: path.Join("/", "meta-data", "testpath"),
|
||||
}
|
||||
|
||||
req := c.NewRequest(op, nil, nil)
|
||||
assert.Equal(t, "http://169.254.169.254/latest", req.ClientInfo.Endpoint)
|
||||
assert.Equal(t, "http://169.254.169.254/latest/meta-data/testpath", req.HTTPRequest.URL.String())
|
||||
}
|
||||
|
||||
func TestGetMetadata(t *testing.T) {
|
||||
server := initTestServer(
|
||||
"/latest/meta-data/some/path",
|
||||
"success", // real response includes suffix
|
||||
)
|
||||
defer server.Close()
|
||||
c := ec2metadata.New(session.New(), &aws.Config{Endpoint: aws.String(server.URL + "/latest")})
|
||||
|
||||
resp, err := c.GetMetadata("some/path")
|
||||
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, "success", resp)
|
||||
}
|
||||
|
||||
func TestGetRegion(t *testing.T) {
|
||||
server := initTestServer(
|
||||
"/latest/meta-data/placement/availability-zone",
|
||||
"us-west-2a", // real response includes suffix
|
||||
)
|
||||
defer server.Close()
|
||||
c := ec2metadata.New(session.New(), &aws.Config{Endpoint: aws.String(server.URL + "/latest")})
|
||||
|
||||
region, err := c.Region()
|
||||
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, "us-west-2", region)
|
||||
}
|
||||
|
||||
func TestMetadataAvailable(t *testing.T) {
|
||||
server := initTestServer(
|
||||
"/latest/meta-data/instance-id",
|
||||
"instance-id",
|
||||
)
|
||||
defer server.Close()
|
||||
c := ec2metadata.New(session.New(), &aws.Config{Endpoint: aws.String(server.URL + "/latest")})
|
||||
|
||||
available := c.Available()
|
||||
|
||||
assert.True(t, available)
|
||||
}
|
||||
|
||||
func TestMetadataNotAvailable(t *testing.T) {
|
||||
c := ec2metadata.New(session.New())
|
||||
c.Handlers.Send.Clear()
|
||||
c.Handlers.Send.PushBack(func(r *request.Request) {
|
||||
r.HTTPResponse = &http.Response{
|
||||
StatusCode: int(0),
|
||||
Status: http.StatusText(int(0)),
|
||||
Body: ioutil.NopCloser(bytes.NewReader([]byte{})),
|
||||
}
|
||||
r.Error = awserr.New("RequestError", "send request failed", nil)
|
||||
r.Retryable = aws.Bool(true) // network errors are retryable
|
||||
})
|
||||
|
||||
available := c.Available()
|
||||
|
||||
assert.False(t, available)
|
||||
}
|
||||
116
Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/ec2metadata/service.go
generated
vendored
Normal file
116
Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/ec2metadata/service.go
generated
vendored
Normal file
@@ -0,0 +1,116 @@
|
||||
// Package ec2metadata provides the client for making API calls to the
|
||||
// EC2 Metadata service.
|
||||
package ec2metadata
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"net"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/aws/awserr"
|
||||
"github.com/aws/aws-sdk-go/aws/client"
|
||||
"github.com/aws/aws-sdk-go/aws/client/metadata"
|
||||
"github.com/aws/aws-sdk-go/aws/request"
|
||||
)
|
||||
|
||||
// ServiceName is the name of the service.
|
||||
const ServiceName = "ec2metadata"
|
||||
|
||||
// A EC2Metadata is an EC2 Metadata service Client.
|
||||
type EC2Metadata struct {
|
||||
*client.Client
|
||||
}
|
||||
|
||||
// New creates a new instance of the EC2Metadata client with a session.
|
||||
// This client is safe to use across multiple goroutines.
|
||||
//
|
||||
// Example:
|
||||
// // Create a EC2Metadata client from just a session.
|
||||
// svc := ec2metadata.New(mySession)
|
||||
//
|
||||
// // Create a EC2Metadata client with additional configuration
|
||||
// svc := ec2metadata.New(mySession, aws.NewConfig().WithLogLevel(aws.LogDebugHTTPBody))
|
||||
func New(p client.ConfigProvider, cfgs ...*aws.Config) *EC2Metadata {
|
||||
c := p.ClientConfig(ServiceName, cfgs...)
|
||||
return NewClient(*c.Config, c.Handlers, c.Endpoint, c.SigningRegion)
|
||||
}
|
||||
|
||||
// NewClient returns a new EC2Metadata client. Should be used to create
|
||||
// a client when not using a session. Generally using just New with a session
|
||||
// is preferred.
|
||||
func NewClient(cfg aws.Config, handlers request.Handlers, endpoint, signingRegion string, opts ...func(*client.Client)) *EC2Metadata {
|
||||
// If the default http client is provided, replace it with a custom
|
||||
// client using default timeouts.
|
||||
if cfg.HTTPClient == http.DefaultClient {
|
||||
cfg.HTTPClient = &http.Client{
|
||||
Transport: &http.Transport{
|
||||
Proxy: http.ProxyFromEnvironment,
|
||||
Dial: (&net.Dialer{
|
||||
// use a shorter timeout than default because the metadata
|
||||
// service is local if it is running, and to fail faster
|
||||
// if not running on an ec2 instance.
|
||||
Timeout: 5 * time.Second,
|
||||
KeepAlive: 30 * time.Second,
|
||||
}).Dial,
|
||||
TLSHandshakeTimeout: 10 * time.Second,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
svc := &EC2Metadata{
|
||||
Client: client.New(
|
||||
cfg,
|
||||
metadata.ClientInfo{
|
||||
ServiceName: ServiceName,
|
||||
Endpoint: endpoint,
|
||||
APIVersion: "latest",
|
||||
},
|
||||
handlers,
|
||||
),
|
||||
}
|
||||
|
||||
svc.Handlers.Unmarshal.PushBack(unmarshalHandler)
|
||||
svc.Handlers.UnmarshalError.PushBack(unmarshalError)
|
||||
svc.Handlers.Validate.Clear()
|
||||
svc.Handlers.Validate.PushBack(validateEndpointHandler)
|
||||
|
||||
// Add additional options to the service config
|
||||
for _, option := range opts {
|
||||
option(svc.Client)
|
||||
}
|
||||
|
||||
return svc
|
||||
}
|
||||
|
||||
type metadataOutput struct {
|
||||
Content string
|
||||
}
|
||||
|
||||
func unmarshalHandler(r *request.Request) {
|
||||
defer r.HTTPResponse.Body.Close()
|
||||
b, err := ioutil.ReadAll(r.HTTPResponse.Body)
|
||||
if err != nil {
|
||||
r.Error = awserr.New("SerializationError", "unable to unmarshal EC2 metadata respose", err)
|
||||
}
|
||||
|
||||
data := r.Data.(*metadataOutput)
|
||||
data.Content = string(b)
|
||||
}
|
||||
|
||||
func unmarshalError(r *request.Request) {
|
||||
defer r.HTTPResponse.Body.Close()
|
||||
_, err := ioutil.ReadAll(r.HTTPResponse.Body)
|
||||
if err != nil {
|
||||
r.Error = awserr.New("SerializationError", "unable to unmarshal EC2 metadata error respose", err)
|
||||
}
|
||||
|
||||
// TODO extract the error...
|
||||
}
|
||||
|
||||
func validateEndpointHandler(r *request.Request) {
|
||||
if r.ClientInfo.Endpoint == "" {
|
||||
r.Error = aws.ErrMissingEndpoint
|
||||
}
|
||||
}
|
||||
17
Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/errors.go
generated
vendored
Normal file
17
Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/errors.go
generated
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
package aws
|
||||
|
||||
import "github.com/aws/aws-sdk-go/aws/awserr"
|
||||
|
||||
var (
|
||||
// ErrMissingRegion is an error that is returned if region configuration is
|
||||
// not found.
|
||||
//
|
||||
// @readonly
|
||||
ErrMissingRegion = awserr.New("MissingRegion", "could not find region configuration", nil)
|
||||
|
||||
// ErrMissingEndpoint is an error that is returned if an endpoint cannot be
|
||||
// resolved for a service.
|
||||
//
|
||||
// @readonly
|
||||
ErrMissingEndpoint = awserr.New("MissingEndpoint", "'Endpoint' configuration is required for this service", nil)
|
||||
)
|
||||
98
Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/logger.go
generated
vendored
Normal file
98
Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/logger.go
generated
vendored
Normal file
@@ -0,0 +1,98 @@
|
||||
package aws
|
||||
|
||||
import (
|
||||
"log"
|
||||
"os"
|
||||
)
|
||||
|
||||
// A LogLevelType defines the level logging should be performed at. Used to instruct
|
||||
// the SDK which statements should be logged.
|
||||
type LogLevelType uint
|
||||
|
||||
// LogLevel returns the pointer to a LogLevel. Should be used to workaround
|
||||
// not being able to take the address of a non-composite literal.
|
||||
func LogLevel(l LogLevelType) *LogLevelType {
|
||||
return &l
|
||||
}
|
||||
|
||||
// Value returns the LogLevel value or the default value LogOff if the LogLevel
|
||||
// is nil. Safe to use on nil value LogLevelTypes.
|
||||
func (l *LogLevelType) Value() LogLevelType {
|
||||
if l != nil {
|
||||
return *l
|
||||
}
|
||||
return LogOff
|
||||
}
|
||||
|
||||
// Matches returns true if the v LogLevel is enabled by this LogLevel. Should be
|
||||
// used with logging sub levels. Is safe to use on nil value LogLevelTypes. If
|
||||
// LogLevel is nill, will default to LogOff comparison.
|
||||
func (l *LogLevelType) Matches(v LogLevelType) bool {
|
||||
c := l.Value()
|
||||
return c&v == v
|
||||
}
|
||||
|
||||
// AtLeast returns true if this LogLevel is at least high enough to satisfies v.
|
||||
// Is safe to use on nil value LogLevelTypes. If LogLevel is nill, will default
|
||||
// to LogOff comparison.
|
||||
func (l *LogLevelType) AtLeast(v LogLevelType) bool {
|
||||
c := l.Value()
|
||||
return c >= v
|
||||
}
|
||||
|
||||
const (
|
||||
// LogOff states that no logging should be performed by the SDK. This is the
|
||||
// default state of the SDK, and should be use to disable all logging.
|
||||
LogOff LogLevelType = iota * 0x1000
|
||||
|
||||
// LogDebug state that debug output should be logged by the SDK. This should
|
||||
// be used to inspect request made and responses received.
|
||||
LogDebug
|
||||
)
|
||||
|
||||
// Debug Logging Sub Levels
|
||||
const (
|
||||
// LogDebugWithSigning states that the SDK should log request signing and
|
||||
// presigning events. This should be used to log the signing details of
|
||||
// requests for debugging. Will also enable LogDebug.
|
||||
LogDebugWithSigning LogLevelType = LogDebug | (1 << iota)
|
||||
|
||||
// LogDebugWithHTTPBody states the SDK should log HTTP request and response
|
||||
// HTTP bodys in addition to the headers and path. This should be used to
|
||||
// see the body content of requests and responses made while using the SDK
|
||||
// Will also enable LogDebug.
|
||||
LogDebugWithHTTPBody
|
||||
|
||||
// LogDebugWithRequestRetries states the SDK should log when service requests will
|
||||
// be retried. This should be used to log when you want to log when service
|
||||
// requests are being retried. Will also enable LogDebug.
|
||||
LogDebugWithRequestRetries
|
||||
|
||||
// LogDebugWithRequestErrors states the SDK should log when service requests fail
|
||||
// to build, send, validate, or unmarshal.
|
||||
LogDebugWithRequestErrors
|
||||
)
|
||||
|
||||
// A Logger is a minimalistic interface for the SDK to log messages to. Should
|
||||
// be used to provide custom logging writers for the SDK to use.
|
||||
type Logger interface {
|
||||
Log(...interface{})
|
||||
}
|
||||
|
||||
// NewDefaultLogger returns a Logger which will write log messages to stdout, and
|
||||
// use same formatting runes as the stdlib log.Logger
|
||||
func NewDefaultLogger() Logger {
|
||||
return &defaultLogger{
|
||||
logger: log.New(os.Stdout, "", log.LstdFlags),
|
||||
}
|
||||
}
|
||||
|
||||
// A defaultLogger provides a minimalistic logger satisfying the Logger interface.
|
||||
type defaultLogger struct {
|
||||
logger *log.Logger
|
||||
}
|
||||
|
||||
// Log logs the parameters to the stdlib logger. See log.Println.
|
||||
func (l defaultLogger) Log(args ...interface{}) {
|
||||
l.logger.Println(args...)
|
||||
}
|
||||
140
Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/request/handlers.go
generated
vendored
Normal file
140
Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/request/handlers.go
generated
vendored
Normal file
@@ -0,0 +1,140 @@
|
||||
package request
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// A Handlers provides a collection of request handlers for various
|
||||
// stages of handling requests.
|
||||
type Handlers struct {
|
||||
Validate HandlerList
|
||||
Build HandlerList
|
||||
Sign HandlerList
|
||||
Send HandlerList
|
||||
ValidateResponse HandlerList
|
||||
Unmarshal HandlerList
|
||||
UnmarshalMeta HandlerList
|
||||
UnmarshalError HandlerList
|
||||
Retry HandlerList
|
||||
AfterRetry HandlerList
|
||||
}
|
||||
|
||||
// Copy returns of this handler's lists.
|
||||
func (h *Handlers) Copy() Handlers {
|
||||
return Handlers{
|
||||
Validate: h.Validate.copy(),
|
||||
Build: h.Build.copy(),
|
||||
Sign: h.Sign.copy(),
|
||||
Send: h.Send.copy(),
|
||||
ValidateResponse: h.ValidateResponse.copy(),
|
||||
Unmarshal: h.Unmarshal.copy(),
|
||||
UnmarshalError: h.UnmarshalError.copy(),
|
||||
UnmarshalMeta: h.UnmarshalMeta.copy(),
|
||||
Retry: h.Retry.copy(),
|
||||
AfterRetry: h.AfterRetry.copy(),
|
||||
}
|
||||
}
|
||||
|
||||
// Clear removes callback functions for all handlers
|
||||
func (h *Handlers) Clear() {
|
||||
h.Validate.Clear()
|
||||
h.Build.Clear()
|
||||
h.Send.Clear()
|
||||
h.Sign.Clear()
|
||||
h.Unmarshal.Clear()
|
||||
h.UnmarshalMeta.Clear()
|
||||
h.UnmarshalError.Clear()
|
||||
h.ValidateResponse.Clear()
|
||||
h.Retry.Clear()
|
||||
h.AfterRetry.Clear()
|
||||
}
|
||||
|
||||
// A HandlerList manages zero or more handlers in a list.
|
||||
type HandlerList struct {
|
||||
list []NamedHandler
|
||||
}
|
||||
|
||||
// A NamedHandler is a struct that contains a name and function callback.
|
||||
type NamedHandler struct {
|
||||
Name string
|
||||
Fn func(*Request)
|
||||
}
|
||||
|
||||
// copy creates a copy of the handler list.
|
||||
func (l *HandlerList) copy() HandlerList {
|
||||
var n HandlerList
|
||||
n.list = append([]NamedHandler{}, l.list...)
|
||||
return n
|
||||
}
|
||||
|
||||
// Clear clears the handler list.
|
||||
func (l *HandlerList) Clear() {
|
||||
l.list = []NamedHandler{}
|
||||
}
|
||||
|
||||
// Len returns the number of handlers in the list.
|
||||
func (l *HandlerList) Len() int {
|
||||
return len(l.list)
|
||||
}
|
||||
|
||||
// PushBack pushes handler f to the back of the handler list.
|
||||
func (l *HandlerList) PushBack(f func(*Request)) {
|
||||
l.list = append(l.list, NamedHandler{"__anonymous", f})
|
||||
}
|
||||
|
||||
// PushFront pushes handler f to the front of the handler list.
|
||||
func (l *HandlerList) PushFront(f func(*Request)) {
|
||||
l.list = append([]NamedHandler{{"__anonymous", f}}, l.list...)
|
||||
}
|
||||
|
||||
// PushBackNamed pushes named handler f to the back of the handler list.
|
||||
func (l *HandlerList) PushBackNamed(n NamedHandler) {
|
||||
l.list = append(l.list, n)
|
||||
}
|
||||
|
||||
// PushFrontNamed pushes named handler f to the front of the handler list.
|
||||
func (l *HandlerList) PushFrontNamed(n NamedHandler) {
|
||||
l.list = append([]NamedHandler{n}, l.list...)
|
||||
}
|
||||
|
||||
// Remove removes a NamedHandler n
|
||||
func (l *HandlerList) Remove(n NamedHandler) {
|
||||
newlist := []NamedHandler{}
|
||||
for _, m := range l.list {
|
||||
if m.Name != n.Name {
|
||||
newlist = append(newlist, m)
|
||||
}
|
||||
}
|
||||
l.list = newlist
|
||||
}
|
||||
|
||||
// Run executes all handlers in the list with a given request object.
|
||||
func (l *HandlerList) Run(r *Request) {
|
||||
for _, f := range l.list {
|
||||
f.Fn(r)
|
||||
}
|
||||
}
|
||||
|
||||
// MakeAddToUserAgentHandler will add the name/version pair to the User-Agent request
|
||||
// header. If the extra parameters are provided they will be added as metadata to the
|
||||
// name/version pair resulting in the following format.
|
||||
// "name/version (extra0; extra1; ...)"
|
||||
// The user agent part will be concatenated with this current request's user agent string.
|
||||
func MakeAddToUserAgentHandler(name, version string, extra ...string) func(*Request) {
|
||||
ua := fmt.Sprintf("%s/%s", name, version)
|
||||
if len(extra) > 0 {
|
||||
ua += fmt.Sprintf(" (%s)", strings.Join(extra, "; "))
|
||||
}
|
||||
return func(r *Request) {
|
||||
AddToUserAgent(r, ua)
|
||||
}
|
||||
}
|
||||
|
||||
// MakeAddToUserAgentFreeFormHandler adds the input to the User-Agent request header.
|
||||
// The input string will be concatenated with the current request's user agent string.
|
||||
func MakeAddToUserAgentFreeFormHandler(s string) func(*Request) {
|
||||
return func(r *Request) {
|
||||
AddToUserAgent(r, s)
|
||||
}
|
||||
}
|
||||
47
Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/request/handlers_test.go
generated
vendored
Normal file
47
Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/request/handlers_test.go
generated
vendored
Normal file
@@ -0,0 +1,47 @@
|
||||
package request_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/aws/request"
|
||||
)
|
||||
|
||||
func TestHandlerList(t *testing.T) {
|
||||
s := ""
|
||||
r := &request.Request{}
|
||||
l := request.HandlerList{}
|
||||
l.PushBack(func(r *request.Request) {
|
||||
s += "a"
|
||||
r.Data = s
|
||||
})
|
||||
l.Run(r)
|
||||
assert.Equal(t, "a", s)
|
||||
assert.Equal(t, "a", r.Data)
|
||||
}
|
||||
|
||||
func TestMultipleHandlers(t *testing.T) {
|
||||
r := &request.Request{}
|
||||
l := request.HandlerList{}
|
||||
l.PushBack(func(r *request.Request) { r.Data = nil })
|
||||
l.PushFront(func(r *request.Request) { r.Data = aws.Bool(true) })
|
||||
l.Run(r)
|
||||
if r.Data != nil {
|
||||
t.Error("Expected handler to execute")
|
||||
}
|
||||
}
|
||||
|
||||
func TestNamedHandlers(t *testing.T) {
|
||||
l := request.HandlerList{}
|
||||
named := request.NamedHandler{Name: "Name", Fn: func(r *request.Request) {}}
|
||||
named2 := request.NamedHandler{Name: "NotName", Fn: func(r *request.Request) {}}
|
||||
l.PushBackNamed(named)
|
||||
l.PushBackNamed(named)
|
||||
l.PushBackNamed(named2)
|
||||
l.PushBack(func(r *request.Request) {})
|
||||
assert.Equal(t, 4, l.Len())
|
||||
l.Remove(named)
|
||||
assert.Equal(t, 2, l.Len())
|
||||
}
|
||||
279
Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/request/request.go
generated
vendored
Normal file
279
Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/request/request.go
generated
vendored
Normal file
@@ -0,0 +1,279 @@
|
||||
package request
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"reflect"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/aws/client/metadata"
|
||||
)
|
||||
|
||||
// A Request is the service request to be made.
|
||||
type Request struct {
|
||||
Config aws.Config
|
||||
ClientInfo metadata.ClientInfo
|
||||
Handlers Handlers
|
||||
|
||||
Retryer
|
||||
Time time.Time
|
||||
ExpireTime time.Duration
|
||||
Operation *Operation
|
||||
HTTPRequest *http.Request
|
||||
HTTPResponse *http.Response
|
||||
Body io.ReadSeeker
|
||||
BodyStart int64 // offset from beginning of Body that the request body starts
|
||||
Params interface{}
|
||||
Error error
|
||||
Data interface{}
|
||||
RequestID string
|
||||
RetryCount int
|
||||
Retryable *bool
|
||||
RetryDelay time.Duration
|
||||
|
||||
built bool
|
||||
}
|
||||
|
||||
// An Operation is the service API operation to be made.
|
||||
type Operation struct {
|
||||
Name string
|
||||
HTTPMethod string
|
||||
HTTPPath string
|
||||
*Paginator
|
||||
}
|
||||
|
||||
// Paginator keeps track of pagination configuration for an API operation.
|
||||
type Paginator struct {
|
||||
InputTokens []string
|
||||
OutputTokens []string
|
||||
LimitToken string
|
||||
TruncationToken string
|
||||
}
|
||||
|
||||
// New returns a new Request pointer for the service API
|
||||
// operation and parameters.
|
||||
//
|
||||
// Params is any value of input parameters to be the request payload.
|
||||
// Data is pointer value to an object which the request's response
|
||||
// payload will be deserialized to.
|
||||
func New(cfg aws.Config, clientInfo metadata.ClientInfo, handlers Handlers,
|
||||
retryer Retryer, operation *Operation, params interface{}, data interface{}) *Request {
|
||||
|
||||
method := operation.HTTPMethod
|
||||
if method == "" {
|
||||
method = "POST"
|
||||
}
|
||||
p := operation.HTTPPath
|
||||
if p == "" {
|
||||
p = "/"
|
||||
}
|
||||
|
||||
httpReq, _ := http.NewRequest(method, "", nil)
|
||||
httpReq.URL, _ = url.Parse(clientInfo.Endpoint + p)
|
||||
|
||||
r := &Request{
|
||||
Config: cfg,
|
||||
ClientInfo: clientInfo,
|
||||
Handlers: handlers.Copy(),
|
||||
|
||||
Retryer: retryer,
|
||||
Time: time.Now(),
|
||||
ExpireTime: 0,
|
||||
Operation: operation,
|
||||
HTTPRequest: httpReq,
|
||||
Body: nil,
|
||||
Params: params,
|
||||
Error: nil,
|
||||
Data: data,
|
||||
}
|
||||
r.SetBufferBody([]byte{})
|
||||
|
||||
return r
|
||||
}
|
||||
|
||||
// WillRetry returns if the request's can be retried.
|
||||
func (r *Request) WillRetry() bool {
|
||||
return r.Error != nil && aws.BoolValue(r.Retryable) && r.RetryCount < r.MaxRetries()
|
||||
}
|
||||
|
||||
// ParamsFilled returns if the request's parameters have been populated
|
||||
// and the parameters are valid. False is returned if no parameters are
|
||||
// provided or invalid.
|
||||
func (r *Request) ParamsFilled() bool {
|
||||
return r.Params != nil && reflect.ValueOf(r.Params).Elem().IsValid()
|
||||
}
|
||||
|
||||
// DataFilled returns true if the request's data for response deserialization
|
||||
// target has been set and is a valid. False is returned if data is not
|
||||
// set, or is invalid.
|
||||
func (r *Request) DataFilled() bool {
|
||||
return r.Data != nil && reflect.ValueOf(r.Data).Elem().IsValid()
|
||||
}
|
||||
|
||||
// SetBufferBody will set the request's body bytes that will be sent to
|
||||
// the service API.
|
||||
func (r *Request) SetBufferBody(buf []byte) {
|
||||
r.SetReaderBody(bytes.NewReader(buf))
|
||||
}
|
||||
|
||||
// SetStringBody sets the body of the request to be backed by a string.
|
||||
func (r *Request) SetStringBody(s string) {
|
||||
r.SetReaderBody(strings.NewReader(s))
|
||||
}
|
||||
|
||||
// SetReaderBody will set the request's body reader.
|
||||
func (r *Request) SetReaderBody(reader io.ReadSeeker) {
|
||||
r.HTTPRequest.Body = ioutil.NopCloser(reader)
|
||||
r.Body = reader
|
||||
}
|
||||
|
||||
// Presign returns the request's signed URL. Error will be returned
|
||||
// if the signing fails.
|
||||
func (r *Request) Presign(expireTime time.Duration) (string, error) {
|
||||
r.ExpireTime = expireTime
|
||||
r.Sign()
|
||||
if r.Error != nil {
|
||||
return "", r.Error
|
||||
}
|
||||
return r.HTTPRequest.URL.String(), nil
|
||||
}
|
||||
|
||||
func debugLogReqError(r *Request, stage string, retrying bool, err error) {
|
||||
if !r.Config.LogLevel.Matches(aws.LogDebugWithRequestErrors) {
|
||||
return
|
||||
}
|
||||
|
||||
retryStr := "not retrying"
|
||||
if retrying {
|
||||
retryStr = "will retry"
|
||||
}
|
||||
|
||||
r.Config.Logger.Log(fmt.Sprintf("DEBUG: %s %s/%s failed, %s, error %v",
|
||||
stage, r.ClientInfo.ServiceName, r.Operation.Name, retryStr, err))
|
||||
}
|
||||
|
||||
// Build will build the request's object so it can be signed and sent
|
||||
// to the service. Build will also validate all the request's parameters.
|
||||
// Anny additional build Handlers set on this request will be run
|
||||
// in the order they were set.
|
||||
//
|
||||
// The request will only be built once. Multiple calls to build will have
|
||||
// no effect.
|
||||
//
|
||||
// If any Validate or Build errors occur the build will stop and the error
|
||||
// which occurred will be returned.
|
||||
func (r *Request) Build() error {
|
||||
if !r.built {
|
||||
r.Error = nil
|
||||
r.Handlers.Validate.Run(r)
|
||||
if r.Error != nil {
|
||||
debugLogReqError(r, "Validate Request", false, r.Error)
|
||||
return r.Error
|
||||
}
|
||||
r.Handlers.Build.Run(r)
|
||||
r.built = true
|
||||
}
|
||||
|
||||
return r.Error
|
||||
}
|
||||
|
||||
// Sign will sign the request retuning error if errors are encountered.
|
||||
//
|
||||
// Send will build the request prior to signing. All Sign Handlers will
|
||||
// be executed in the order they were set.
|
||||
func (r *Request) Sign() error {
|
||||
r.Build()
|
||||
if r.Error != nil {
|
||||
debugLogReqError(r, "Build Request", false, r.Error)
|
||||
return r.Error
|
||||
}
|
||||
|
||||
r.Handlers.Sign.Run(r)
|
||||
return r.Error
|
||||
}
|
||||
|
||||
// Send will send the request returning error if errors are encountered.
|
||||
//
|
||||
// Send will sign the request prior to sending. All Send Handlers will
|
||||
// be executed in the order they were set.
|
||||
func (r *Request) Send() error {
|
||||
for {
|
||||
r.Sign()
|
||||
if r.Error != nil {
|
||||
return r.Error
|
||||
}
|
||||
|
||||
if aws.BoolValue(r.Retryable) {
|
||||
if r.Config.LogLevel.Matches(aws.LogDebugWithRequestRetries) {
|
||||
r.Config.Logger.Log(fmt.Sprintf("DEBUG: Retrying Request %s/%s, attempt %d",
|
||||
r.ClientInfo.ServiceName, r.Operation.Name, r.RetryCount))
|
||||
}
|
||||
|
||||
// Re-seek the body back to the original point in for a retry so that
|
||||
// send will send the body's contents again in the upcoming request.
|
||||
r.Body.Seek(r.BodyStart, 0)
|
||||
r.HTTPRequest.Body = ioutil.NopCloser(r.Body)
|
||||
}
|
||||
r.Retryable = nil
|
||||
|
||||
r.Handlers.Send.Run(r)
|
||||
if r.Error != nil {
|
||||
err := r.Error
|
||||
r.Handlers.Retry.Run(r)
|
||||
r.Handlers.AfterRetry.Run(r)
|
||||
if r.Error != nil {
|
||||
debugLogReqError(r, "Send Request", false, r.Error)
|
||||
return r.Error
|
||||
}
|
||||
debugLogReqError(r, "Send Request", true, err)
|
||||
continue
|
||||
}
|
||||
|
||||
r.Handlers.UnmarshalMeta.Run(r)
|
||||
r.Handlers.ValidateResponse.Run(r)
|
||||
if r.Error != nil {
|
||||
err := r.Error
|
||||
r.Handlers.UnmarshalError.Run(r)
|
||||
r.Handlers.Retry.Run(r)
|
||||
r.Handlers.AfterRetry.Run(r)
|
||||
if r.Error != nil {
|
||||
debugLogReqError(r, "Validate Response", false, r.Error)
|
||||
return r.Error
|
||||
}
|
||||
debugLogReqError(r, "Validate Response", true, err)
|
||||
continue
|
||||
}
|
||||
|
||||
r.Handlers.Unmarshal.Run(r)
|
||||
if r.Error != nil {
|
||||
err := r.Error
|
||||
r.Handlers.Retry.Run(r)
|
||||
r.Handlers.AfterRetry.Run(r)
|
||||
if r.Error != nil {
|
||||
debugLogReqError(r, "Unmarshal Response", false, r.Error)
|
||||
return r.Error
|
||||
}
|
||||
debugLogReqError(r, "Unmarshal Response", true, err)
|
||||
continue
|
||||
}
|
||||
|
||||
break
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// AddToUserAgent adds the string to the end of the request's current user agent.
|
||||
func AddToUserAgent(r *Request, s string) {
|
||||
curUA := r.HTTPRequest.Header.Get("User-Agent")
|
||||
if len(curUA) > 0 {
|
||||
s = curUA + " " + s
|
||||
}
|
||||
r.HTTPRequest.Header.Set("User-Agent", s)
|
||||
}
|
||||
104
Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/request/request_pagination.go
generated
vendored
Normal file
104
Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/request/request_pagination.go
generated
vendored
Normal file
@@ -0,0 +1,104 @@
|
||||
package request
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/aws/awsutil"
|
||||
)
|
||||
|
||||
//type Paginater interface {
|
||||
// HasNextPage() bool
|
||||
// NextPage() *Request
|
||||
// EachPage(fn func(data interface{}, isLastPage bool) (shouldContinue bool)) error
|
||||
//}
|
||||
|
||||
// HasNextPage returns true if this request has more pages of data available.
|
||||
func (r *Request) HasNextPage() bool {
|
||||
return len(r.nextPageTokens()) > 0
|
||||
}
|
||||
|
||||
// nextPageTokens returns the tokens to use when asking for the next page of
|
||||
// data.
|
||||
func (r *Request) nextPageTokens() []interface{} {
|
||||
if r.Operation.Paginator == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
if r.Operation.TruncationToken != "" {
|
||||
tr, _ := awsutil.ValuesAtPath(r.Data, r.Operation.TruncationToken)
|
||||
if len(tr) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
switch v := tr[0].(type) {
|
||||
case *bool:
|
||||
if !aws.BoolValue(v) {
|
||||
return nil
|
||||
}
|
||||
case bool:
|
||||
if v == false {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tokens := []interface{}{}
|
||||
tokenAdded := false
|
||||
for _, outToken := range r.Operation.OutputTokens {
|
||||
v, _ := awsutil.ValuesAtPath(r.Data, outToken)
|
||||
if len(v) > 0 {
|
||||
tokens = append(tokens, v[0])
|
||||
tokenAdded = true
|
||||
} else {
|
||||
tokens = append(tokens, nil)
|
||||
}
|
||||
}
|
||||
if !tokenAdded {
|
||||
return nil
|
||||
}
|
||||
|
||||
return tokens
|
||||
}
|
||||
|
||||
// NextPage returns a new Request that can be executed to return the next
|
||||
// page of result data. Call .Send() on this request to execute it.
|
||||
func (r *Request) NextPage() *Request {
|
||||
tokens := r.nextPageTokens()
|
||||
if len(tokens) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
data := reflect.New(reflect.TypeOf(r.Data).Elem()).Interface()
|
||||
nr := New(r.Config, r.ClientInfo, r.Handlers, r.Retryer, r.Operation, awsutil.CopyOf(r.Params), data)
|
||||
for i, intok := range nr.Operation.InputTokens {
|
||||
awsutil.SetValueAtPath(nr.Params, intok, tokens[i])
|
||||
}
|
||||
return nr
|
||||
}
|
||||
|
||||
// EachPage iterates over each page of a paginated request object. The fn
|
||||
// parameter should be a function with the following sample signature:
|
||||
//
|
||||
// func(page *T, lastPage bool) bool {
|
||||
// return true // return false to stop iterating
|
||||
// }
|
||||
//
|
||||
// Where "T" is the structure type matching the output structure of the given
|
||||
// operation. For example, a request object generated by
|
||||
// DynamoDB.ListTablesRequest() would expect to see dynamodb.ListTablesOutput
|
||||
// as the structure "T". The lastPage value represents whether the page is
|
||||
// the last page of data or not. The return value of this function should
|
||||
// return true to keep iterating or false to stop.
|
||||
func (r *Request) EachPage(fn func(data interface{}, isLastPage bool) (shouldContinue bool)) error {
|
||||
for page := r; page != nil; page = page.NextPage() {
|
||||
if err := page.Send(); err != nil {
|
||||
return err
|
||||
}
|
||||
if getNextPage := fn(page.Data, !page.HasNextPage()); !getNextPage {
|
||||
return page.Error
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
455
Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/request/request_pagination_test.go
generated
vendored
Normal file
455
Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/request/request_pagination_test.go
generated
vendored
Normal file
@@ -0,0 +1,455 @@
|
||||
package request_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/aws/request"
|
||||
"github.com/aws/aws-sdk-go/awstesting/unit"
|
||||
"github.com/aws/aws-sdk-go/service/dynamodb"
|
||||
"github.com/aws/aws-sdk-go/service/route53"
|
||||
"github.com/aws/aws-sdk-go/service/s3"
|
||||
)
|
||||
|
||||
// Use DynamoDB methods for simplicity
|
||||
func TestPaginationQueryPage(t *testing.T) {
|
||||
db := dynamodb.New(unit.Session)
|
||||
tokens, pages, numPages, gotToEnd := []map[string]*dynamodb.AttributeValue{}, []map[string]*dynamodb.AttributeValue{}, 0, false
|
||||
|
||||
reqNum := 0
|
||||
resps := []*dynamodb.QueryOutput{
|
||||
{
|
||||
LastEvaluatedKey: map[string]*dynamodb.AttributeValue{"key": {S: aws.String("key1")}},
|
||||
Count: aws.Int64(1),
|
||||
Items: []map[string]*dynamodb.AttributeValue{
|
||||
map[string]*dynamodb.AttributeValue{
|
||||
"key": {S: aws.String("key1")},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
LastEvaluatedKey: map[string]*dynamodb.AttributeValue{"key": {S: aws.String("key2")}},
|
||||
Count: aws.Int64(1),
|
||||
Items: []map[string]*dynamodb.AttributeValue{
|
||||
map[string]*dynamodb.AttributeValue{
|
||||
"key": {S: aws.String("key2")},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
LastEvaluatedKey: map[string]*dynamodb.AttributeValue{},
|
||||
Count: aws.Int64(1),
|
||||
Items: []map[string]*dynamodb.AttributeValue{
|
||||
map[string]*dynamodb.AttributeValue{
|
||||
"key": {S: aws.String("key3")},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
db.Handlers.Send.Clear() // mock sending
|
||||
db.Handlers.Unmarshal.Clear()
|
||||
db.Handlers.UnmarshalMeta.Clear()
|
||||
db.Handlers.ValidateResponse.Clear()
|
||||
db.Handlers.Build.PushBack(func(r *request.Request) {
|
||||
in := r.Params.(*dynamodb.QueryInput)
|
||||
if in == nil {
|
||||
tokens = append(tokens, nil)
|
||||
} else if len(in.ExclusiveStartKey) != 0 {
|
||||
tokens = append(tokens, in.ExclusiveStartKey)
|
||||
}
|
||||
})
|
||||
db.Handlers.Unmarshal.PushBack(func(r *request.Request) {
|
||||
r.Data = resps[reqNum]
|
||||
reqNum++
|
||||
})
|
||||
|
||||
params := &dynamodb.QueryInput{
|
||||
Limit: aws.Int64(2),
|
||||
TableName: aws.String("tablename"),
|
||||
}
|
||||
err := db.QueryPages(params, func(p *dynamodb.QueryOutput, last bool) bool {
|
||||
numPages++
|
||||
for _, item := range p.Items {
|
||||
pages = append(pages, item)
|
||||
}
|
||||
if last {
|
||||
if gotToEnd {
|
||||
assert.Fail(t, "last=true happened twice")
|
||||
}
|
||||
gotToEnd = true
|
||||
}
|
||||
return true
|
||||
})
|
||||
assert.Nil(t, err)
|
||||
|
||||
assert.Equal(t,
|
||||
[]map[string]*dynamodb.AttributeValue{
|
||||
map[string]*dynamodb.AttributeValue{"key": {S: aws.String("key1")}},
|
||||
map[string]*dynamodb.AttributeValue{"key": {S: aws.String("key2")}},
|
||||
}, tokens)
|
||||
assert.Equal(t,
|
||||
[]map[string]*dynamodb.AttributeValue{
|
||||
map[string]*dynamodb.AttributeValue{"key": {S: aws.String("key1")}},
|
||||
map[string]*dynamodb.AttributeValue{"key": {S: aws.String("key2")}},
|
||||
map[string]*dynamodb.AttributeValue{"key": {S: aws.String("key3")}},
|
||||
}, pages)
|
||||
assert.Equal(t, 3, numPages)
|
||||
assert.True(t, gotToEnd)
|
||||
assert.Nil(t, params.ExclusiveStartKey)
|
||||
}
|
||||
|
||||
// Use DynamoDB methods for simplicity
|
||||
func TestPagination(t *testing.T) {
|
||||
db := dynamodb.New(unit.Session)
|
||||
tokens, pages, numPages, gotToEnd := []string{}, []string{}, 0, false
|
||||
|
||||
reqNum := 0
|
||||
resps := []*dynamodb.ListTablesOutput{
|
||||
{TableNames: []*string{aws.String("Table1"), aws.String("Table2")}, LastEvaluatedTableName: aws.String("Table2")},
|
||||
{TableNames: []*string{aws.String("Table3"), aws.String("Table4")}, LastEvaluatedTableName: aws.String("Table4")},
|
||||
{TableNames: []*string{aws.String("Table5")}},
|
||||
}
|
||||
|
||||
db.Handlers.Send.Clear() // mock sending
|
||||
db.Handlers.Unmarshal.Clear()
|
||||
db.Handlers.UnmarshalMeta.Clear()
|
||||
db.Handlers.ValidateResponse.Clear()
|
||||
db.Handlers.Build.PushBack(func(r *request.Request) {
|
||||
in := r.Params.(*dynamodb.ListTablesInput)
|
||||
if in == nil {
|
||||
tokens = append(tokens, "")
|
||||
} else if in.ExclusiveStartTableName != nil {
|
||||
tokens = append(tokens, *in.ExclusiveStartTableName)
|
||||
}
|
||||
})
|
||||
db.Handlers.Unmarshal.PushBack(func(r *request.Request) {
|
||||
r.Data = resps[reqNum]
|
||||
reqNum++
|
||||
})
|
||||
|
||||
params := &dynamodb.ListTablesInput{Limit: aws.Int64(2)}
|
||||
err := db.ListTablesPages(params, func(p *dynamodb.ListTablesOutput, last bool) bool {
|
||||
numPages++
|
||||
for _, t := range p.TableNames {
|
||||
pages = append(pages, *t)
|
||||
}
|
||||
if last {
|
||||
if gotToEnd {
|
||||
assert.Fail(t, "last=true happened twice")
|
||||
}
|
||||
gotToEnd = true
|
||||
}
|
||||
return true
|
||||
})
|
||||
|
||||
assert.Equal(t, []string{"Table2", "Table4"}, tokens)
|
||||
assert.Equal(t, []string{"Table1", "Table2", "Table3", "Table4", "Table5"}, pages)
|
||||
assert.Equal(t, 3, numPages)
|
||||
assert.True(t, gotToEnd)
|
||||
assert.Nil(t, err)
|
||||
assert.Nil(t, params.ExclusiveStartTableName)
|
||||
}
|
||||
|
||||
// Use DynamoDB methods for simplicity
|
||||
func TestPaginationEachPage(t *testing.T) {
|
||||
db := dynamodb.New(unit.Session)
|
||||
tokens, pages, numPages, gotToEnd := []string{}, []string{}, 0, false
|
||||
|
||||
reqNum := 0
|
||||
resps := []*dynamodb.ListTablesOutput{
|
||||
{TableNames: []*string{aws.String("Table1"), aws.String("Table2")}, LastEvaluatedTableName: aws.String("Table2")},
|
||||
{TableNames: []*string{aws.String("Table3"), aws.String("Table4")}, LastEvaluatedTableName: aws.String("Table4")},
|
||||
{TableNames: []*string{aws.String("Table5")}},
|
||||
}
|
||||
|
||||
db.Handlers.Send.Clear() // mock sending
|
||||
db.Handlers.Unmarshal.Clear()
|
||||
db.Handlers.UnmarshalMeta.Clear()
|
||||
db.Handlers.ValidateResponse.Clear()
|
||||
db.Handlers.Build.PushBack(func(r *request.Request) {
|
||||
in := r.Params.(*dynamodb.ListTablesInput)
|
||||
if in == nil {
|
||||
tokens = append(tokens, "")
|
||||
} else if in.ExclusiveStartTableName != nil {
|
||||
tokens = append(tokens, *in.ExclusiveStartTableName)
|
||||
}
|
||||
})
|
||||
db.Handlers.Unmarshal.PushBack(func(r *request.Request) {
|
||||
r.Data = resps[reqNum]
|
||||
reqNum++
|
||||
})
|
||||
|
||||
params := &dynamodb.ListTablesInput{Limit: aws.Int64(2)}
|
||||
req, _ := db.ListTablesRequest(params)
|
||||
err := req.EachPage(func(p interface{}, last bool) bool {
|
||||
numPages++
|
||||
for _, t := range p.(*dynamodb.ListTablesOutput).TableNames {
|
||||
pages = append(pages, *t)
|
||||
}
|
||||
if last {
|
||||
if gotToEnd {
|
||||
assert.Fail(t, "last=true happened twice")
|
||||
}
|
||||
gotToEnd = true
|
||||
}
|
||||
|
||||
return true
|
||||
})
|
||||
|
||||
assert.Equal(t, []string{"Table2", "Table4"}, tokens)
|
||||
assert.Equal(t, []string{"Table1", "Table2", "Table3", "Table4", "Table5"}, pages)
|
||||
assert.Equal(t, 3, numPages)
|
||||
assert.True(t, gotToEnd)
|
||||
assert.Nil(t, err)
|
||||
}
|
||||
|
||||
// Use DynamoDB methods for simplicity
|
||||
func TestPaginationEarlyExit(t *testing.T) {
|
||||
db := dynamodb.New(unit.Session)
|
||||
numPages, gotToEnd := 0, false
|
||||
|
||||
reqNum := 0
|
||||
resps := []*dynamodb.ListTablesOutput{
|
||||
{TableNames: []*string{aws.String("Table1"), aws.String("Table2")}, LastEvaluatedTableName: aws.String("Table2")},
|
||||
{TableNames: []*string{aws.String("Table3"), aws.String("Table4")}, LastEvaluatedTableName: aws.String("Table4")},
|
||||
{TableNames: []*string{aws.String("Table5")}},
|
||||
}
|
||||
|
||||
db.Handlers.Send.Clear() // mock sending
|
||||
db.Handlers.Unmarshal.Clear()
|
||||
db.Handlers.UnmarshalMeta.Clear()
|
||||
db.Handlers.ValidateResponse.Clear()
|
||||
db.Handlers.Unmarshal.PushBack(func(r *request.Request) {
|
||||
r.Data = resps[reqNum]
|
||||
reqNum++
|
||||
})
|
||||
|
||||
params := &dynamodb.ListTablesInput{Limit: aws.Int64(2)}
|
||||
err := db.ListTablesPages(params, func(p *dynamodb.ListTablesOutput, last bool) bool {
|
||||
numPages++
|
||||
if numPages == 2 {
|
||||
return false
|
||||
}
|
||||
if last {
|
||||
if gotToEnd {
|
||||
assert.Fail(t, "last=true happened twice")
|
||||
}
|
||||
gotToEnd = true
|
||||
}
|
||||
return true
|
||||
})
|
||||
|
||||
assert.Equal(t, 2, numPages)
|
||||
assert.False(t, gotToEnd)
|
||||
assert.Nil(t, err)
|
||||
}
|
||||
|
||||
func TestSkipPagination(t *testing.T) {
|
||||
client := s3.New(unit.Session)
|
||||
client.Handlers.Send.Clear() // mock sending
|
||||
client.Handlers.Unmarshal.Clear()
|
||||
client.Handlers.UnmarshalMeta.Clear()
|
||||
client.Handlers.ValidateResponse.Clear()
|
||||
client.Handlers.Unmarshal.PushBack(func(r *request.Request) {
|
||||
r.Data = &s3.HeadBucketOutput{}
|
||||
})
|
||||
|
||||
req, _ := client.HeadBucketRequest(&s3.HeadBucketInput{Bucket: aws.String("bucket")})
|
||||
|
||||
numPages, gotToEnd := 0, false
|
||||
req.EachPage(func(p interface{}, last bool) bool {
|
||||
numPages++
|
||||
if last {
|
||||
gotToEnd = true
|
||||
}
|
||||
return true
|
||||
})
|
||||
assert.Equal(t, 1, numPages)
|
||||
assert.True(t, gotToEnd)
|
||||
}
|
||||
|
||||
// Use S3 for simplicity
|
||||
func TestPaginationTruncation(t *testing.T) {
|
||||
client := s3.New(unit.Session)
|
||||
|
||||
reqNum := 0
|
||||
resps := []*s3.ListObjectsOutput{
|
||||
{IsTruncated: aws.Bool(true), Contents: []*s3.Object{{Key: aws.String("Key1")}}},
|
||||
{IsTruncated: aws.Bool(true), Contents: []*s3.Object{{Key: aws.String("Key2")}}},
|
||||
{IsTruncated: aws.Bool(false), Contents: []*s3.Object{{Key: aws.String("Key3")}}},
|
||||
{IsTruncated: aws.Bool(true), Contents: []*s3.Object{{Key: aws.String("Key4")}}},
|
||||
}
|
||||
|
||||
client.Handlers.Send.Clear() // mock sending
|
||||
client.Handlers.Unmarshal.Clear()
|
||||
client.Handlers.UnmarshalMeta.Clear()
|
||||
client.Handlers.ValidateResponse.Clear()
|
||||
client.Handlers.Unmarshal.PushBack(func(r *request.Request) {
|
||||
r.Data = resps[reqNum]
|
||||
reqNum++
|
||||
})
|
||||
|
||||
params := &s3.ListObjectsInput{Bucket: aws.String("bucket")}
|
||||
|
||||
results := []string{}
|
||||
err := client.ListObjectsPages(params, func(p *s3.ListObjectsOutput, last bool) bool {
|
||||
results = append(results, *p.Contents[0].Key)
|
||||
return true
|
||||
})
|
||||
|
||||
assert.Equal(t, []string{"Key1", "Key2", "Key3"}, results)
|
||||
assert.Nil(t, err)
|
||||
|
||||
// Try again without truncation token at all
|
||||
reqNum = 0
|
||||
resps[1].IsTruncated = nil
|
||||
resps[2].IsTruncated = aws.Bool(true)
|
||||
results = []string{}
|
||||
err = client.ListObjectsPages(params, func(p *s3.ListObjectsOutput, last bool) bool {
|
||||
results = append(results, *p.Contents[0].Key)
|
||||
return true
|
||||
})
|
||||
|
||||
assert.Equal(t, []string{"Key1", "Key2"}, results)
|
||||
assert.Nil(t, err)
|
||||
}
|
||||
|
||||
func TestPaginationNilToken(t *testing.T) {
|
||||
client := route53.New(unit.Session)
|
||||
|
||||
reqNum := 0
|
||||
resps := []*route53.ListResourceRecordSetsOutput{
|
||||
{
|
||||
ResourceRecordSets: []*route53.ResourceRecordSet{
|
||||
{Name: aws.String("first.example.com.")},
|
||||
},
|
||||
IsTruncated: aws.Bool(true),
|
||||
NextRecordName: aws.String("second.example.com."),
|
||||
NextRecordType: aws.String("MX"),
|
||||
NextRecordIdentifier: aws.String("second"),
|
||||
MaxItems: aws.String("1"),
|
||||
},
|
||||
{
|
||||
ResourceRecordSets: []*route53.ResourceRecordSet{
|
||||
{Name: aws.String("second.example.com.")},
|
||||
},
|
||||
IsTruncated: aws.Bool(true),
|
||||
NextRecordName: aws.String("third.example.com."),
|
||||
NextRecordType: aws.String("MX"),
|
||||
MaxItems: aws.String("1"),
|
||||
},
|
||||
{
|
||||
ResourceRecordSets: []*route53.ResourceRecordSet{
|
||||
{Name: aws.String("third.example.com.")},
|
||||
},
|
||||
IsTruncated: aws.Bool(false),
|
||||
MaxItems: aws.String("1"),
|
||||
},
|
||||
}
|
||||
client.Handlers.Send.Clear() // mock sending
|
||||
client.Handlers.Unmarshal.Clear()
|
||||
client.Handlers.UnmarshalMeta.Clear()
|
||||
client.Handlers.ValidateResponse.Clear()
|
||||
|
||||
idents := []string{}
|
||||
client.Handlers.Build.PushBack(func(r *request.Request) {
|
||||
p := r.Params.(*route53.ListResourceRecordSetsInput)
|
||||
idents = append(idents, aws.StringValue(p.StartRecordIdentifier))
|
||||
|
||||
})
|
||||
client.Handlers.Unmarshal.PushBack(func(r *request.Request) {
|
||||
r.Data = resps[reqNum]
|
||||
reqNum++
|
||||
})
|
||||
|
||||
params := &route53.ListResourceRecordSetsInput{
|
||||
HostedZoneId: aws.String("id-zone"),
|
||||
}
|
||||
|
||||
results := []string{}
|
||||
err := client.ListResourceRecordSetsPages(params, func(p *route53.ListResourceRecordSetsOutput, last bool) bool {
|
||||
results = append(results, *p.ResourceRecordSets[0].Name)
|
||||
return true
|
||||
})
|
||||
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, []string{"", "second", ""}, idents)
|
||||
assert.Equal(t, []string{"first.example.com.", "second.example.com.", "third.example.com."}, results)
|
||||
}
|
||||
|
||||
// Benchmarks
|
||||
var benchResps = []*dynamodb.ListTablesOutput{
|
||||
{TableNames: []*string{aws.String("TABLE"), aws.String("NXT")}, LastEvaluatedTableName: aws.String("NXT")},
|
||||
{TableNames: []*string{aws.String("TABLE"), aws.String("NXT")}, LastEvaluatedTableName: aws.String("NXT")},
|
||||
{TableNames: []*string{aws.String("TABLE"), aws.String("NXT")}, LastEvaluatedTableName: aws.String("NXT")},
|
||||
{TableNames: []*string{aws.String("TABLE"), aws.String("NXT")}, LastEvaluatedTableName: aws.String("NXT")},
|
||||
{TableNames: []*string{aws.String("TABLE"), aws.String("NXT")}, LastEvaluatedTableName: aws.String("NXT")},
|
||||
{TableNames: []*string{aws.String("TABLE"), aws.String("NXT")}, LastEvaluatedTableName: aws.String("NXT")},
|
||||
{TableNames: []*string{aws.String("TABLE"), aws.String("NXT")}, LastEvaluatedTableName: aws.String("NXT")},
|
||||
{TableNames: []*string{aws.String("TABLE"), aws.String("NXT")}, LastEvaluatedTableName: aws.String("NXT")},
|
||||
{TableNames: []*string{aws.String("TABLE"), aws.String("NXT")}, LastEvaluatedTableName: aws.String("NXT")},
|
||||
{TableNames: []*string{aws.String("TABLE"), aws.String("NXT")}, LastEvaluatedTableName: aws.String("NXT")},
|
||||
{TableNames: []*string{aws.String("TABLE"), aws.String("NXT")}, LastEvaluatedTableName: aws.String("NXT")},
|
||||
{TableNames: []*string{aws.String("TABLE"), aws.String("NXT")}, LastEvaluatedTableName: aws.String("NXT")},
|
||||
{TableNames: []*string{aws.String("TABLE"), aws.String("NXT")}, LastEvaluatedTableName: aws.String("NXT")},
|
||||
{TableNames: []*string{aws.String("TABLE")}},
|
||||
}
|
||||
|
||||
var benchDb = func() *dynamodb.DynamoDB {
|
||||
db := dynamodb.New(unit.Session)
|
||||
db.Handlers.Send.Clear() // mock sending
|
||||
db.Handlers.Unmarshal.Clear()
|
||||
db.Handlers.UnmarshalMeta.Clear()
|
||||
db.Handlers.ValidateResponse.Clear()
|
||||
return db
|
||||
}
|
||||
|
||||
func BenchmarkCodegenIterator(b *testing.B) {
|
||||
reqNum := 0
|
||||
db := benchDb()
|
||||
db.Handlers.Unmarshal.PushBack(func(r *request.Request) {
|
||||
r.Data = benchResps[reqNum]
|
||||
reqNum++
|
||||
})
|
||||
|
||||
input := &dynamodb.ListTablesInput{Limit: aws.Int64(2)}
|
||||
iter := func(fn func(*dynamodb.ListTablesOutput, bool) bool) error {
|
||||
page, _ := db.ListTablesRequest(input)
|
||||
for ; page != nil; page = page.NextPage() {
|
||||
page.Send()
|
||||
out := page.Data.(*dynamodb.ListTablesOutput)
|
||||
if result := fn(out, !page.HasNextPage()); page.Error != nil || !result {
|
||||
return page.Error
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
reqNum = 0
|
||||
iter(func(p *dynamodb.ListTablesOutput, last bool) bool {
|
||||
return true
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkEachPageIterator(b *testing.B) {
|
||||
reqNum := 0
|
||||
db := benchDb()
|
||||
db.Handlers.Unmarshal.PushBack(func(r *request.Request) {
|
||||
r.Data = benchResps[reqNum]
|
||||
reqNum++
|
||||
})
|
||||
|
||||
input := &dynamodb.ListTablesInput{Limit: aws.Int64(2)}
|
||||
for i := 0; i < b.N; i++ {
|
||||
reqNum = 0
|
||||
req, _ := db.ListTablesRequest(input)
|
||||
req.EachPage(func(p interface{}, last bool) bool {
|
||||
return true
|
||||
})
|
||||
}
|
||||
}
|
||||
261
Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/request/request_test.go
generated
vendored
Normal file
261
Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/request/request_test.go
generated
vendored
Normal file
@@ -0,0 +1,261 @@
|
||||
package request_test
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"runtime"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/aws/awserr"
|
||||
"github.com/aws/aws-sdk-go/aws/credentials"
|
||||
"github.com/aws/aws-sdk-go/aws/request"
|
||||
"github.com/aws/aws-sdk-go/awstesting"
|
||||
)
|
||||
|
||||
type testData struct {
|
||||
Data string
|
||||
}
|
||||
|
||||
func body(str string) io.ReadCloser {
|
||||
return ioutil.NopCloser(bytes.NewReader([]byte(str)))
|
||||
}
|
||||
|
||||
func unmarshal(req *request.Request) {
|
||||
defer req.HTTPResponse.Body.Close()
|
||||
if req.Data != nil {
|
||||
json.NewDecoder(req.HTTPResponse.Body).Decode(req.Data)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func unmarshalError(req *request.Request) {
|
||||
bodyBytes, err := ioutil.ReadAll(req.HTTPResponse.Body)
|
||||
if err != nil {
|
||||
req.Error = awserr.New("UnmarshaleError", req.HTTPResponse.Status, err)
|
||||
return
|
||||
}
|
||||
if len(bodyBytes) == 0 {
|
||||
req.Error = awserr.NewRequestFailure(
|
||||
awserr.New("UnmarshaleError", req.HTTPResponse.Status, fmt.Errorf("empty body")),
|
||||
req.HTTPResponse.StatusCode,
|
||||
"",
|
||||
)
|
||||
return
|
||||
}
|
||||
var jsonErr jsonErrorResponse
|
||||
if err := json.Unmarshal(bodyBytes, &jsonErr); err != nil {
|
||||
req.Error = awserr.New("UnmarshaleError", "JSON unmarshal", err)
|
||||
return
|
||||
}
|
||||
req.Error = awserr.NewRequestFailure(
|
||||
awserr.New(jsonErr.Code, jsonErr.Message, nil),
|
||||
req.HTTPResponse.StatusCode,
|
||||
"",
|
||||
)
|
||||
}
|
||||
|
||||
type jsonErrorResponse struct {
|
||||
Code string `json:"__type"`
|
||||
Message string `json:"message"`
|
||||
}
|
||||
|
||||
// test that retries occur for 5xx status codes
|
||||
func TestRequestRecoverRetry5xx(t *testing.T) {
|
||||
reqNum := 0
|
||||
reqs := []http.Response{
|
||||
{StatusCode: 500, Body: body(`{"__type":"UnknownError","message":"An error occurred."}`)},
|
||||
{StatusCode: 501, Body: body(`{"__type":"UnknownError","message":"An error occurred."}`)},
|
||||
{StatusCode: 200, Body: body(`{"data":"valid"}`)},
|
||||
}
|
||||
|
||||
s := awstesting.NewClient(aws.NewConfig().WithMaxRetries(10))
|
||||
s.Handlers.Validate.Clear()
|
||||
s.Handlers.Unmarshal.PushBack(unmarshal)
|
||||
s.Handlers.UnmarshalError.PushBack(unmarshalError)
|
||||
s.Handlers.Send.Clear() // mock sending
|
||||
s.Handlers.Send.PushBack(func(r *request.Request) {
|
||||
r.HTTPResponse = &reqs[reqNum]
|
||||
reqNum++
|
||||
})
|
||||
out := &testData{}
|
||||
r := s.NewRequest(&request.Operation{Name: "Operation"}, nil, out)
|
||||
err := r.Send()
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, 2, int(r.RetryCount))
|
||||
assert.Equal(t, "valid", out.Data)
|
||||
}
|
||||
|
||||
// test that retries occur for 4xx status codes with a response type that can be retried - see `shouldRetry`
|
||||
func TestRequestRecoverRetry4xxRetryable(t *testing.T) {
|
||||
reqNum := 0
|
||||
reqs := []http.Response{
|
||||
{StatusCode: 400, Body: body(`{"__type":"Throttling","message":"Rate exceeded."}`)},
|
||||
{StatusCode: 429, Body: body(`{"__type":"ProvisionedThroughputExceededException","message":"Rate exceeded."}`)},
|
||||
{StatusCode: 200, Body: body(`{"data":"valid"}`)},
|
||||
}
|
||||
|
||||
s := awstesting.NewClient(aws.NewConfig().WithMaxRetries(10))
|
||||
s.Handlers.Validate.Clear()
|
||||
s.Handlers.Unmarshal.PushBack(unmarshal)
|
||||
s.Handlers.UnmarshalError.PushBack(unmarshalError)
|
||||
s.Handlers.Send.Clear() // mock sending
|
||||
s.Handlers.Send.PushBack(func(r *request.Request) {
|
||||
r.HTTPResponse = &reqs[reqNum]
|
||||
reqNum++
|
||||
})
|
||||
out := &testData{}
|
||||
r := s.NewRequest(&request.Operation{Name: "Operation"}, nil, out)
|
||||
err := r.Send()
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, 2, int(r.RetryCount))
|
||||
assert.Equal(t, "valid", out.Data)
|
||||
}
|
||||
|
||||
// test that retries don't occur for 4xx status codes with a response type that can't be retried
|
||||
func TestRequest4xxUnretryable(t *testing.T) {
|
||||
s := awstesting.NewClient(aws.NewConfig().WithMaxRetries(10))
|
||||
s.Handlers.Validate.Clear()
|
||||
s.Handlers.Unmarshal.PushBack(unmarshal)
|
||||
s.Handlers.UnmarshalError.PushBack(unmarshalError)
|
||||
s.Handlers.Send.Clear() // mock sending
|
||||
s.Handlers.Send.PushBack(func(r *request.Request) {
|
||||
r.HTTPResponse = &http.Response{StatusCode: 401, Body: body(`{"__type":"SignatureDoesNotMatch","message":"Signature does not match."}`)}
|
||||
})
|
||||
out := &testData{}
|
||||
r := s.NewRequest(&request.Operation{Name: "Operation"}, nil, out)
|
||||
err := r.Send()
|
||||
assert.NotNil(t, err)
|
||||
if e, ok := err.(awserr.RequestFailure); ok {
|
||||
assert.Equal(t, 401, e.StatusCode())
|
||||
} else {
|
||||
assert.Fail(t, "Expected error to be a service failure")
|
||||
}
|
||||
assert.Equal(t, "SignatureDoesNotMatch", err.(awserr.Error).Code())
|
||||
assert.Equal(t, "Signature does not match.", err.(awserr.Error).Message())
|
||||
assert.Equal(t, 0, int(r.RetryCount))
|
||||
}
|
||||
|
||||
func TestRequestExhaustRetries(t *testing.T) {
|
||||
delays := []time.Duration{}
|
||||
sleepDelay := func(delay time.Duration) {
|
||||
delays = append(delays, delay)
|
||||
}
|
||||
|
||||
reqNum := 0
|
||||
reqs := []http.Response{
|
||||
{StatusCode: 500, Body: body(`{"__type":"UnknownError","message":"An error occurred."}`)},
|
||||
{StatusCode: 500, Body: body(`{"__type":"UnknownError","message":"An error occurred."}`)},
|
||||
{StatusCode: 500, Body: body(`{"__type":"UnknownError","message":"An error occurred."}`)},
|
||||
{StatusCode: 500, Body: body(`{"__type":"UnknownError","message":"An error occurred."}`)},
|
||||
}
|
||||
|
||||
s := awstesting.NewClient(aws.NewConfig().WithSleepDelay(sleepDelay))
|
||||
s.Handlers.Validate.Clear()
|
||||
s.Handlers.Unmarshal.PushBack(unmarshal)
|
||||
s.Handlers.UnmarshalError.PushBack(unmarshalError)
|
||||
s.Handlers.Send.Clear() // mock sending
|
||||
s.Handlers.Send.PushBack(func(r *request.Request) {
|
||||
r.HTTPResponse = &reqs[reqNum]
|
||||
reqNum++
|
||||
})
|
||||
r := s.NewRequest(&request.Operation{Name: "Operation"}, nil, nil)
|
||||
err := r.Send()
|
||||
assert.NotNil(t, err)
|
||||
if e, ok := err.(awserr.RequestFailure); ok {
|
||||
assert.Equal(t, 500, e.StatusCode())
|
||||
} else {
|
||||
assert.Fail(t, "Expected error to be a service failure")
|
||||
}
|
||||
assert.Equal(t, "UnknownError", err.(awserr.Error).Code())
|
||||
assert.Equal(t, "An error occurred.", err.(awserr.Error).Message())
|
||||
assert.Equal(t, 3, int(r.RetryCount))
|
||||
|
||||
expectDelays := []struct{ min, max time.Duration }{{30, 59}, {60, 118}, {120, 236}}
|
||||
for i, v := range delays {
|
||||
min := expectDelays[i].min * time.Millisecond
|
||||
max := expectDelays[i].max * time.Millisecond
|
||||
assert.True(t, min <= v && v <= max,
|
||||
"Expect delay to be within range, i:%d, v:%s, min:%s, max:%s", i, v, min, max)
|
||||
}
|
||||
}
|
||||
|
||||
// test that the request is retried after the credentials are expired.
|
||||
func TestRequestRecoverExpiredCreds(t *testing.T) {
|
||||
reqNum := 0
|
||||
reqs := []http.Response{
|
||||
{StatusCode: 400, Body: body(`{"__type":"ExpiredTokenException","message":"expired token"}`)},
|
||||
{StatusCode: 200, Body: body(`{"data":"valid"}`)},
|
||||
}
|
||||
|
||||
s := awstesting.NewClient(&aws.Config{MaxRetries: aws.Int(10), Credentials: credentials.NewStaticCredentials("AKID", "SECRET", "")})
|
||||
s.Handlers.Validate.Clear()
|
||||
s.Handlers.Unmarshal.PushBack(unmarshal)
|
||||
s.Handlers.UnmarshalError.PushBack(unmarshalError)
|
||||
|
||||
credExpiredBeforeRetry := false
|
||||
credExpiredAfterRetry := false
|
||||
|
||||
s.Handlers.AfterRetry.PushBack(func(r *request.Request) {
|
||||
credExpiredAfterRetry = r.Config.Credentials.IsExpired()
|
||||
})
|
||||
|
||||
s.Handlers.Sign.Clear()
|
||||
s.Handlers.Sign.PushBack(func(r *request.Request) {
|
||||
r.Config.Credentials.Get()
|
||||
})
|
||||
s.Handlers.Send.Clear() // mock sending
|
||||
s.Handlers.Send.PushBack(func(r *request.Request) {
|
||||
r.HTTPResponse = &reqs[reqNum]
|
||||
reqNum++
|
||||
})
|
||||
out := &testData{}
|
||||
r := s.NewRequest(&request.Operation{Name: "Operation"}, nil, out)
|
||||
err := r.Send()
|
||||
assert.Nil(t, err)
|
||||
|
||||
assert.False(t, credExpiredBeforeRetry, "Expect valid creds before retry check")
|
||||
assert.True(t, credExpiredAfterRetry, "Expect expired creds after retry check")
|
||||
assert.False(t, s.Config.Credentials.IsExpired(), "Expect valid creds after cred expired recovery")
|
||||
|
||||
assert.Equal(t, 1, int(r.RetryCount))
|
||||
assert.Equal(t, "valid", out.Data)
|
||||
}
|
||||
|
||||
func TestMakeAddtoUserAgentHandler(t *testing.T) {
|
||||
fn := request.MakeAddToUserAgentHandler("name", "version", "extra1", "extra2")
|
||||
r := &request.Request{HTTPRequest: &http.Request{Header: http.Header{}}}
|
||||
r.HTTPRequest.Header.Set("User-Agent", "foo/bar")
|
||||
fn(r)
|
||||
|
||||
assert.Equal(t, "foo/bar name/version (extra1; extra2)", r.HTTPRequest.Header.Get("User-Agent"))
|
||||
}
|
||||
|
||||
func TestMakeAddtoUserAgentFreeFormHandler(t *testing.T) {
|
||||
fn := request.MakeAddToUserAgentFreeFormHandler("name/version (extra1; extra2)")
|
||||
r := &request.Request{HTTPRequest: &http.Request{Header: http.Header{}}}
|
||||
r.HTTPRequest.Header.Set("User-Agent", "foo/bar")
|
||||
fn(r)
|
||||
|
||||
assert.Equal(t, "foo/bar name/version (extra1; extra2)", r.HTTPRequest.Header.Get("User-Agent"))
|
||||
}
|
||||
|
||||
func TestRequestUserAgent(t *testing.T) {
|
||||
s := awstesting.NewClient(&aws.Config{Region: aws.String("us-east-1")})
|
||||
// s.Handlers.Validate.Clear()
|
||||
|
||||
req := s.NewRequest(&request.Operation{Name: "Operation"}, nil, &testData{})
|
||||
req.HTTPRequest.Header.Set("User-Agent", "foo/bar")
|
||||
assert.NoError(t, req.Build())
|
||||
|
||||
expectUA := fmt.Sprintf("foo/bar %s/%s (%s; %s; %s)",
|
||||
aws.SDKName, aws.SDKVersion, runtime.Version(), runtime.GOOS, runtime.GOARCH)
|
||||
assert.Equal(t, expectUA, req.HTTPRequest.Header.Get("User-Agent"))
|
||||
}
|
||||
82
Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/request/retryer.go
generated
vendored
Normal file
82
Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/request/retryer.go
generated
vendored
Normal file
@@ -0,0 +1,82 @@
|
||||
package request
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/aws/awserr"
|
||||
)
|
||||
|
||||
// Retryer is an interface to control retry logic for a given service.
|
||||
// The default implementation used by most services is the service.DefaultRetryer
|
||||
// structure, which contains basic retry logic using exponential backoff.
|
||||
type Retryer interface {
|
||||
RetryRules(*Request) time.Duration
|
||||
ShouldRetry(*Request) bool
|
||||
MaxRetries() int
|
||||
}
|
||||
|
||||
// WithRetryer sets a config Retryer value to the given Config returning it
|
||||
// for chaining.
|
||||
func WithRetryer(cfg *aws.Config, retryer Retryer) *aws.Config {
|
||||
cfg.Retryer = retryer
|
||||
return cfg
|
||||
}
|
||||
|
||||
// retryableCodes is a collection of service response codes which are retry-able
|
||||
// without any further action.
|
||||
var retryableCodes = map[string]struct{}{
|
||||
"RequestError": {},
|
||||
"RequestTimeout": {},
|
||||
"ProvisionedThroughputExceededException": {},
|
||||
"Throttling": {},
|
||||
"ThrottlingException": {},
|
||||
"RequestLimitExceeded": {},
|
||||
"RequestThrottled": {},
|
||||
"LimitExceededException": {}, // Deleting 10+ DynamoDb tables at once
|
||||
"TooManyRequestsException": {}, // Lambda functions
|
||||
}
|
||||
|
||||
// credsExpiredCodes is a collection of error codes which signify the credentials
|
||||
// need to be refreshed. Expired tokens require refreshing of credentials, and
|
||||
// resigning before the request can be retried.
|
||||
var credsExpiredCodes = map[string]struct{}{
|
||||
"ExpiredToken": {},
|
||||
"ExpiredTokenException": {},
|
||||
"RequestExpired": {}, // EC2 Only
|
||||
}
|
||||
|
||||
func isCodeRetryable(code string) bool {
|
||||
if _, ok := retryableCodes[code]; ok {
|
||||
return true
|
||||
}
|
||||
|
||||
return isCodeExpiredCreds(code)
|
||||
}
|
||||
|
||||
func isCodeExpiredCreds(code string) bool {
|
||||
_, ok := credsExpiredCodes[code]
|
||||
return ok
|
||||
}
|
||||
|
||||
// IsErrorRetryable returns whether the error is retryable, based on its Code.
|
||||
// Returns false if the request has no Error set.
|
||||
func (r *Request) IsErrorRetryable() bool {
|
||||
if r.Error != nil {
|
||||
if err, ok := r.Error.(awserr.Error); ok {
|
||||
return isCodeRetryable(err.Code())
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// IsErrorExpired returns whether the error code is a credential expiry error.
|
||||
// Returns false if the request has no Error set.
|
||||
func (r *Request) IsErrorExpired() bool {
|
||||
if r.Error != nil {
|
||||
if err, ok := r.Error.(awserr.Error); ok {
|
||||
return isCodeExpiredCreds(err.Code())
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
105
Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/session/session.go
generated
vendored
Normal file
105
Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/session/session.go
generated
vendored
Normal file
@@ -0,0 +1,105 @@
|
||||
// Package session provides a way to create service clients with shared configuration
|
||||
// and handlers.
|
||||
package session
|
||||
|
||||
import (
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/aws/client"
|
||||
"github.com/aws/aws-sdk-go/aws/corehandlers"
|
||||
"github.com/aws/aws-sdk-go/aws/defaults"
|
||||
"github.com/aws/aws-sdk-go/aws/request"
|
||||
"github.com/aws/aws-sdk-go/private/endpoints"
|
||||
)
|
||||
|
||||
// A Session provides a central location to create service clients from and
|
||||
// store configurations and request handlers for those services.
|
||||
//
|
||||
// Sessions are safe to create service clients concurrently, but it is not safe
|
||||
// to mutate the session concurrently.
|
||||
type Session struct {
|
||||
Config *aws.Config
|
||||
Handlers request.Handlers
|
||||
}
|
||||
|
||||
// New creates a new instance of the handlers merging in the provided Configs
|
||||
// on top of the SDK's default configurations. Once the session is created it
|
||||
// can be mutated to modify Configs or Handlers. The session is safe to be read
|
||||
// concurrently, but it should not be written to concurrently.
|
||||
//
|
||||
// Example:
|
||||
// // Create a session with the default config and request handlers.
|
||||
// sess := session.New()
|
||||
//
|
||||
// // Create a session with a custom region
|
||||
// sess := session.New(&aws.Config{Region: aws.String("us-east-1")})
|
||||
//
|
||||
// // Create a session, and add additional handlers for all service
|
||||
// // clients created with the session to inherit. Adds logging handler.
|
||||
// sess := session.New()
|
||||
// sess.Handlers.Send.PushFront(func(r *request.Request) {
|
||||
// // Log every request made and its payload
|
||||
// logger.Println("Request: %s/%s, Payload: %s", r.ClientInfo.ServiceName, r.Operation, r.Params)
|
||||
// })
|
||||
//
|
||||
// // Create a S3 client instance from a session
|
||||
// sess := session.New()
|
||||
// svc := s3.New(sess)
|
||||
func New(cfgs ...*aws.Config) *Session {
|
||||
def := defaults.Get()
|
||||
s := &Session{
|
||||
Config: def.Config,
|
||||
Handlers: def.Handlers,
|
||||
}
|
||||
s.Config.MergeIn(cfgs...)
|
||||
|
||||
initHandlers(s)
|
||||
|
||||
return s
|
||||
}
|
||||
|
||||
func initHandlers(s *Session) {
|
||||
// Add the Validate parameter handler if it is not disabled.
|
||||
s.Handlers.Validate.Remove(corehandlers.ValidateParametersHandler)
|
||||
if !aws.BoolValue(s.Config.DisableParamValidation) {
|
||||
s.Handlers.Validate.PushBackNamed(corehandlers.ValidateParametersHandler)
|
||||
}
|
||||
}
|
||||
|
||||
// Copy creates and returns a copy of the current session, coping the config
|
||||
// and handlers. If any additional configs are provided they will be merged
|
||||
// on top of the session's copied config.
|
||||
//
|
||||
// Example:
|
||||
// // Create a copy of the current session, configured for the us-west-2 region.
|
||||
// sess.Copy(&aws.Config{Region: aws.String("us-west-2"})
|
||||
func (s *Session) Copy(cfgs ...*aws.Config) *Session {
|
||||
newSession := &Session{
|
||||
Config: s.Config.Copy(cfgs...),
|
||||
Handlers: s.Handlers.Copy(),
|
||||
}
|
||||
|
||||
initHandlers(newSession)
|
||||
|
||||
return newSession
|
||||
}
|
||||
|
||||
// ClientConfig satisfies the client.ConfigProvider interface and is used to
|
||||
// configure the service client instances. Passing the Session to the service
|
||||
// client's constructor (New) will use this method to configure the client.
|
||||
//
|
||||
// Example:
|
||||
// sess := session.New()
|
||||
// s3.New(sess)
|
||||
func (s *Session) ClientConfig(serviceName string, cfgs ...*aws.Config) client.Config {
|
||||
s = s.Copy(cfgs...)
|
||||
endpoint, signingRegion := endpoints.NormalizeEndpoint(
|
||||
aws.StringValue(s.Config.Endpoint), serviceName,
|
||||
aws.StringValue(s.Config.Region), aws.BoolValue(s.Config.DisableSSL))
|
||||
|
||||
return client.Config{
|
||||
Config: s.Config,
|
||||
Handlers: s.Handlers,
|
||||
Endpoint: endpoint,
|
||||
SigningRegion: signingRegion,
|
||||
}
|
||||
}
|
||||
20
Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/session/session_test.go
generated
vendored
Normal file
20
Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/session/session_test.go
generated
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
package session_test
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/aws/session"
|
||||
)
|
||||
|
||||
func TestNewDefaultSession(t *testing.T) {
|
||||
s := session.New(&aws.Config{Region: aws.String("region")})
|
||||
|
||||
assert.Equal(t, "region", *s.Config.Region)
|
||||
assert.Equal(t, http.DefaultClient, s.Config.HTTPClient)
|
||||
assert.NotNil(t, s.Config.Logger)
|
||||
assert.Equal(t, aws.LogOff, *s.Config.LogLevel)
|
||||
}
|
||||
88
Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/types.go
generated
vendored
Normal file
88
Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/types.go
generated
vendored
Normal file
@@ -0,0 +1,88 @@
|
||||
package aws
|
||||
|
||||
import (
|
||||
"io"
|
||||
"sync"
|
||||
)
|
||||
|
||||
// ReadSeekCloser wraps a io.Reader returning a ReaderSeekerCloser
|
||||
func ReadSeekCloser(r io.Reader) ReaderSeekerCloser {
|
||||
return ReaderSeekerCloser{r}
|
||||
}
|
||||
|
||||
// ReaderSeekerCloser represents a reader that can also delegate io.Seeker and
|
||||
// io.Closer interfaces to the underlying object if they are available.
|
||||
type ReaderSeekerCloser struct {
|
||||
r io.Reader
|
||||
}
|
||||
|
||||
// Read reads from the reader up to size of p. The number of bytes read, and
|
||||
// error if it occurred will be returned.
|
||||
//
|
||||
// If the reader is not an io.Reader zero bytes read, and nil error will be returned.
|
||||
//
|
||||
// Performs the same functionality as io.Reader Read
|
||||
func (r ReaderSeekerCloser) Read(p []byte) (int, error) {
|
||||
switch t := r.r.(type) {
|
||||
case io.Reader:
|
||||
return t.Read(p)
|
||||
}
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
// Seek sets the offset for the next Read to offset, interpreted according to
|
||||
// whence: 0 means relative to the origin of the file, 1 means relative to the
|
||||
// current offset, and 2 means relative to the end. Seek returns the new offset
|
||||
// and an error, if any.
|
||||
//
|
||||
// If the ReaderSeekerCloser is not an io.Seeker nothing will be done.
|
||||
func (r ReaderSeekerCloser) Seek(offset int64, whence int) (int64, error) {
|
||||
switch t := r.r.(type) {
|
||||
case io.Seeker:
|
||||
return t.Seek(offset, whence)
|
||||
}
|
||||
return int64(0), nil
|
||||
}
|
||||
|
||||
// Close closes the ReaderSeekerCloser.
|
||||
//
|
||||
// If the ReaderSeekerCloser is not an io.Closer nothing will be done.
|
||||
func (r ReaderSeekerCloser) Close() error {
|
||||
switch t := r.r.(type) {
|
||||
case io.Closer:
|
||||
return t.Close()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// A WriteAtBuffer provides a in memory buffer supporting the io.WriterAt interface
|
||||
// Can be used with the s3manager.Downloader to download content to a buffer
|
||||
// in memory. Safe to use concurrently.
|
||||
type WriteAtBuffer struct {
|
||||
buf []byte
|
||||
m sync.Mutex
|
||||
}
|
||||
|
||||
// WriteAt writes a slice of bytes to a buffer starting at the position provided
|
||||
// The number of bytes written will be returned, or error. Can overwrite previous
|
||||
// written slices if the write ats overlap.
|
||||
func (b *WriteAtBuffer) WriteAt(p []byte, pos int64) (n int, err error) {
|
||||
b.m.Lock()
|
||||
defer b.m.Unlock()
|
||||
|
||||
expLen := pos + int64(len(p))
|
||||
if int64(len(b.buf)) < expLen {
|
||||
newBuf := make([]byte, expLen)
|
||||
copy(newBuf, b.buf)
|
||||
b.buf = newBuf
|
||||
}
|
||||
copy(b.buf[pos:], p)
|
||||
return len(p), nil
|
||||
}
|
||||
|
||||
// Bytes returns a slice of bytes written to the buffer.
|
||||
func (b *WriteAtBuffer) Bytes() []byte {
|
||||
b.m.Lock()
|
||||
defer b.m.Unlock()
|
||||
return b.buf[:len(b.buf):len(b.buf)]
|
||||
}
|
||||
56
Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/types_test.go
generated
vendored
Normal file
56
Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/types_test.go
generated
vendored
Normal file
@@ -0,0 +1,56 @@
|
||||
package aws
|
||||
|
||||
import (
|
||||
"math/rand"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestWriteAtBuffer(t *testing.T) {
|
||||
b := &WriteAtBuffer{}
|
||||
|
||||
n, err := b.WriteAt([]byte{1}, 0)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, 1, n)
|
||||
|
||||
n, err = b.WriteAt([]byte{1, 1, 1}, 5)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, 3, n)
|
||||
|
||||
n, err = b.WriteAt([]byte{2}, 1)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, 1, n)
|
||||
|
||||
n, err = b.WriteAt([]byte{3}, 2)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, 1, n)
|
||||
|
||||
assert.Equal(t, []byte{1, 2, 3, 0, 0, 1, 1, 1}, b.Bytes())
|
||||
}
|
||||
|
||||
func BenchmarkWriteAtBuffer(b *testing.B) {
|
||||
buf := &WriteAtBuffer{}
|
||||
r := rand.New(rand.NewSource(1))
|
||||
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
to := r.Intn(10) * 4096
|
||||
bs := make([]byte, to)
|
||||
buf.WriteAt(bs, r.Int63n(10)*4096)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkWriteAtBufferParallel(b *testing.B) {
|
||||
buf := &WriteAtBuffer{}
|
||||
r := rand.New(rand.NewSource(1))
|
||||
|
||||
b.ResetTimer()
|
||||
b.RunParallel(func(pb *testing.PB) {
|
||||
for pb.Next() {
|
||||
to := r.Intn(10) * 4096
|
||||
bs := make([]byte, to)
|
||||
buf.WriteAt(bs, r.Int63n(10)*4096)
|
||||
}
|
||||
})
|
||||
}
|
||||
8
Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/version.go
generated
vendored
Normal file
8
Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/version.go
generated
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
// Package aws provides core functionality for making requests to AWS services.
|
||||
package aws
|
||||
|
||||
// SDKName is the name of this AWS SDK
|
||||
const SDKName = "aws-sdk-go"
|
||||
|
||||
// SDKVersion is the version of this SDK
|
||||
const SDKVersion = "1.0.0"
|
||||
31
Godeps/_workspace/src/github.com/aws/aws-sdk-go/internal/endpoints/endpoints.go
generated
vendored
Normal file
31
Godeps/_workspace/src/github.com/aws/aws-sdk-go/internal/endpoints/endpoints.go
generated
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
// Package endpoints validates regional endpoints for services.
|
||||
package endpoints
|
||||
|
||||
//go:generate go run ../model/cli/gen-endpoints/main.go endpoints.json endpoints_map.go
|
||||
//go:generate gofmt -s -w endpoints_map.go
|
||||
|
||||
import "strings"
|
||||
|
||||
// EndpointForRegion returns an endpoint and its signing region for a service and region.
|
||||
// if the service and region pair are not found endpoint and signingRegion will be empty.
|
||||
func EndpointForRegion(svcName, region string) (endpoint, signingRegion string) {
|
||||
derivedKeys := []string{
|
||||
region + "/" + svcName,
|
||||
region + "/*",
|
||||
"*/" + svcName,
|
||||
"*/*",
|
||||
}
|
||||
|
||||
for _, key := range derivedKeys {
|
||||
if val, ok := endpointsMap.Endpoints[key]; ok {
|
||||
ep := val.Endpoint
|
||||
ep = strings.Replace(ep, "{region}", region, -1)
|
||||
ep = strings.Replace(ep, "{service}", svcName, -1)
|
||||
|
||||
endpoint = ep
|
||||
signingRegion = val.SigningRegion
|
||||
return
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
77
Godeps/_workspace/src/github.com/aws/aws-sdk-go/internal/endpoints/endpoints.json
generated
vendored
Normal file
77
Godeps/_workspace/src/github.com/aws/aws-sdk-go/internal/endpoints/endpoints.json
generated
vendored
Normal file
@@ -0,0 +1,77 @@
|
||||
{
|
||||
"version": 2,
|
||||
"endpoints": {
|
||||
"*/*": {
|
||||
"endpoint": "{service}.{region}.amazonaws.com"
|
||||
},
|
||||
"cn-north-1/*": {
|
||||
"endpoint": "{service}.{region}.amazonaws.com.cn",
|
||||
"signatureVersion": "v4"
|
||||
},
|
||||
"us-gov-west-1/iam": {
|
||||
"endpoint": "iam.us-gov.amazonaws.com"
|
||||
},
|
||||
"us-gov-west-1/sts": {
|
||||
"endpoint": "sts.us-gov-west-1.amazonaws.com"
|
||||
},
|
||||
"us-gov-west-1/s3": {
|
||||
"endpoint": "s3-{region}.amazonaws.com"
|
||||
},
|
||||
"*/cloudfront": {
|
||||
"endpoint": "cloudfront.amazonaws.com",
|
||||
"signingRegion": "us-east-1"
|
||||
},
|
||||
"*/cloudsearchdomain": {
|
||||
"endpoint": "",
|
||||
"signingRegion": "us-east-1"
|
||||
},
|
||||
"*/iam": {
|
||||
"endpoint": "iam.amazonaws.com",
|
||||
"signingRegion": "us-east-1"
|
||||
},
|
||||
"*/importexport": {
|
||||
"endpoint": "importexport.amazonaws.com",
|
||||
"signingRegion": "us-east-1"
|
||||
},
|
||||
"*/route53": {
|
||||
"endpoint": "route53.amazonaws.com",
|
||||
"signingRegion": "us-east-1"
|
||||
},
|
||||
"*/sts": {
|
||||
"endpoint": "sts.amazonaws.com",
|
||||
"signingRegion": "us-east-1"
|
||||
},
|
||||
"us-east-1/sdb": {
|
||||
"endpoint": "sdb.amazonaws.com",
|
||||
"signingRegion": "us-east-1"
|
||||
},
|
||||
"us-east-1/s3": {
|
||||
"endpoint": "s3.amazonaws.com"
|
||||
},
|
||||
"us-west-1/s3": {
|
||||
"endpoint": "s3-{region}.amazonaws.com"
|
||||
},
|
||||
"us-west-2/s3": {
|
||||
"endpoint": "s3-{region}.amazonaws.com"
|
||||
},
|
||||
"eu-west-1/s3": {
|
||||
"endpoint": "s3-{region}.amazonaws.com"
|
||||
},
|
||||
"ap-southeast-1/s3": {
|
||||
"endpoint": "s3-{region}.amazonaws.com"
|
||||
},
|
||||
"ap-southeast-2/s3": {
|
||||
"endpoint": "s3-{region}.amazonaws.com"
|
||||
},
|
||||
"ap-northeast-1/s3": {
|
||||
"endpoint": "s3-{region}.amazonaws.com"
|
||||
},
|
||||
"sa-east-1/s3": {
|
||||
"endpoint": "s3-{region}.amazonaws.com"
|
||||
},
|
||||
"eu-central-1/s3": {
|
||||
"endpoint": "{service}.{region}.amazonaws.com",
|
||||
"signatureVersion": "v4"
|
||||
}
|
||||
}
|
||||
}
|
||||
89
Godeps/_workspace/src/github.com/aws/aws-sdk-go/internal/endpoints/endpoints_map.go
generated
vendored
Normal file
89
Godeps/_workspace/src/github.com/aws/aws-sdk-go/internal/endpoints/endpoints_map.go
generated
vendored
Normal file
@@ -0,0 +1,89 @@
|
||||
package endpoints
|
||||
|
||||
// THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT.
|
||||
|
||||
type endpointStruct struct {
|
||||
Version int
|
||||
Endpoints map[string]endpointEntry
|
||||
}
|
||||
|
||||
type endpointEntry struct {
|
||||
Endpoint string
|
||||
SigningRegion string
|
||||
}
|
||||
|
||||
var endpointsMap = endpointStruct{
|
||||
Version: 2,
|
||||
Endpoints: map[string]endpointEntry{
|
||||
"*/*": {
|
||||
Endpoint: "{service}.{region}.amazonaws.com",
|
||||
},
|
||||
"*/cloudfront": {
|
||||
Endpoint: "cloudfront.amazonaws.com",
|
||||
SigningRegion: "us-east-1",
|
||||
},
|
||||
"*/cloudsearchdomain": {
|
||||
Endpoint: "",
|
||||
SigningRegion: "us-east-1",
|
||||
},
|
||||
"*/iam": {
|
||||
Endpoint: "iam.amazonaws.com",
|
||||
SigningRegion: "us-east-1",
|
||||
},
|
||||
"*/importexport": {
|
||||
Endpoint: "importexport.amazonaws.com",
|
||||
SigningRegion: "us-east-1",
|
||||
},
|
||||
"*/route53": {
|
||||
Endpoint: "route53.amazonaws.com",
|
||||
SigningRegion: "us-east-1",
|
||||
},
|
||||
"*/sts": {
|
||||
Endpoint: "sts.amazonaws.com",
|
||||
SigningRegion: "us-east-1",
|
||||
},
|
||||
"ap-northeast-1/s3": {
|
||||
Endpoint: "s3-{region}.amazonaws.com",
|
||||
},
|
||||
"ap-southeast-1/s3": {
|
||||
Endpoint: "s3-{region}.amazonaws.com",
|
||||
},
|
||||
"ap-southeast-2/s3": {
|
||||
Endpoint: "s3-{region}.amazonaws.com",
|
||||
},
|
||||
"cn-north-1/*": {
|
||||
Endpoint: "{service}.{region}.amazonaws.com.cn",
|
||||
},
|
||||
"eu-central-1/s3": {
|
||||
Endpoint: "{service}.{region}.amazonaws.com",
|
||||
},
|
||||
"eu-west-1/s3": {
|
||||
Endpoint: "s3-{region}.amazonaws.com",
|
||||
},
|
||||
"sa-east-1/s3": {
|
||||
Endpoint: "s3-{region}.amazonaws.com",
|
||||
},
|
||||
"us-east-1/s3": {
|
||||
Endpoint: "s3.amazonaws.com",
|
||||
},
|
||||
"us-east-1/sdb": {
|
||||
Endpoint: "sdb.amazonaws.com",
|
||||
SigningRegion: "us-east-1",
|
||||
},
|
||||
"us-gov-west-1/iam": {
|
||||
Endpoint: "iam.us-gov.amazonaws.com",
|
||||
},
|
||||
"us-gov-west-1/s3": {
|
||||
Endpoint: "s3-{region}.amazonaws.com",
|
||||
},
|
||||
"us-gov-west-1/sts": {
|
||||
Endpoint: "sts.us-gov-west-1.amazonaws.com",
|
||||
},
|
||||
"us-west-1/s3": {
|
||||
Endpoint: "s3-{region}.amazonaws.com",
|
||||
},
|
||||
"us-west-2/s3": {
|
||||
Endpoint: "s3-{region}.amazonaws.com",
|
||||
},
|
||||
},
|
||||
}
|
||||
28
Godeps/_workspace/src/github.com/aws/aws-sdk-go/internal/endpoints/endpoints_test.go
generated
vendored
Normal file
28
Godeps/_workspace/src/github.com/aws/aws-sdk-go/internal/endpoints/endpoints_test.go
generated
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
package endpoints
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestGlobalEndpoints(t *testing.T) {
|
||||
region := "mock-region-1"
|
||||
svcs := []string{"cloudfront", "iam", "importexport", "route53", "sts"}
|
||||
|
||||
for _, name := range svcs {
|
||||
ep, sr := EndpointForRegion(name, region)
|
||||
assert.Equal(t, name+".amazonaws.com", ep)
|
||||
assert.Equal(t, "us-east-1", sr)
|
||||
}
|
||||
}
|
||||
|
||||
func TestServicesInCN(t *testing.T) {
|
||||
region := "cn-north-1"
|
||||
svcs := []string{"cloudfront", "iam", "importexport", "route53", "sts", "s3"}
|
||||
|
||||
for _, name := range svcs {
|
||||
ep, _ := EndpointForRegion(name, region)
|
||||
assert.Equal(t, name+"."+region+".amazonaws.com.cn", ep)
|
||||
}
|
||||
}
|
||||
32
Godeps/_workspace/src/github.com/aws/aws-sdk-go/internal/protocol/ec2query/build.go
generated
vendored
Normal file
32
Godeps/_workspace/src/github.com/aws/aws-sdk-go/internal/protocol/ec2query/build.go
generated
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
// Package ec2query provides serialisation of AWS EC2 requests and responses.
|
||||
package ec2query
|
||||
|
||||
//go:generate go run ../../fixtures/protocol/generate.go ../../fixtures/protocol/input/ec2.json build_test.go
|
||||
|
||||
import (
|
||||
"net/url"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/aws/awserr"
|
||||
"github.com/aws/aws-sdk-go/internal/protocol/query/queryutil"
|
||||
)
|
||||
|
||||
// Build builds a request for the EC2 protocol.
|
||||
func Build(r *aws.Request) {
|
||||
body := url.Values{
|
||||
"Action": {r.Operation.Name},
|
||||
"Version": {r.Service.APIVersion},
|
||||
}
|
||||
if err := queryutil.Parse(body, r.Params, true); err != nil {
|
||||
r.Error = awserr.New("SerializationError", "failed encoding EC2 Query request", err)
|
||||
}
|
||||
|
||||
if r.ExpireTime == 0 {
|
||||
r.HTTPRequest.Method = "POST"
|
||||
r.HTTPRequest.Header.Set("Content-Type", "application/x-www-form-urlencoded; charset=utf-8")
|
||||
r.SetBufferBody([]byte(body.Encode()))
|
||||
} else { // This is a pre-signed request
|
||||
r.HTTPRequest.Method = "GET"
|
||||
r.HTTPRequest.URL.RawQuery = body.Encode()
|
||||
}
|
||||
}
|
||||
860
Godeps/_workspace/src/github.com/aws/aws-sdk-go/internal/protocol/ec2query/build_test.go
generated
vendored
Normal file
860
Godeps/_workspace/src/github.com/aws/aws-sdk-go/internal/protocol/ec2query/build_test.go
generated
vendored
Normal file
@@ -0,0 +1,860 @@
|
||||
package ec2query_test
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"encoding/xml"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/internal/protocol/ec2query"
|
||||
"github.com/aws/aws-sdk-go/internal/protocol/xml/xmlutil"
|
||||
"github.com/aws/aws-sdk-go/internal/signer/v4"
|
||||
"github.com/aws/aws-sdk-go/internal/util"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
var _ bytes.Buffer // always import bytes
|
||||
var _ http.Request
|
||||
var _ json.Marshaler
|
||||
var _ time.Time
|
||||
var _ xmlutil.XMLNode
|
||||
var _ xml.Attr
|
||||
var _ = ioutil.Discard
|
||||
var _ = util.Trim("")
|
||||
var _ = url.Values{}
|
||||
var _ = io.EOF
|
||||
|
||||
type InputService1ProtocolTest struct {
|
||||
*aws.Service
|
||||
}
|
||||
|
||||
// New returns a new InputService1ProtocolTest client.
|
||||
func NewInputService1ProtocolTest(config *aws.Config) *InputService1ProtocolTest {
|
||||
service := &aws.Service{
|
||||
Config: aws.DefaultConfig.Merge(config),
|
||||
ServiceName: "inputservice1protocoltest",
|
||||
APIVersion: "2014-01-01",
|
||||
}
|
||||
service.Initialize()
|
||||
|
||||
// Handlers
|
||||
service.Handlers.Sign.PushBack(v4.Sign)
|
||||
service.Handlers.Build.PushBack(ec2query.Build)
|
||||
service.Handlers.Unmarshal.PushBack(ec2query.Unmarshal)
|
||||
service.Handlers.UnmarshalMeta.PushBack(ec2query.UnmarshalMeta)
|
||||
service.Handlers.UnmarshalError.PushBack(ec2query.UnmarshalError)
|
||||
|
||||
return &InputService1ProtocolTest{service}
|
||||
}
|
||||
|
||||
// newRequest creates a new request for a InputService1ProtocolTest operation and runs any
|
||||
// custom request initialization.
|
||||
func (c *InputService1ProtocolTest) newRequest(op *aws.Operation, params, data interface{}) *aws.Request {
|
||||
req := aws.NewRequest(c.Service, op, params, data)
|
||||
|
||||
return req
|
||||
}
|
||||
|
||||
const opInputService1TestCaseOperation1 = "OperationName"
|
||||
|
||||
// InputService1TestCaseOperation1Request generates a request for the InputService1TestCaseOperation1 operation.
|
||||
func (c *InputService1ProtocolTest) InputService1TestCaseOperation1Request(input *InputService1TestShapeInputShape) (req *aws.Request, output *InputService1TestShapeInputService1TestCaseOperation1Output) {
|
||||
op := &aws.Operation{
|
||||
Name: opInputService1TestCaseOperation1,
|
||||
}
|
||||
|
||||
if input == nil {
|
||||
input = &InputService1TestShapeInputShape{}
|
||||
}
|
||||
|
||||
req = c.newRequest(op, input, output)
|
||||
output = &InputService1TestShapeInputService1TestCaseOperation1Output{}
|
||||
req.Data = output
|
||||
return
|
||||
}
|
||||
|
||||
func (c *InputService1ProtocolTest) InputService1TestCaseOperation1(input *InputService1TestShapeInputShape) (*InputService1TestShapeInputService1TestCaseOperation1Output, error) {
|
||||
req, out := c.InputService1TestCaseOperation1Request(input)
|
||||
err := req.Send()
|
||||
return out, err
|
||||
}
|
||||
|
||||
type InputService1TestShapeInputService1TestCaseOperation1Output struct {
|
||||
metadataInputService1TestShapeInputService1TestCaseOperation1Output `json:"-" xml:"-"`
|
||||
}
|
||||
|
||||
type metadataInputService1TestShapeInputService1TestCaseOperation1Output struct {
|
||||
SDKShapeTraits bool `type:"structure"`
|
||||
}
|
||||
|
||||
type InputService1TestShapeInputShape struct {
|
||||
Bar *string `type:"string"`
|
||||
|
||||
Foo *string `type:"string"`
|
||||
|
||||
metadataInputService1TestShapeInputShape `json:"-" xml:"-"`
|
||||
}
|
||||
|
||||
type metadataInputService1TestShapeInputShape struct {
|
||||
SDKShapeTraits bool `type:"structure"`
|
||||
}
|
||||
|
||||
type InputService2ProtocolTest struct {
|
||||
*aws.Service
|
||||
}
|
||||
|
||||
// New returns a new InputService2ProtocolTest client.
|
||||
func NewInputService2ProtocolTest(config *aws.Config) *InputService2ProtocolTest {
|
||||
service := &aws.Service{
|
||||
Config: aws.DefaultConfig.Merge(config),
|
||||
ServiceName: "inputservice2protocoltest",
|
||||
APIVersion: "2014-01-01",
|
||||
}
|
||||
service.Initialize()
|
||||
|
||||
// Handlers
|
||||
service.Handlers.Sign.PushBack(v4.Sign)
|
||||
service.Handlers.Build.PushBack(ec2query.Build)
|
||||
service.Handlers.Unmarshal.PushBack(ec2query.Unmarshal)
|
||||
service.Handlers.UnmarshalMeta.PushBack(ec2query.UnmarshalMeta)
|
||||
service.Handlers.UnmarshalError.PushBack(ec2query.UnmarshalError)
|
||||
|
||||
return &InputService2ProtocolTest{service}
|
||||
}
|
||||
|
||||
// newRequest creates a new request for a InputService2ProtocolTest operation and runs any
|
||||
// custom request initialization.
|
||||
func (c *InputService2ProtocolTest) newRequest(op *aws.Operation, params, data interface{}) *aws.Request {
|
||||
req := aws.NewRequest(c.Service, op, params, data)
|
||||
|
||||
return req
|
||||
}
|
||||
|
||||
const opInputService2TestCaseOperation1 = "OperationName"
|
||||
|
||||
// InputService2TestCaseOperation1Request generates a request for the InputService2TestCaseOperation1 operation.
|
||||
func (c *InputService2ProtocolTest) InputService2TestCaseOperation1Request(input *InputService2TestShapeInputShape) (req *aws.Request, output *InputService2TestShapeInputService2TestCaseOperation1Output) {
|
||||
op := &aws.Operation{
|
||||
Name: opInputService2TestCaseOperation1,
|
||||
}
|
||||
|
||||
if input == nil {
|
||||
input = &InputService2TestShapeInputShape{}
|
||||
}
|
||||
|
||||
req = c.newRequest(op, input, output)
|
||||
output = &InputService2TestShapeInputService2TestCaseOperation1Output{}
|
||||
req.Data = output
|
||||
return
|
||||
}
|
||||
|
||||
func (c *InputService2ProtocolTest) InputService2TestCaseOperation1(input *InputService2TestShapeInputShape) (*InputService2TestShapeInputService2TestCaseOperation1Output, error) {
|
||||
req, out := c.InputService2TestCaseOperation1Request(input)
|
||||
err := req.Send()
|
||||
return out, err
|
||||
}
|
||||
|
||||
type InputService2TestShapeInputService2TestCaseOperation1Output struct {
|
||||
metadataInputService2TestShapeInputService2TestCaseOperation1Output `json:"-" xml:"-"`
|
||||
}
|
||||
|
||||
type metadataInputService2TestShapeInputService2TestCaseOperation1Output struct {
|
||||
SDKShapeTraits bool `type:"structure"`
|
||||
}
|
||||
|
||||
type InputService2TestShapeInputShape struct {
|
||||
Bar *string `locationName:"barLocationName" type:"string"`
|
||||
|
||||
Foo *string `type:"string"`
|
||||
|
||||
Yuck *string `locationName:"yuckLocationName" queryName:"yuckQueryName" type:"string"`
|
||||
|
||||
metadataInputService2TestShapeInputShape `json:"-" xml:"-"`
|
||||
}
|
||||
|
||||
type metadataInputService2TestShapeInputShape struct {
|
||||
SDKShapeTraits bool `type:"structure"`
|
||||
}
|
||||
|
||||
type InputService3ProtocolTest struct {
|
||||
*aws.Service
|
||||
}
|
||||
|
||||
// New returns a new InputService3ProtocolTest client.
|
||||
func NewInputService3ProtocolTest(config *aws.Config) *InputService3ProtocolTest {
|
||||
service := &aws.Service{
|
||||
Config: aws.DefaultConfig.Merge(config),
|
||||
ServiceName: "inputservice3protocoltest",
|
||||
APIVersion: "2014-01-01",
|
||||
}
|
||||
service.Initialize()
|
||||
|
||||
// Handlers
|
||||
service.Handlers.Sign.PushBack(v4.Sign)
|
||||
service.Handlers.Build.PushBack(ec2query.Build)
|
||||
service.Handlers.Unmarshal.PushBack(ec2query.Unmarshal)
|
||||
service.Handlers.UnmarshalMeta.PushBack(ec2query.UnmarshalMeta)
|
||||
service.Handlers.UnmarshalError.PushBack(ec2query.UnmarshalError)
|
||||
|
||||
return &InputService3ProtocolTest{service}
|
||||
}
|
||||
|
||||
// newRequest creates a new request for a InputService3ProtocolTest operation and runs any
|
||||
// custom request initialization.
|
||||
func (c *InputService3ProtocolTest) newRequest(op *aws.Operation, params, data interface{}) *aws.Request {
|
||||
req := aws.NewRequest(c.Service, op, params, data)
|
||||
|
||||
return req
|
||||
}
|
||||
|
||||
const opInputService3TestCaseOperation1 = "OperationName"
|
||||
|
||||
// InputService3TestCaseOperation1Request generates a request for the InputService3TestCaseOperation1 operation.
|
||||
func (c *InputService3ProtocolTest) InputService3TestCaseOperation1Request(input *InputService3TestShapeInputShape) (req *aws.Request, output *InputService3TestShapeInputService3TestCaseOperation1Output) {
|
||||
op := &aws.Operation{
|
||||
Name: opInputService3TestCaseOperation1,
|
||||
}
|
||||
|
||||
if input == nil {
|
||||
input = &InputService3TestShapeInputShape{}
|
||||
}
|
||||
|
||||
req = c.newRequest(op, input, output)
|
||||
output = &InputService3TestShapeInputService3TestCaseOperation1Output{}
|
||||
req.Data = output
|
||||
return
|
||||
}
|
||||
|
||||
func (c *InputService3ProtocolTest) InputService3TestCaseOperation1(input *InputService3TestShapeInputShape) (*InputService3TestShapeInputService3TestCaseOperation1Output, error) {
|
||||
req, out := c.InputService3TestCaseOperation1Request(input)
|
||||
err := req.Send()
|
||||
return out, err
|
||||
}
|
||||
|
||||
type InputService3TestShapeInputService3TestCaseOperation1Output struct {
|
||||
metadataInputService3TestShapeInputService3TestCaseOperation1Output `json:"-" xml:"-"`
|
||||
}
|
||||
|
||||
type metadataInputService3TestShapeInputService3TestCaseOperation1Output struct {
|
||||
SDKShapeTraits bool `type:"structure"`
|
||||
}
|
||||
|
||||
type InputService3TestShapeInputShape struct {
|
||||
StructArg *InputService3TestShapeStructType `locationName:"Struct" type:"structure"`
|
||||
|
||||
metadataInputService3TestShapeInputShape `json:"-" xml:"-"`
|
||||
}
|
||||
|
||||
type metadataInputService3TestShapeInputShape struct {
|
||||
SDKShapeTraits bool `type:"structure"`
|
||||
}
|
||||
|
||||
type InputService3TestShapeStructType struct {
|
||||
ScalarArg *string `locationName:"Scalar" type:"string"`
|
||||
|
||||
metadataInputService3TestShapeStructType `json:"-" xml:"-"`
|
||||
}
|
||||
|
||||
type metadataInputService3TestShapeStructType struct {
|
||||
SDKShapeTraits bool `type:"structure"`
|
||||
}
|
||||
|
||||
type InputService4ProtocolTest struct {
|
||||
*aws.Service
|
||||
}
|
||||
|
||||
// New returns a new InputService4ProtocolTest client.
|
||||
func NewInputService4ProtocolTest(config *aws.Config) *InputService4ProtocolTest {
|
||||
service := &aws.Service{
|
||||
Config: aws.DefaultConfig.Merge(config),
|
||||
ServiceName: "inputservice4protocoltest",
|
||||
APIVersion: "2014-01-01",
|
||||
}
|
||||
service.Initialize()
|
||||
|
||||
// Handlers
|
||||
service.Handlers.Sign.PushBack(v4.Sign)
|
||||
service.Handlers.Build.PushBack(ec2query.Build)
|
||||
service.Handlers.Unmarshal.PushBack(ec2query.Unmarshal)
|
||||
service.Handlers.UnmarshalMeta.PushBack(ec2query.UnmarshalMeta)
|
||||
service.Handlers.UnmarshalError.PushBack(ec2query.UnmarshalError)
|
||||
|
||||
return &InputService4ProtocolTest{service}
|
||||
}
|
||||
|
||||
// newRequest creates a new request for a InputService4ProtocolTest operation and runs any
|
||||
// custom request initialization.
|
||||
func (c *InputService4ProtocolTest) newRequest(op *aws.Operation, params, data interface{}) *aws.Request {
|
||||
req := aws.NewRequest(c.Service, op, params, data)
|
||||
|
||||
return req
|
||||
}
|
||||
|
||||
const opInputService4TestCaseOperation1 = "OperationName"
|
||||
|
||||
// InputService4TestCaseOperation1Request generates a request for the InputService4TestCaseOperation1 operation.
|
||||
func (c *InputService4ProtocolTest) InputService4TestCaseOperation1Request(input *InputService4TestShapeInputShape) (req *aws.Request, output *InputService4TestShapeInputService4TestCaseOperation1Output) {
|
||||
op := &aws.Operation{
|
||||
Name: opInputService4TestCaseOperation1,
|
||||
}
|
||||
|
||||
if input == nil {
|
||||
input = &InputService4TestShapeInputShape{}
|
||||
}
|
||||
|
||||
req = c.newRequest(op, input, output)
|
||||
output = &InputService4TestShapeInputService4TestCaseOperation1Output{}
|
||||
req.Data = output
|
||||
return
|
||||
}
|
||||
|
||||
func (c *InputService4ProtocolTest) InputService4TestCaseOperation1(input *InputService4TestShapeInputShape) (*InputService4TestShapeInputService4TestCaseOperation1Output, error) {
|
||||
req, out := c.InputService4TestCaseOperation1Request(input)
|
||||
err := req.Send()
|
||||
return out, err
|
||||
}
|
||||
|
||||
type InputService4TestShapeInputService4TestCaseOperation1Output struct {
|
||||
metadataInputService4TestShapeInputService4TestCaseOperation1Output `json:"-" xml:"-"`
|
||||
}
|
||||
|
||||
type metadataInputService4TestShapeInputService4TestCaseOperation1Output struct {
|
||||
SDKShapeTraits bool `type:"structure"`
|
||||
}
|
||||
|
||||
type InputService4TestShapeInputShape struct {
|
||||
ListArg []*string `type:"list"`
|
||||
|
||||
metadataInputService4TestShapeInputShape `json:"-" xml:"-"`
|
||||
}
|
||||
|
||||
type metadataInputService4TestShapeInputShape struct {
|
||||
SDKShapeTraits bool `type:"structure"`
|
||||
}
|
||||
|
||||
type InputService5ProtocolTest struct {
|
||||
*aws.Service
|
||||
}
|
||||
|
||||
// New returns a new InputService5ProtocolTest client.
|
||||
func NewInputService5ProtocolTest(config *aws.Config) *InputService5ProtocolTest {
|
||||
service := &aws.Service{
|
||||
Config: aws.DefaultConfig.Merge(config),
|
||||
ServiceName: "inputservice5protocoltest",
|
||||
APIVersion: "2014-01-01",
|
||||
}
|
||||
service.Initialize()
|
||||
|
||||
// Handlers
|
||||
service.Handlers.Sign.PushBack(v4.Sign)
|
||||
service.Handlers.Build.PushBack(ec2query.Build)
|
||||
service.Handlers.Unmarshal.PushBack(ec2query.Unmarshal)
|
||||
service.Handlers.UnmarshalMeta.PushBack(ec2query.UnmarshalMeta)
|
||||
service.Handlers.UnmarshalError.PushBack(ec2query.UnmarshalError)
|
||||
|
||||
return &InputService5ProtocolTest{service}
|
||||
}
|
||||
|
||||
// newRequest creates a new request for a InputService5ProtocolTest operation and runs any
|
||||
// custom request initialization.
|
||||
func (c *InputService5ProtocolTest) newRequest(op *aws.Operation, params, data interface{}) *aws.Request {
|
||||
req := aws.NewRequest(c.Service, op, params, data)
|
||||
|
||||
return req
|
||||
}
|
||||
|
||||
const opInputService5TestCaseOperation1 = "OperationName"
|
||||
|
||||
// InputService5TestCaseOperation1Request generates a request for the InputService5TestCaseOperation1 operation.
|
||||
func (c *InputService5ProtocolTest) InputService5TestCaseOperation1Request(input *InputService5TestShapeInputShape) (req *aws.Request, output *InputService5TestShapeInputService5TestCaseOperation1Output) {
|
||||
op := &aws.Operation{
|
||||
Name: opInputService5TestCaseOperation1,
|
||||
}
|
||||
|
||||
if input == nil {
|
||||
input = &InputService5TestShapeInputShape{}
|
||||
}
|
||||
|
||||
req = c.newRequest(op, input, output)
|
||||
output = &InputService5TestShapeInputService5TestCaseOperation1Output{}
|
||||
req.Data = output
|
||||
return
|
||||
}
|
||||
|
||||
func (c *InputService5ProtocolTest) InputService5TestCaseOperation1(input *InputService5TestShapeInputShape) (*InputService5TestShapeInputService5TestCaseOperation1Output, error) {
|
||||
req, out := c.InputService5TestCaseOperation1Request(input)
|
||||
err := req.Send()
|
||||
return out, err
|
||||
}
|
||||
|
||||
type InputService5TestShapeInputService5TestCaseOperation1Output struct {
|
||||
metadataInputService5TestShapeInputService5TestCaseOperation1Output `json:"-" xml:"-"`
|
||||
}
|
||||
|
||||
type metadataInputService5TestShapeInputService5TestCaseOperation1Output struct {
|
||||
SDKShapeTraits bool `type:"structure"`
|
||||
}
|
||||
|
||||
type InputService5TestShapeInputShape struct {
|
||||
ListArg []*string `locationName:"ListMemberName" locationNameList:"item" type:"list"`
|
||||
|
||||
metadataInputService5TestShapeInputShape `json:"-" xml:"-"`
|
||||
}
|
||||
|
||||
type metadataInputService5TestShapeInputShape struct {
|
||||
SDKShapeTraits bool `type:"structure"`
|
||||
}
|
||||
|
||||
type InputService6ProtocolTest struct {
|
||||
*aws.Service
|
||||
}
|
||||
|
||||
// New returns a new InputService6ProtocolTest client.
|
||||
func NewInputService6ProtocolTest(config *aws.Config) *InputService6ProtocolTest {
|
||||
service := &aws.Service{
|
||||
Config: aws.DefaultConfig.Merge(config),
|
||||
ServiceName: "inputservice6protocoltest",
|
||||
APIVersion: "2014-01-01",
|
||||
}
|
||||
service.Initialize()
|
||||
|
||||
// Handlers
|
||||
service.Handlers.Sign.PushBack(v4.Sign)
|
||||
service.Handlers.Build.PushBack(ec2query.Build)
|
||||
service.Handlers.Unmarshal.PushBack(ec2query.Unmarshal)
|
||||
service.Handlers.UnmarshalMeta.PushBack(ec2query.UnmarshalMeta)
|
||||
service.Handlers.UnmarshalError.PushBack(ec2query.UnmarshalError)
|
||||
|
||||
return &InputService6ProtocolTest{service}
|
||||
}
|
||||
|
||||
// newRequest creates a new request for a InputService6ProtocolTest operation and runs any
|
||||
// custom request initialization.
|
||||
func (c *InputService6ProtocolTest) newRequest(op *aws.Operation, params, data interface{}) *aws.Request {
|
||||
req := aws.NewRequest(c.Service, op, params, data)
|
||||
|
||||
return req
|
||||
}
|
||||
|
||||
const opInputService6TestCaseOperation1 = "OperationName"
|
||||
|
||||
// InputService6TestCaseOperation1Request generates a request for the InputService6TestCaseOperation1 operation.
|
||||
func (c *InputService6ProtocolTest) InputService6TestCaseOperation1Request(input *InputService6TestShapeInputShape) (req *aws.Request, output *InputService6TestShapeInputService6TestCaseOperation1Output) {
|
||||
op := &aws.Operation{
|
||||
Name: opInputService6TestCaseOperation1,
|
||||
}
|
||||
|
||||
if input == nil {
|
||||
input = &InputService6TestShapeInputShape{}
|
||||
}
|
||||
|
||||
req = c.newRequest(op, input, output)
|
||||
output = &InputService6TestShapeInputService6TestCaseOperation1Output{}
|
||||
req.Data = output
|
||||
return
|
||||
}
|
||||
|
||||
func (c *InputService6ProtocolTest) InputService6TestCaseOperation1(input *InputService6TestShapeInputShape) (*InputService6TestShapeInputService6TestCaseOperation1Output, error) {
|
||||
req, out := c.InputService6TestCaseOperation1Request(input)
|
||||
err := req.Send()
|
||||
return out, err
|
||||
}
|
||||
|
||||
type InputService6TestShapeInputService6TestCaseOperation1Output struct {
|
||||
metadataInputService6TestShapeInputService6TestCaseOperation1Output `json:"-" xml:"-"`
|
||||
}
|
||||
|
||||
type metadataInputService6TestShapeInputService6TestCaseOperation1Output struct {
|
||||
SDKShapeTraits bool `type:"structure"`
|
||||
}
|
||||
|
||||
type InputService6TestShapeInputShape struct {
|
||||
ListArg []*string `locationName:"ListMemberName" queryName:"ListQueryName" locationNameList:"item" type:"list"`
|
||||
|
||||
metadataInputService6TestShapeInputShape `json:"-" xml:"-"`
|
||||
}
|
||||
|
||||
type metadataInputService6TestShapeInputShape struct {
|
||||
SDKShapeTraits bool `type:"structure"`
|
||||
}
|
||||
|
||||
type InputService7ProtocolTest struct {
|
||||
*aws.Service
|
||||
}
|
||||
|
||||
// New returns a new InputService7ProtocolTest client.
|
||||
func NewInputService7ProtocolTest(config *aws.Config) *InputService7ProtocolTest {
|
||||
service := &aws.Service{
|
||||
Config: aws.DefaultConfig.Merge(config),
|
||||
ServiceName: "inputservice7protocoltest",
|
||||
APIVersion: "2014-01-01",
|
||||
}
|
||||
service.Initialize()
|
||||
|
||||
// Handlers
|
||||
service.Handlers.Sign.PushBack(v4.Sign)
|
||||
service.Handlers.Build.PushBack(ec2query.Build)
|
||||
service.Handlers.Unmarshal.PushBack(ec2query.Unmarshal)
|
||||
service.Handlers.UnmarshalMeta.PushBack(ec2query.UnmarshalMeta)
|
||||
service.Handlers.UnmarshalError.PushBack(ec2query.UnmarshalError)
|
||||
|
||||
return &InputService7ProtocolTest{service}
|
||||
}
|
||||
|
||||
// newRequest creates a new request for a InputService7ProtocolTest operation and runs any
|
||||
// custom request initialization.
|
||||
func (c *InputService7ProtocolTest) newRequest(op *aws.Operation, params, data interface{}) *aws.Request {
|
||||
req := aws.NewRequest(c.Service, op, params, data)
|
||||
|
||||
return req
|
||||
}
|
||||
|
||||
const opInputService7TestCaseOperation1 = "OperationName"
|
||||
|
||||
// InputService7TestCaseOperation1Request generates a request for the InputService7TestCaseOperation1 operation.
|
||||
func (c *InputService7ProtocolTest) InputService7TestCaseOperation1Request(input *InputService7TestShapeInputShape) (req *aws.Request, output *InputService7TestShapeInputService7TestCaseOperation1Output) {
|
||||
op := &aws.Operation{
|
||||
Name: opInputService7TestCaseOperation1,
|
||||
}
|
||||
|
||||
if input == nil {
|
||||
input = &InputService7TestShapeInputShape{}
|
||||
}
|
||||
|
||||
req = c.newRequest(op, input, output)
|
||||
output = &InputService7TestShapeInputService7TestCaseOperation1Output{}
|
||||
req.Data = output
|
||||
return
|
||||
}
|
||||
|
||||
func (c *InputService7ProtocolTest) InputService7TestCaseOperation1(input *InputService7TestShapeInputShape) (*InputService7TestShapeInputService7TestCaseOperation1Output, error) {
|
||||
req, out := c.InputService7TestCaseOperation1Request(input)
|
||||
err := req.Send()
|
||||
return out, err
|
||||
}
|
||||
|
||||
type InputService7TestShapeInputService7TestCaseOperation1Output struct {
|
||||
metadataInputService7TestShapeInputService7TestCaseOperation1Output `json:"-" xml:"-"`
|
||||
}
|
||||
|
||||
type metadataInputService7TestShapeInputService7TestCaseOperation1Output struct {
|
||||
SDKShapeTraits bool `type:"structure"`
|
||||
}
|
||||
|
||||
type InputService7TestShapeInputShape struct {
|
||||
BlobArg []byte `type:"blob"`
|
||||
|
||||
metadataInputService7TestShapeInputShape `json:"-" xml:"-"`
|
||||
}
|
||||
|
||||
type metadataInputService7TestShapeInputShape struct {
|
||||
SDKShapeTraits bool `type:"structure"`
|
||||
}
|
||||
|
||||
type InputService8ProtocolTest struct {
|
||||
*aws.Service
|
||||
}
|
||||
|
||||
// New returns a new InputService8ProtocolTest client.
|
||||
func NewInputService8ProtocolTest(config *aws.Config) *InputService8ProtocolTest {
|
||||
service := &aws.Service{
|
||||
Config: aws.DefaultConfig.Merge(config),
|
||||
ServiceName: "inputservice8protocoltest",
|
||||
APIVersion: "2014-01-01",
|
||||
}
|
||||
service.Initialize()
|
||||
|
||||
// Handlers
|
||||
service.Handlers.Sign.PushBack(v4.Sign)
|
||||
service.Handlers.Build.PushBack(ec2query.Build)
|
||||
service.Handlers.Unmarshal.PushBack(ec2query.Unmarshal)
|
||||
service.Handlers.UnmarshalMeta.PushBack(ec2query.UnmarshalMeta)
|
||||
service.Handlers.UnmarshalError.PushBack(ec2query.UnmarshalError)
|
||||
|
||||
return &InputService8ProtocolTest{service}
|
||||
}
|
||||
|
||||
// newRequest creates a new request for a InputService8ProtocolTest operation and runs any
|
||||
// custom request initialization.
|
||||
func (c *InputService8ProtocolTest) newRequest(op *aws.Operation, params, data interface{}) *aws.Request {
|
||||
req := aws.NewRequest(c.Service, op, params, data)
|
||||
|
||||
return req
|
||||
}
|
||||
|
||||
const opInputService8TestCaseOperation1 = "OperationName"
|
||||
|
||||
// InputService8TestCaseOperation1Request generates a request for the InputService8TestCaseOperation1 operation.
|
||||
func (c *InputService8ProtocolTest) InputService8TestCaseOperation1Request(input *InputService8TestShapeInputShape) (req *aws.Request, output *InputService8TestShapeInputService8TestCaseOperation1Output) {
|
||||
op := &aws.Operation{
|
||||
Name: opInputService8TestCaseOperation1,
|
||||
}
|
||||
|
||||
if input == nil {
|
||||
input = &InputService8TestShapeInputShape{}
|
||||
}
|
||||
|
||||
req = c.newRequest(op, input, output)
|
||||
output = &InputService8TestShapeInputService8TestCaseOperation1Output{}
|
||||
req.Data = output
|
||||
return
|
||||
}
|
||||
|
||||
func (c *InputService8ProtocolTest) InputService8TestCaseOperation1(input *InputService8TestShapeInputShape) (*InputService8TestShapeInputService8TestCaseOperation1Output, error) {
|
||||
req, out := c.InputService8TestCaseOperation1Request(input)
|
||||
err := req.Send()
|
||||
return out, err
|
||||
}
|
||||
|
||||
type InputService8TestShapeInputService8TestCaseOperation1Output struct {
|
||||
metadataInputService8TestShapeInputService8TestCaseOperation1Output `json:"-" xml:"-"`
|
||||
}
|
||||
|
||||
type metadataInputService8TestShapeInputService8TestCaseOperation1Output struct {
|
||||
SDKShapeTraits bool `type:"structure"`
|
||||
}
|
||||
|
||||
type InputService8TestShapeInputShape struct {
|
||||
TimeArg *time.Time `type:"timestamp" timestampFormat:"iso8601"`
|
||||
|
||||
metadataInputService8TestShapeInputShape `json:"-" xml:"-"`
|
||||
}
|
||||
|
||||
type metadataInputService8TestShapeInputShape struct {
|
||||
SDKShapeTraits bool `type:"structure"`
|
||||
}
|
||||
|
||||
//
|
||||
// Tests begin here
|
||||
//
|
||||
|
||||
func TestInputService1ProtocolTestScalarMembersCase1(t *testing.T) {
|
||||
svc := NewInputService1ProtocolTest(nil)
|
||||
svc.Endpoint = "https://test"
|
||||
|
||||
input := &InputService1TestShapeInputShape{
|
||||
Bar: aws.String("val2"),
|
||||
Foo: aws.String("val1"),
|
||||
}
|
||||
req, _ := svc.InputService1TestCaseOperation1Request(input)
|
||||
r := req.HTTPRequest
|
||||
|
||||
// build request
|
||||
ec2query.Build(req)
|
||||
assert.NoError(t, req.Error)
|
||||
|
||||
// assert body
|
||||
assert.NotNil(t, r.Body)
|
||||
body, _ := ioutil.ReadAll(r.Body)
|
||||
assert.Equal(t, util.Trim(`Action=OperationName&Bar=val2&Foo=val1&Version=2014-01-01`), util.Trim(string(body)))
|
||||
|
||||
// assert URL
|
||||
assert.Equal(t, "https://test/", r.URL.String())
|
||||
|
||||
// assert headers
|
||||
|
||||
}
|
||||
|
||||
func TestInputService2ProtocolTestStructureWithLocationNameAndQueryNameAppliedToMembersCase1(t *testing.T) {
|
||||
svc := NewInputService2ProtocolTest(nil)
|
||||
svc.Endpoint = "https://test"
|
||||
|
||||
input := &InputService2TestShapeInputShape{
|
||||
Bar: aws.String("val2"),
|
||||
Foo: aws.String("val1"),
|
||||
Yuck: aws.String("val3"),
|
||||
}
|
||||
req, _ := svc.InputService2TestCaseOperation1Request(input)
|
||||
r := req.HTTPRequest
|
||||
|
||||
// build request
|
||||
ec2query.Build(req)
|
||||
assert.NoError(t, req.Error)
|
||||
|
||||
// assert body
|
||||
assert.NotNil(t, r.Body)
|
||||
body, _ := ioutil.ReadAll(r.Body)
|
||||
assert.Equal(t, util.Trim(`Action=OperationName&BarLocationName=val2&Foo=val1&Version=2014-01-01&yuckQueryName=val3`), util.Trim(string(body)))
|
||||
|
||||
// assert URL
|
||||
assert.Equal(t, "https://test/", r.URL.String())
|
||||
|
||||
// assert headers
|
||||
|
||||
}
|
||||
|
||||
func TestInputService3ProtocolTestNestedStructureMembersCase1(t *testing.T) {
|
||||
svc := NewInputService3ProtocolTest(nil)
|
||||
svc.Endpoint = "https://test"
|
||||
|
||||
input := &InputService3TestShapeInputShape{
|
||||
StructArg: &InputService3TestShapeStructType{
|
||||
ScalarArg: aws.String("foo"),
|
||||
},
|
||||
}
|
||||
req, _ := svc.InputService3TestCaseOperation1Request(input)
|
||||
r := req.HTTPRequest
|
||||
|
||||
// build request
|
||||
ec2query.Build(req)
|
||||
assert.NoError(t, req.Error)
|
||||
|
||||
// assert body
|
||||
assert.NotNil(t, r.Body)
|
||||
body, _ := ioutil.ReadAll(r.Body)
|
||||
assert.Equal(t, util.Trim(`Action=OperationName&Struct.Scalar=foo&Version=2014-01-01`), util.Trim(string(body)))
|
||||
|
||||
// assert URL
|
||||
assert.Equal(t, "https://test/", r.URL.String())
|
||||
|
||||
// assert headers
|
||||
|
||||
}
|
||||
|
||||
func TestInputService4ProtocolTestListTypesCase1(t *testing.T) {
|
||||
svc := NewInputService4ProtocolTest(nil)
|
||||
svc.Endpoint = "https://test"
|
||||
|
||||
input := &InputService4TestShapeInputShape{
|
||||
ListArg: []*string{
|
||||
aws.String("foo"),
|
||||
aws.String("bar"),
|
||||
aws.String("baz"),
|
||||
},
|
||||
}
|
||||
req, _ := svc.InputService4TestCaseOperation1Request(input)
|
||||
r := req.HTTPRequest
|
||||
|
||||
// build request
|
||||
ec2query.Build(req)
|
||||
assert.NoError(t, req.Error)
|
||||
|
||||
// assert body
|
||||
assert.NotNil(t, r.Body)
|
||||
body, _ := ioutil.ReadAll(r.Body)
|
||||
assert.Equal(t, util.Trim(`Action=OperationName&ListArg.1=foo&ListArg.2=bar&ListArg.3=baz&Version=2014-01-01`), util.Trim(string(body)))
|
||||
|
||||
// assert URL
|
||||
assert.Equal(t, "https://test/", r.URL.String())
|
||||
|
||||
// assert headers
|
||||
|
||||
}
|
||||
|
||||
func TestInputService5ProtocolTestListWithLocationNameAppliedToMemberCase1(t *testing.T) {
|
||||
svc := NewInputService5ProtocolTest(nil)
|
||||
svc.Endpoint = "https://test"
|
||||
|
||||
input := &InputService5TestShapeInputShape{
|
||||
ListArg: []*string{
|
||||
aws.String("a"),
|
||||
aws.String("b"),
|
||||
aws.String("c"),
|
||||
},
|
||||
}
|
||||
req, _ := svc.InputService5TestCaseOperation1Request(input)
|
||||
r := req.HTTPRequest
|
||||
|
||||
// build request
|
||||
ec2query.Build(req)
|
||||
assert.NoError(t, req.Error)
|
||||
|
||||
// assert body
|
||||
assert.NotNil(t, r.Body)
|
||||
body, _ := ioutil.ReadAll(r.Body)
|
||||
assert.Equal(t, util.Trim(`Action=OperationName&ListMemberName.1=a&ListMemberName.2=b&ListMemberName.3=c&Version=2014-01-01`), util.Trim(string(body)))
|
||||
|
||||
// assert URL
|
||||
assert.Equal(t, "https://test/", r.URL.String())
|
||||
|
||||
// assert headers
|
||||
|
||||
}
|
||||
|
||||
func TestInputService6ProtocolTestListWithLocationNameAndQueryNameCase1(t *testing.T) {
|
||||
svc := NewInputService6ProtocolTest(nil)
|
||||
svc.Endpoint = "https://test"
|
||||
|
||||
input := &InputService6TestShapeInputShape{
|
||||
ListArg: []*string{
|
||||
aws.String("a"),
|
||||
aws.String("b"),
|
||||
aws.String("c"),
|
||||
},
|
||||
}
|
||||
req, _ := svc.InputService6TestCaseOperation1Request(input)
|
||||
r := req.HTTPRequest
|
||||
|
||||
// build request
|
||||
ec2query.Build(req)
|
||||
assert.NoError(t, req.Error)
|
||||
|
||||
// assert body
|
||||
assert.NotNil(t, r.Body)
|
||||
body, _ := ioutil.ReadAll(r.Body)
|
||||
assert.Equal(t, util.Trim(`Action=OperationName&ListQueryName.1=a&ListQueryName.2=b&ListQueryName.3=c&Version=2014-01-01`), util.Trim(string(body)))
|
||||
|
||||
// assert URL
|
||||
assert.Equal(t, "https://test/", r.URL.String())
|
||||
|
||||
// assert headers
|
||||
|
||||
}
|
||||
|
||||
func TestInputService7ProtocolTestBase64EncodedBlobsCase1(t *testing.T) {
|
||||
svc := NewInputService7ProtocolTest(nil)
|
||||
svc.Endpoint = "https://test"
|
||||
|
||||
input := &InputService7TestShapeInputShape{
|
||||
BlobArg: []byte("foo"),
|
||||
}
|
||||
req, _ := svc.InputService7TestCaseOperation1Request(input)
|
||||
r := req.HTTPRequest
|
||||
|
||||
// build request
|
||||
ec2query.Build(req)
|
||||
assert.NoError(t, req.Error)
|
||||
|
||||
// assert body
|
||||
assert.NotNil(t, r.Body)
|
||||
body, _ := ioutil.ReadAll(r.Body)
|
||||
assert.Equal(t, util.Trim(`Action=OperationName&BlobArg=Zm9v&Version=2014-01-01`), util.Trim(string(body)))
|
||||
|
||||
// assert URL
|
||||
assert.Equal(t, "https://test/", r.URL.String())
|
||||
|
||||
// assert headers
|
||||
|
||||
}
|
||||
|
||||
func TestInputService8ProtocolTestTimestampValuesCase1(t *testing.T) {
|
||||
svc := NewInputService8ProtocolTest(nil)
|
||||
svc.Endpoint = "https://test"
|
||||
|
||||
input := &InputService8TestShapeInputShape{
|
||||
TimeArg: aws.Time(time.Unix(1422172800, 0)),
|
||||
}
|
||||
req, _ := svc.InputService8TestCaseOperation1Request(input)
|
||||
r := req.HTTPRequest
|
||||
|
||||
// build request
|
||||
ec2query.Build(req)
|
||||
assert.NoError(t, req.Error)
|
||||
|
||||
// assert body
|
||||
assert.NotNil(t, r.Body)
|
||||
body, _ := ioutil.ReadAll(r.Body)
|
||||
assert.Equal(t, util.Trim(`Action=OperationName&TimeArg=2015-01-25T08%3A00%3A00Z&Version=2014-01-01`), util.Trim(string(body)))
|
||||
|
||||
// assert URL
|
||||
assert.Equal(t, "https://test/", r.URL.String())
|
||||
|
||||
// assert headers
|
||||
|
||||
}
|
||||
54
Godeps/_workspace/src/github.com/aws/aws-sdk-go/internal/protocol/ec2query/unmarshal.go
generated
vendored
Normal file
54
Godeps/_workspace/src/github.com/aws/aws-sdk-go/internal/protocol/ec2query/unmarshal.go
generated
vendored
Normal file
@@ -0,0 +1,54 @@
|
||||
package ec2query
|
||||
|
||||
//go:generate go run ../../fixtures/protocol/generate.go ../../fixtures/protocol/output/ec2.json unmarshal_test.go
|
||||
|
||||
import (
|
||||
"encoding/xml"
|
||||
"io"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/aws/awserr"
|
||||
"github.com/aws/aws-sdk-go/internal/protocol/xml/xmlutil"
|
||||
)
|
||||
|
||||
// Unmarshal unmarshals a response body for the EC2 protocol.
|
||||
func Unmarshal(r *aws.Request) {
|
||||
defer r.HTTPResponse.Body.Close()
|
||||
if r.DataFilled() {
|
||||
decoder := xml.NewDecoder(r.HTTPResponse.Body)
|
||||
err := xmlutil.UnmarshalXML(r.Data, decoder, "")
|
||||
if err != nil {
|
||||
r.Error = awserr.New("SerializationError", "failed decoding EC2 Query response", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// UnmarshalMeta unmarshals response headers for the EC2 protocol.
|
||||
func UnmarshalMeta(r *aws.Request) {
|
||||
// TODO implement unmarshaling of request IDs
|
||||
}
|
||||
|
||||
type xmlErrorResponse struct {
|
||||
XMLName xml.Name `xml:"Response"`
|
||||
Code string `xml:"Errors>Error>Code"`
|
||||
Message string `xml:"Errors>Error>Message"`
|
||||
RequestID string `xml:"RequestId"`
|
||||
}
|
||||
|
||||
// UnmarshalError unmarshals a response error for the EC2 protocol.
|
||||
func UnmarshalError(r *aws.Request) {
|
||||
defer r.HTTPResponse.Body.Close()
|
||||
|
||||
resp := &xmlErrorResponse{}
|
||||
err := xml.NewDecoder(r.HTTPResponse.Body).Decode(resp)
|
||||
if err != nil && err != io.EOF {
|
||||
r.Error = awserr.New("SerializationError", "failed decoding EC2 Query error response", err)
|
||||
} else {
|
||||
r.Error = awserr.NewRequestFailure(
|
||||
awserr.New(resp.Code, resp.Message, nil),
|
||||
r.HTTPResponse.StatusCode,
|
||||
resp.RequestID,
|
||||
)
|
||||
}
|
||||
}
|
||||
816
Godeps/_workspace/src/github.com/aws/aws-sdk-go/internal/protocol/ec2query/unmarshal_test.go
generated
vendored
Normal file
816
Godeps/_workspace/src/github.com/aws/aws-sdk-go/internal/protocol/ec2query/unmarshal_test.go
generated
vendored
Normal file
@@ -0,0 +1,816 @@
|
||||
package ec2query_test
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"encoding/xml"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/internal/protocol/ec2query"
|
||||
"github.com/aws/aws-sdk-go/internal/protocol/xml/xmlutil"
|
||||
"github.com/aws/aws-sdk-go/internal/signer/v4"
|
||||
"github.com/aws/aws-sdk-go/internal/util"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
var _ bytes.Buffer // always import bytes
|
||||
var _ http.Request
|
||||
var _ json.Marshaler
|
||||
var _ time.Time
|
||||
var _ xmlutil.XMLNode
|
||||
var _ xml.Attr
|
||||
var _ = ioutil.Discard
|
||||
var _ = util.Trim("")
|
||||
var _ = url.Values{}
|
||||
var _ = io.EOF
|
||||
|
||||
type OutputService1ProtocolTest struct {
|
||||
*aws.Service
|
||||
}
|
||||
|
||||
// New returns a new OutputService1ProtocolTest client.
|
||||
func NewOutputService1ProtocolTest(config *aws.Config) *OutputService1ProtocolTest {
|
||||
service := &aws.Service{
|
||||
Config: aws.DefaultConfig.Merge(config),
|
||||
ServiceName: "outputservice1protocoltest",
|
||||
APIVersion: "",
|
||||
}
|
||||
service.Initialize()
|
||||
|
||||
// Handlers
|
||||
service.Handlers.Sign.PushBack(v4.Sign)
|
||||
service.Handlers.Build.PushBack(ec2query.Build)
|
||||
service.Handlers.Unmarshal.PushBack(ec2query.Unmarshal)
|
||||
service.Handlers.UnmarshalMeta.PushBack(ec2query.UnmarshalMeta)
|
||||
service.Handlers.UnmarshalError.PushBack(ec2query.UnmarshalError)
|
||||
|
||||
return &OutputService1ProtocolTest{service}
|
||||
}
|
||||
|
||||
// newRequest creates a new request for a OutputService1ProtocolTest operation and runs any
|
||||
// custom request initialization.
|
||||
func (c *OutputService1ProtocolTest) newRequest(op *aws.Operation, params, data interface{}) *aws.Request {
|
||||
req := aws.NewRequest(c.Service, op, params, data)
|
||||
|
||||
return req
|
||||
}
|
||||
|
||||
const opOutputService1TestCaseOperation1 = "OperationName"
|
||||
|
||||
// OutputService1TestCaseOperation1Request generates a request for the OutputService1TestCaseOperation1 operation.
|
||||
func (c *OutputService1ProtocolTest) OutputService1TestCaseOperation1Request(input *OutputService1TestShapeOutputService1TestCaseOperation1Input) (req *aws.Request, output *OutputService1TestShapeOutputShape) {
|
||||
op := &aws.Operation{
|
||||
Name: opOutputService1TestCaseOperation1,
|
||||
}
|
||||
|
||||
if input == nil {
|
||||
input = &OutputService1TestShapeOutputService1TestCaseOperation1Input{}
|
||||
}
|
||||
|
||||
req = c.newRequest(op, input, output)
|
||||
output = &OutputService1TestShapeOutputShape{}
|
||||
req.Data = output
|
||||
return
|
||||
}
|
||||
|
||||
func (c *OutputService1ProtocolTest) OutputService1TestCaseOperation1(input *OutputService1TestShapeOutputService1TestCaseOperation1Input) (*OutputService1TestShapeOutputShape, error) {
|
||||
req, out := c.OutputService1TestCaseOperation1Request(input)
|
||||
err := req.Send()
|
||||
return out, err
|
||||
}
|
||||
|
||||
type OutputService1TestShapeOutputService1TestCaseOperation1Input struct {
|
||||
metadataOutputService1TestShapeOutputService1TestCaseOperation1Input `json:"-" xml:"-"`
|
||||
}
|
||||
|
||||
type metadataOutputService1TestShapeOutputService1TestCaseOperation1Input struct {
|
||||
SDKShapeTraits bool `type:"structure"`
|
||||
}
|
||||
|
||||
type OutputService1TestShapeOutputShape struct {
|
||||
Char *string `type:"character"`
|
||||
|
||||
Double *float64 `type:"double"`
|
||||
|
||||
FalseBool *bool `type:"boolean"`
|
||||
|
||||
Float *float64 `type:"float"`
|
||||
|
||||
Long *int64 `type:"long"`
|
||||
|
||||
Num *int64 `locationName:"FooNum" type:"integer"`
|
||||
|
||||
Str *string `type:"string"`
|
||||
|
||||
TrueBool *bool `type:"boolean"`
|
||||
|
||||
metadataOutputService1TestShapeOutputShape `json:"-" xml:"-"`
|
||||
}
|
||||
|
||||
type metadataOutputService1TestShapeOutputShape struct {
|
||||
SDKShapeTraits bool `type:"structure"`
|
||||
}
|
||||
|
||||
type OutputService2ProtocolTest struct {
|
||||
*aws.Service
|
||||
}
|
||||
|
||||
// New returns a new OutputService2ProtocolTest client.
|
||||
func NewOutputService2ProtocolTest(config *aws.Config) *OutputService2ProtocolTest {
|
||||
service := &aws.Service{
|
||||
Config: aws.DefaultConfig.Merge(config),
|
||||
ServiceName: "outputservice2protocoltest",
|
||||
APIVersion: "",
|
||||
}
|
||||
service.Initialize()
|
||||
|
||||
// Handlers
|
||||
service.Handlers.Sign.PushBack(v4.Sign)
|
||||
service.Handlers.Build.PushBack(ec2query.Build)
|
||||
service.Handlers.Unmarshal.PushBack(ec2query.Unmarshal)
|
||||
service.Handlers.UnmarshalMeta.PushBack(ec2query.UnmarshalMeta)
|
||||
service.Handlers.UnmarshalError.PushBack(ec2query.UnmarshalError)
|
||||
|
||||
return &OutputService2ProtocolTest{service}
|
||||
}
|
||||
|
||||
// newRequest creates a new request for a OutputService2ProtocolTest operation and runs any
|
||||
// custom request initialization.
|
||||
func (c *OutputService2ProtocolTest) newRequest(op *aws.Operation, params, data interface{}) *aws.Request {
|
||||
req := aws.NewRequest(c.Service, op, params, data)
|
||||
|
||||
return req
|
||||
}
|
||||
|
||||
const opOutputService2TestCaseOperation1 = "OperationName"
|
||||
|
||||
// OutputService2TestCaseOperation1Request generates a request for the OutputService2TestCaseOperation1 operation.
|
||||
func (c *OutputService2ProtocolTest) OutputService2TestCaseOperation1Request(input *OutputService2TestShapeOutputService2TestCaseOperation1Input) (req *aws.Request, output *OutputService2TestShapeOutputShape) {
|
||||
op := &aws.Operation{
|
||||
Name: opOutputService2TestCaseOperation1,
|
||||
}
|
||||
|
||||
if input == nil {
|
||||
input = &OutputService2TestShapeOutputService2TestCaseOperation1Input{}
|
||||
}
|
||||
|
||||
req = c.newRequest(op, input, output)
|
||||
output = &OutputService2TestShapeOutputShape{}
|
||||
req.Data = output
|
||||
return
|
||||
}
|
||||
|
||||
func (c *OutputService2ProtocolTest) OutputService2TestCaseOperation1(input *OutputService2TestShapeOutputService2TestCaseOperation1Input) (*OutputService2TestShapeOutputShape, error) {
|
||||
req, out := c.OutputService2TestCaseOperation1Request(input)
|
||||
err := req.Send()
|
||||
return out, err
|
||||
}
|
||||
|
||||
type OutputService2TestShapeOutputService2TestCaseOperation1Input struct {
|
||||
metadataOutputService2TestShapeOutputService2TestCaseOperation1Input `json:"-" xml:"-"`
|
||||
}
|
||||
|
||||
type metadataOutputService2TestShapeOutputService2TestCaseOperation1Input struct {
|
||||
SDKShapeTraits bool `type:"structure"`
|
||||
}
|
||||
|
||||
type OutputService2TestShapeOutputShape struct {
|
||||
Blob []byte `type:"blob"`
|
||||
|
||||
metadataOutputService2TestShapeOutputShape `json:"-" xml:"-"`
|
||||
}
|
||||
|
||||
type metadataOutputService2TestShapeOutputShape struct {
|
||||
SDKShapeTraits bool `type:"structure"`
|
||||
}
|
||||
|
||||
type OutputService3ProtocolTest struct {
|
||||
*aws.Service
|
||||
}
|
||||
|
||||
// New returns a new OutputService3ProtocolTest client.
|
||||
func NewOutputService3ProtocolTest(config *aws.Config) *OutputService3ProtocolTest {
|
||||
service := &aws.Service{
|
||||
Config: aws.DefaultConfig.Merge(config),
|
||||
ServiceName: "outputservice3protocoltest",
|
||||
APIVersion: "",
|
||||
}
|
||||
service.Initialize()
|
||||
|
||||
// Handlers
|
||||
service.Handlers.Sign.PushBack(v4.Sign)
|
||||
service.Handlers.Build.PushBack(ec2query.Build)
|
||||
service.Handlers.Unmarshal.PushBack(ec2query.Unmarshal)
|
||||
service.Handlers.UnmarshalMeta.PushBack(ec2query.UnmarshalMeta)
|
||||
service.Handlers.UnmarshalError.PushBack(ec2query.UnmarshalError)
|
||||
|
||||
return &OutputService3ProtocolTest{service}
|
||||
}
|
||||
|
||||
// newRequest creates a new request for a OutputService3ProtocolTest operation and runs any
|
||||
// custom request initialization.
|
||||
func (c *OutputService3ProtocolTest) newRequest(op *aws.Operation, params, data interface{}) *aws.Request {
|
||||
req := aws.NewRequest(c.Service, op, params, data)
|
||||
|
||||
return req
|
||||
}
|
||||
|
||||
const opOutputService3TestCaseOperation1 = "OperationName"
|
||||
|
||||
// OutputService3TestCaseOperation1Request generates a request for the OutputService3TestCaseOperation1 operation.
|
||||
func (c *OutputService3ProtocolTest) OutputService3TestCaseOperation1Request(input *OutputService3TestShapeOutputService3TestCaseOperation1Input) (req *aws.Request, output *OutputService3TestShapeOutputShape) {
|
||||
op := &aws.Operation{
|
||||
Name: opOutputService3TestCaseOperation1,
|
||||
}
|
||||
|
||||
if input == nil {
|
||||
input = &OutputService3TestShapeOutputService3TestCaseOperation1Input{}
|
||||
}
|
||||
|
||||
req = c.newRequest(op, input, output)
|
||||
output = &OutputService3TestShapeOutputShape{}
|
||||
req.Data = output
|
||||
return
|
||||
}
|
||||
|
||||
func (c *OutputService3ProtocolTest) OutputService3TestCaseOperation1(input *OutputService3TestShapeOutputService3TestCaseOperation1Input) (*OutputService3TestShapeOutputShape, error) {
|
||||
req, out := c.OutputService3TestCaseOperation1Request(input)
|
||||
err := req.Send()
|
||||
return out, err
|
||||
}
|
||||
|
||||
type OutputService3TestShapeOutputService3TestCaseOperation1Input struct {
|
||||
metadataOutputService3TestShapeOutputService3TestCaseOperation1Input `json:"-" xml:"-"`
|
||||
}
|
||||
|
||||
type metadataOutputService3TestShapeOutputService3TestCaseOperation1Input struct {
|
||||
SDKShapeTraits bool `type:"structure"`
|
||||
}
|
||||
|
||||
type OutputService3TestShapeOutputShape struct {
|
||||
ListMember []*string `type:"list"`
|
||||
|
||||
metadataOutputService3TestShapeOutputShape `json:"-" xml:"-"`
|
||||
}
|
||||
|
||||
type metadataOutputService3TestShapeOutputShape struct {
|
||||
SDKShapeTraits bool `type:"structure"`
|
||||
}
|
||||
|
||||
type OutputService4ProtocolTest struct {
|
||||
*aws.Service
|
||||
}
|
||||
|
||||
// New returns a new OutputService4ProtocolTest client.
|
||||
func NewOutputService4ProtocolTest(config *aws.Config) *OutputService4ProtocolTest {
|
||||
service := &aws.Service{
|
||||
Config: aws.DefaultConfig.Merge(config),
|
||||
ServiceName: "outputservice4protocoltest",
|
||||
APIVersion: "",
|
||||
}
|
||||
service.Initialize()
|
||||
|
||||
// Handlers
|
||||
service.Handlers.Sign.PushBack(v4.Sign)
|
||||
service.Handlers.Build.PushBack(ec2query.Build)
|
||||
service.Handlers.Unmarshal.PushBack(ec2query.Unmarshal)
|
||||
service.Handlers.UnmarshalMeta.PushBack(ec2query.UnmarshalMeta)
|
||||
service.Handlers.UnmarshalError.PushBack(ec2query.UnmarshalError)
|
||||
|
||||
return &OutputService4ProtocolTest{service}
|
||||
}
|
||||
|
||||
// newRequest creates a new request for a OutputService4ProtocolTest operation and runs any
|
||||
// custom request initialization.
|
||||
func (c *OutputService4ProtocolTest) newRequest(op *aws.Operation, params, data interface{}) *aws.Request {
|
||||
req := aws.NewRequest(c.Service, op, params, data)
|
||||
|
||||
return req
|
||||
}
|
||||
|
||||
const opOutputService4TestCaseOperation1 = "OperationName"
|
||||
|
||||
// OutputService4TestCaseOperation1Request generates a request for the OutputService4TestCaseOperation1 operation.
|
||||
func (c *OutputService4ProtocolTest) OutputService4TestCaseOperation1Request(input *OutputService4TestShapeOutputService4TestCaseOperation1Input) (req *aws.Request, output *OutputService4TestShapeOutputShape) {
|
||||
op := &aws.Operation{
|
||||
Name: opOutputService4TestCaseOperation1,
|
||||
}
|
||||
|
||||
if input == nil {
|
||||
input = &OutputService4TestShapeOutputService4TestCaseOperation1Input{}
|
||||
}
|
||||
|
||||
req = c.newRequest(op, input, output)
|
||||
output = &OutputService4TestShapeOutputShape{}
|
||||
req.Data = output
|
||||
return
|
||||
}
|
||||
|
||||
func (c *OutputService4ProtocolTest) OutputService4TestCaseOperation1(input *OutputService4TestShapeOutputService4TestCaseOperation1Input) (*OutputService4TestShapeOutputShape, error) {
|
||||
req, out := c.OutputService4TestCaseOperation1Request(input)
|
||||
err := req.Send()
|
||||
return out, err
|
||||
}
|
||||
|
||||
type OutputService4TestShapeOutputService4TestCaseOperation1Input struct {
|
||||
metadataOutputService4TestShapeOutputService4TestCaseOperation1Input `json:"-" xml:"-"`
|
||||
}
|
||||
|
||||
type metadataOutputService4TestShapeOutputService4TestCaseOperation1Input struct {
|
||||
SDKShapeTraits bool `type:"structure"`
|
||||
}
|
||||
|
||||
type OutputService4TestShapeOutputShape struct {
|
||||
ListMember []*string `locationNameList:"item" type:"list"`
|
||||
|
||||
metadataOutputService4TestShapeOutputShape `json:"-" xml:"-"`
|
||||
}
|
||||
|
||||
type metadataOutputService4TestShapeOutputShape struct {
|
||||
SDKShapeTraits bool `type:"structure"`
|
||||
}
|
||||
|
||||
type OutputService5ProtocolTest struct {
|
||||
*aws.Service
|
||||
}
|
||||
|
||||
// New returns a new OutputService5ProtocolTest client.
|
||||
func NewOutputService5ProtocolTest(config *aws.Config) *OutputService5ProtocolTest {
|
||||
service := &aws.Service{
|
||||
Config: aws.DefaultConfig.Merge(config),
|
||||
ServiceName: "outputservice5protocoltest",
|
||||
APIVersion: "",
|
||||
}
|
||||
service.Initialize()
|
||||
|
||||
// Handlers
|
||||
service.Handlers.Sign.PushBack(v4.Sign)
|
||||
service.Handlers.Build.PushBack(ec2query.Build)
|
||||
service.Handlers.Unmarshal.PushBack(ec2query.Unmarshal)
|
||||
service.Handlers.UnmarshalMeta.PushBack(ec2query.UnmarshalMeta)
|
||||
service.Handlers.UnmarshalError.PushBack(ec2query.UnmarshalError)
|
||||
|
||||
return &OutputService5ProtocolTest{service}
|
||||
}
|
||||
|
||||
// newRequest creates a new request for a OutputService5ProtocolTest operation and runs any
|
||||
// custom request initialization.
|
||||
func (c *OutputService5ProtocolTest) newRequest(op *aws.Operation, params, data interface{}) *aws.Request {
|
||||
req := aws.NewRequest(c.Service, op, params, data)
|
||||
|
||||
return req
|
||||
}
|
||||
|
||||
const opOutputService5TestCaseOperation1 = "OperationName"
|
||||
|
||||
// OutputService5TestCaseOperation1Request generates a request for the OutputService5TestCaseOperation1 operation.
|
||||
func (c *OutputService5ProtocolTest) OutputService5TestCaseOperation1Request(input *OutputService5TestShapeOutputService5TestCaseOperation1Input) (req *aws.Request, output *OutputService5TestShapeOutputShape) {
|
||||
op := &aws.Operation{
|
||||
Name: opOutputService5TestCaseOperation1,
|
||||
}
|
||||
|
||||
if input == nil {
|
||||
input = &OutputService5TestShapeOutputService5TestCaseOperation1Input{}
|
||||
}
|
||||
|
||||
req = c.newRequest(op, input, output)
|
||||
output = &OutputService5TestShapeOutputShape{}
|
||||
req.Data = output
|
||||
return
|
||||
}
|
||||
|
||||
func (c *OutputService5ProtocolTest) OutputService5TestCaseOperation1(input *OutputService5TestShapeOutputService5TestCaseOperation1Input) (*OutputService5TestShapeOutputShape, error) {
|
||||
req, out := c.OutputService5TestCaseOperation1Request(input)
|
||||
err := req.Send()
|
||||
return out, err
|
||||
}
|
||||
|
||||
type OutputService5TestShapeOutputService5TestCaseOperation1Input struct {
|
||||
metadataOutputService5TestShapeOutputService5TestCaseOperation1Input `json:"-" xml:"-"`
|
||||
}
|
||||
|
||||
type metadataOutputService5TestShapeOutputService5TestCaseOperation1Input struct {
|
||||
SDKShapeTraits bool `type:"structure"`
|
||||
}
|
||||
|
||||
type OutputService5TestShapeOutputShape struct {
|
||||
ListMember []*string `type:"list" flattened:"true"`
|
||||
|
||||
metadataOutputService5TestShapeOutputShape `json:"-" xml:"-"`
|
||||
}
|
||||
|
||||
type metadataOutputService5TestShapeOutputShape struct {
|
||||
SDKShapeTraits bool `type:"structure"`
|
||||
}
|
||||
|
||||
type OutputService6ProtocolTest struct {
|
||||
*aws.Service
|
||||
}
|
||||
|
||||
// New returns a new OutputService6ProtocolTest client.
|
||||
func NewOutputService6ProtocolTest(config *aws.Config) *OutputService6ProtocolTest {
|
||||
service := &aws.Service{
|
||||
Config: aws.DefaultConfig.Merge(config),
|
||||
ServiceName: "outputservice6protocoltest",
|
||||
APIVersion: "",
|
||||
}
|
||||
service.Initialize()
|
||||
|
||||
// Handlers
|
||||
service.Handlers.Sign.PushBack(v4.Sign)
|
||||
service.Handlers.Build.PushBack(ec2query.Build)
|
||||
service.Handlers.Unmarshal.PushBack(ec2query.Unmarshal)
|
||||
service.Handlers.UnmarshalMeta.PushBack(ec2query.UnmarshalMeta)
|
||||
service.Handlers.UnmarshalError.PushBack(ec2query.UnmarshalError)
|
||||
|
||||
return &OutputService6ProtocolTest{service}
|
||||
}
|
||||
|
||||
// newRequest creates a new request for a OutputService6ProtocolTest operation and runs any
|
||||
// custom request initialization.
|
||||
func (c *OutputService6ProtocolTest) newRequest(op *aws.Operation, params, data interface{}) *aws.Request {
|
||||
req := aws.NewRequest(c.Service, op, params, data)
|
||||
|
||||
return req
|
||||
}
|
||||
|
||||
const opOutputService6TestCaseOperation1 = "OperationName"
|
||||
|
||||
// OutputService6TestCaseOperation1Request generates a request for the OutputService6TestCaseOperation1 operation.
|
||||
func (c *OutputService6ProtocolTest) OutputService6TestCaseOperation1Request(input *OutputService6TestShapeOutputService6TestCaseOperation1Input) (req *aws.Request, output *OutputService6TestShapeOutputShape) {
|
||||
op := &aws.Operation{
|
||||
Name: opOutputService6TestCaseOperation1,
|
||||
}
|
||||
|
||||
if input == nil {
|
||||
input = &OutputService6TestShapeOutputService6TestCaseOperation1Input{}
|
||||
}
|
||||
|
||||
req = c.newRequest(op, input, output)
|
||||
output = &OutputService6TestShapeOutputShape{}
|
||||
req.Data = output
|
||||
return
|
||||
}
|
||||
|
||||
func (c *OutputService6ProtocolTest) OutputService6TestCaseOperation1(input *OutputService6TestShapeOutputService6TestCaseOperation1Input) (*OutputService6TestShapeOutputShape, error) {
|
||||
req, out := c.OutputService6TestCaseOperation1Request(input)
|
||||
err := req.Send()
|
||||
return out, err
|
||||
}
|
||||
|
||||
type OutputService6TestShapeOutputService6TestCaseOperation1Input struct {
|
||||
metadataOutputService6TestShapeOutputService6TestCaseOperation1Input `json:"-" xml:"-"`
|
||||
}
|
||||
|
||||
type metadataOutputService6TestShapeOutputService6TestCaseOperation1Input struct {
|
||||
SDKShapeTraits bool `type:"structure"`
|
||||
}
|
||||
|
||||
type OutputService6TestShapeOutputShape struct {
|
||||
Map map[string]*OutputService6TestShapeStructureType `type:"map"`
|
||||
|
||||
metadataOutputService6TestShapeOutputShape `json:"-" xml:"-"`
|
||||
}
|
||||
|
||||
type metadataOutputService6TestShapeOutputShape struct {
|
||||
SDKShapeTraits bool `type:"structure"`
|
||||
}
|
||||
|
||||
type OutputService6TestShapeStructureType struct {
|
||||
Foo *string `locationName:"foo" type:"string"`
|
||||
|
||||
metadataOutputService6TestShapeStructureType `json:"-" xml:"-"`
|
||||
}
|
||||
|
||||
type metadataOutputService6TestShapeStructureType struct {
|
||||
SDKShapeTraits bool `type:"structure"`
|
||||
}
|
||||
|
||||
type OutputService7ProtocolTest struct {
|
||||
*aws.Service
|
||||
}
|
||||
|
||||
// New returns a new OutputService7ProtocolTest client.
|
||||
func NewOutputService7ProtocolTest(config *aws.Config) *OutputService7ProtocolTest {
|
||||
service := &aws.Service{
|
||||
Config: aws.DefaultConfig.Merge(config),
|
||||
ServiceName: "outputservice7protocoltest",
|
||||
APIVersion: "",
|
||||
}
|
||||
service.Initialize()
|
||||
|
||||
// Handlers
|
||||
service.Handlers.Sign.PushBack(v4.Sign)
|
||||
service.Handlers.Build.PushBack(ec2query.Build)
|
||||
service.Handlers.Unmarshal.PushBack(ec2query.Unmarshal)
|
||||
service.Handlers.UnmarshalMeta.PushBack(ec2query.UnmarshalMeta)
|
||||
service.Handlers.UnmarshalError.PushBack(ec2query.UnmarshalError)
|
||||
|
||||
return &OutputService7ProtocolTest{service}
|
||||
}
|
||||
|
||||
// newRequest creates a new request for a OutputService7ProtocolTest operation and runs any
|
||||
// custom request initialization.
|
||||
func (c *OutputService7ProtocolTest) newRequest(op *aws.Operation, params, data interface{}) *aws.Request {
|
||||
req := aws.NewRequest(c.Service, op, params, data)
|
||||
|
||||
return req
|
||||
}
|
||||
|
||||
const opOutputService7TestCaseOperation1 = "OperationName"
|
||||
|
||||
// OutputService7TestCaseOperation1Request generates a request for the OutputService7TestCaseOperation1 operation.
|
||||
func (c *OutputService7ProtocolTest) OutputService7TestCaseOperation1Request(input *OutputService7TestShapeOutputService7TestCaseOperation1Input) (req *aws.Request, output *OutputService7TestShapeOutputShape) {
|
||||
op := &aws.Operation{
|
||||
Name: opOutputService7TestCaseOperation1,
|
||||
}
|
||||
|
||||
if input == nil {
|
||||
input = &OutputService7TestShapeOutputService7TestCaseOperation1Input{}
|
||||
}
|
||||
|
||||
req = c.newRequest(op, input, output)
|
||||
output = &OutputService7TestShapeOutputShape{}
|
||||
req.Data = output
|
||||
return
|
||||
}
|
||||
|
||||
func (c *OutputService7ProtocolTest) OutputService7TestCaseOperation1(input *OutputService7TestShapeOutputService7TestCaseOperation1Input) (*OutputService7TestShapeOutputShape, error) {
|
||||
req, out := c.OutputService7TestCaseOperation1Request(input)
|
||||
err := req.Send()
|
||||
return out, err
|
||||
}
|
||||
|
||||
type OutputService7TestShapeOutputService7TestCaseOperation1Input struct {
|
||||
metadataOutputService7TestShapeOutputService7TestCaseOperation1Input `json:"-" xml:"-"`
|
||||
}
|
||||
|
||||
type metadataOutputService7TestShapeOutputService7TestCaseOperation1Input struct {
|
||||
SDKShapeTraits bool `type:"structure"`
|
||||
}
|
||||
|
||||
type OutputService7TestShapeOutputShape struct {
|
||||
Map map[string]*string `type:"map" flattened:"true"`
|
||||
|
||||
metadataOutputService7TestShapeOutputShape `json:"-" xml:"-"`
|
||||
}
|
||||
|
||||
type metadataOutputService7TestShapeOutputShape struct {
|
||||
SDKShapeTraits bool `type:"structure"`
|
||||
}
|
||||
|
||||
type OutputService8ProtocolTest struct {
|
||||
*aws.Service
|
||||
}
|
||||
|
||||
// New returns a new OutputService8ProtocolTest client.
|
||||
func NewOutputService8ProtocolTest(config *aws.Config) *OutputService8ProtocolTest {
|
||||
service := &aws.Service{
|
||||
Config: aws.DefaultConfig.Merge(config),
|
||||
ServiceName: "outputservice8protocoltest",
|
||||
APIVersion: "",
|
||||
}
|
||||
service.Initialize()
|
||||
|
||||
// Handlers
|
||||
service.Handlers.Sign.PushBack(v4.Sign)
|
||||
service.Handlers.Build.PushBack(ec2query.Build)
|
||||
service.Handlers.Unmarshal.PushBack(ec2query.Unmarshal)
|
||||
service.Handlers.UnmarshalMeta.PushBack(ec2query.UnmarshalMeta)
|
||||
service.Handlers.UnmarshalError.PushBack(ec2query.UnmarshalError)
|
||||
|
||||
return &OutputService8ProtocolTest{service}
|
||||
}
|
||||
|
||||
// newRequest creates a new request for a OutputService8ProtocolTest operation and runs any
|
||||
// custom request initialization.
|
||||
func (c *OutputService8ProtocolTest) newRequest(op *aws.Operation, params, data interface{}) *aws.Request {
|
||||
req := aws.NewRequest(c.Service, op, params, data)
|
||||
|
||||
return req
|
||||
}
|
||||
|
||||
const opOutputService8TestCaseOperation1 = "OperationName"
|
||||
|
||||
// OutputService8TestCaseOperation1Request generates a request for the OutputService8TestCaseOperation1 operation.
|
||||
func (c *OutputService8ProtocolTest) OutputService8TestCaseOperation1Request(input *OutputService8TestShapeOutputService8TestCaseOperation1Input) (req *aws.Request, output *OutputService8TestShapeOutputShape) {
|
||||
op := &aws.Operation{
|
||||
Name: opOutputService8TestCaseOperation1,
|
||||
}
|
||||
|
||||
if input == nil {
|
||||
input = &OutputService8TestShapeOutputService8TestCaseOperation1Input{}
|
||||
}
|
||||
|
||||
req = c.newRequest(op, input, output)
|
||||
output = &OutputService8TestShapeOutputShape{}
|
||||
req.Data = output
|
||||
return
|
||||
}
|
||||
|
||||
func (c *OutputService8ProtocolTest) OutputService8TestCaseOperation1(input *OutputService8TestShapeOutputService8TestCaseOperation1Input) (*OutputService8TestShapeOutputShape, error) {
|
||||
req, out := c.OutputService8TestCaseOperation1Request(input)
|
||||
err := req.Send()
|
||||
return out, err
|
||||
}
|
||||
|
||||
type OutputService8TestShapeOutputService8TestCaseOperation1Input struct {
|
||||
metadataOutputService8TestShapeOutputService8TestCaseOperation1Input `json:"-" xml:"-"`
|
||||
}
|
||||
|
||||
type metadataOutputService8TestShapeOutputService8TestCaseOperation1Input struct {
|
||||
SDKShapeTraits bool `type:"structure"`
|
||||
}
|
||||
|
||||
type OutputService8TestShapeOutputShape struct {
|
||||
Map map[string]*string `locationNameKey:"foo" locationNameValue:"bar" type:"map" flattened:"true"`
|
||||
|
||||
metadataOutputService8TestShapeOutputShape `json:"-" xml:"-"`
|
||||
}
|
||||
|
||||
type metadataOutputService8TestShapeOutputShape struct {
|
||||
SDKShapeTraits bool `type:"structure"`
|
||||
}
|
||||
|
||||
//
|
||||
// Tests begin here
|
||||
//
|
||||
|
||||
func TestOutputService1ProtocolTestScalarMembersCase1(t *testing.T) {
|
||||
svc := NewOutputService1ProtocolTest(nil)
|
||||
|
||||
buf := bytes.NewReader([]byte("<OperationNameResponse><Str>myname</Str><FooNum>123</FooNum><FalseBool>false</FalseBool><TrueBool>true</TrueBool><Float>1.2</Float><Double>1.3</Double><Long>200</Long><Char>a</Char><RequestId>request-id</RequestId></OperationNameResponse>"))
|
||||
req, out := svc.OutputService1TestCaseOperation1Request(nil)
|
||||
req.HTTPResponse = &http.Response{StatusCode: 200, Body: ioutil.NopCloser(buf), Header: http.Header{}}
|
||||
|
||||
// set headers
|
||||
|
||||
// unmarshal response
|
||||
ec2query.UnmarshalMeta(req)
|
||||
ec2query.Unmarshal(req)
|
||||
assert.NoError(t, req.Error)
|
||||
|
||||
// assert response
|
||||
assert.NotNil(t, out) // ensure out variable is used
|
||||
assert.Equal(t, "a", *out.Char)
|
||||
assert.Equal(t, 1.3, *out.Double)
|
||||
assert.Equal(t, false, *out.FalseBool)
|
||||
assert.Equal(t, 1.2, *out.Float)
|
||||
assert.Equal(t, int64(200), *out.Long)
|
||||
assert.Equal(t, int64(123), *out.Num)
|
||||
assert.Equal(t, "myname", *out.Str)
|
||||
assert.Equal(t, true, *out.TrueBool)
|
||||
|
||||
}
|
||||
|
||||
func TestOutputService2ProtocolTestBlobCase1(t *testing.T) {
|
||||
svc := NewOutputService2ProtocolTest(nil)
|
||||
|
||||
buf := bytes.NewReader([]byte("<OperationNameResponse><Blob>dmFsdWU=</Blob><RequestId>requestid</RequestId></OperationNameResponse>"))
|
||||
req, out := svc.OutputService2TestCaseOperation1Request(nil)
|
||||
req.HTTPResponse = &http.Response{StatusCode: 200, Body: ioutil.NopCloser(buf), Header: http.Header{}}
|
||||
|
||||
// set headers
|
||||
|
||||
// unmarshal response
|
||||
ec2query.UnmarshalMeta(req)
|
||||
ec2query.Unmarshal(req)
|
||||
assert.NoError(t, req.Error)
|
||||
|
||||
// assert response
|
||||
assert.NotNil(t, out) // ensure out variable is used
|
||||
assert.Equal(t, "value", string(out.Blob))
|
||||
|
||||
}
|
||||
|
||||
func TestOutputService3ProtocolTestListsCase1(t *testing.T) {
|
||||
svc := NewOutputService3ProtocolTest(nil)
|
||||
|
||||
buf := bytes.NewReader([]byte("<OperationNameResponse><ListMember><member>abc</member><member>123</member></ListMember><RequestId>requestid</RequestId></OperationNameResponse>"))
|
||||
req, out := svc.OutputService3TestCaseOperation1Request(nil)
|
||||
req.HTTPResponse = &http.Response{StatusCode: 200, Body: ioutil.NopCloser(buf), Header: http.Header{}}
|
||||
|
||||
// set headers
|
||||
|
||||
// unmarshal response
|
||||
ec2query.UnmarshalMeta(req)
|
||||
ec2query.Unmarshal(req)
|
||||
assert.NoError(t, req.Error)
|
||||
|
||||
// assert response
|
||||
assert.NotNil(t, out) // ensure out variable is used
|
||||
assert.Equal(t, "abc", *out.ListMember[0])
|
||||
assert.Equal(t, "123", *out.ListMember[1])
|
||||
|
||||
}
|
||||
|
||||
func TestOutputService4ProtocolTestListWithCustomMemberNameCase1(t *testing.T) {
|
||||
svc := NewOutputService4ProtocolTest(nil)
|
||||
|
||||
buf := bytes.NewReader([]byte("<OperationNameResponse><ListMember><item>abc</item><item>123</item></ListMember><RequestId>requestid</RequestId></OperationNameResponse>"))
|
||||
req, out := svc.OutputService4TestCaseOperation1Request(nil)
|
||||
req.HTTPResponse = &http.Response{StatusCode: 200, Body: ioutil.NopCloser(buf), Header: http.Header{}}
|
||||
|
||||
// set headers
|
||||
|
||||
// unmarshal response
|
||||
ec2query.UnmarshalMeta(req)
|
||||
ec2query.Unmarshal(req)
|
||||
assert.NoError(t, req.Error)
|
||||
|
||||
// assert response
|
||||
assert.NotNil(t, out) // ensure out variable is used
|
||||
assert.Equal(t, "abc", *out.ListMember[0])
|
||||
assert.Equal(t, "123", *out.ListMember[1])
|
||||
|
||||
}
|
||||
|
||||
func TestOutputService5ProtocolTestFlattenedListCase1(t *testing.T) {
|
||||
svc := NewOutputService5ProtocolTest(nil)
|
||||
|
||||
buf := bytes.NewReader([]byte("<OperationNameResponse><ListMember>abc</ListMember><ListMember>123</ListMember><RequestId>requestid</RequestId></OperationNameResponse>"))
|
||||
req, out := svc.OutputService5TestCaseOperation1Request(nil)
|
||||
req.HTTPResponse = &http.Response{StatusCode: 200, Body: ioutil.NopCloser(buf), Header: http.Header{}}
|
||||
|
||||
// set headers
|
||||
|
||||
// unmarshal response
|
||||
ec2query.UnmarshalMeta(req)
|
||||
ec2query.Unmarshal(req)
|
||||
assert.NoError(t, req.Error)
|
||||
|
||||
// assert response
|
||||
assert.NotNil(t, out) // ensure out variable is used
|
||||
assert.Equal(t, "abc", *out.ListMember[0])
|
||||
assert.Equal(t, "123", *out.ListMember[1])
|
||||
|
||||
}
|
||||
|
||||
func TestOutputService6ProtocolTestNormalMapCase1(t *testing.T) {
|
||||
svc := NewOutputService6ProtocolTest(nil)
|
||||
|
||||
buf := bytes.NewReader([]byte("<OperationNameResponse><Map><entry><key>qux</key><value><foo>bar</foo></value></entry><entry><key>baz</key><value><foo>bam</foo></value></entry></Map><RequestId>requestid</RequestId></OperationNameResponse>"))
|
||||
req, out := svc.OutputService6TestCaseOperation1Request(nil)
|
||||
req.HTTPResponse = &http.Response{StatusCode: 200, Body: ioutil.NopCloser(buf), Header: http.Header{}}
|
||||
|
||||
// set headers
|
||||
|
||||
// unmarshal response
|
||||
ec2query.UnmarshalMeta(req)
|
||||
ec2query.Unmarshal(req)
|
||||
assert.NoError(t, req.Error)
|
||||
|
||||
// assert response
|
||||
assert.NotNil(t, out) // ensure out variable is used
|
||||
assert.Equal(t, "bam", *out.Map["baz"].Foo)
|
||||
assert.Equal(t, "bar", *out.Map["qux"].Foo)
|
||||
|
||||
}
|
||||
|
||||
func TestOutputService7ProtocolTestFlattenedMapCase1(t *testing.T) {
|
||||
svc := NewOutputService7ProtocolTest(nil)
|
||||
|
||||
buf := bytes.NewReader([]byte("<OperationNameResponse><Map><key>qux</key><value>bar</value></Map><Map><key>baz</key><value>bam</value></Map><RequestId>requestid</RequestId></OperationNameResponse>"))
|
||||
req, out := svc.OutputService7TestCaseOperation1Request(nil)
|
||||
req.HTTPResponse = &http.Response{StatusCode: 200, Body: ioutil.NopCloser(buf), Header: http.Header{}}
|
||||
|
||||
// set headers
|
||||
|
||||
// unmarshal response
|
||||
ec2query.UnmarshalMeta(req)
|
||||
ec2query.Unmarshal(req)
|
||||
assert.NoError(t, req.Error)
|
||||
|
||||
// assert response
|
||||
assert.NotNil(t, out) // ensure out variable is used
|
||||
assert.Equal(t, "bam", *out.Map["baz"])
|
||||
assert.Equal(t, "bar", *out.Map["qux"])
|
||||
|
||||
}
|
||||
|
||||
func TestOutputService8ProtocolTestNamedMapCase1(t *testing.T) {
|
||||
svc := NewOutputService8ProtocolTest(nil)
|
||||
|
||||
buf := bytes.NewReader([]byte("<OperationNameResponse><Map><foo>qux</foo><bar>bar</bar></Map><Map><foo>baz</foo><bar>bam</bar></Map><RequestId>requestid</RequestId></OperationNameResponse>"))
|
||||
req, out := svc.OutputService8TestCaseOperation1Request(nil)
|
||||
req.HTTPResponse = &http.Response{StatusCode: 200, Body: ioutil.NopCloser(buf), Header: http.Header{}}
|
||||
|
||||
// set headers
|
||||
|
||||
// unmarshal response
|
||||
ec2query.UnmarshalMeta(req)
|
||||
ec2query.Unmarshal(req)
|
||||
assert.NoError(t, req.Error)
|
||||
|
||||
// assert response
|
||||
assert.NotNil(t, out) // ensure out variable is used
|
||||
assert.Equal(t, "bam", *out.Map["baz"])
|
||||
assert.Equal(t, "bar", *out.Map["qux"])
|
||||
|
||||
}
|
||||
33
Godeps/_workspace/src/github.com/aws/aws-sdk-go/internal/protocol/query/build.go
generated
vendored
Normal file
33
Godeps/_workspace/src/github.com/aws/aws-sdk-go/internal/protocol/query/build.go
generated
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
// Package query provides serialisation of AWS query requests, and responses.
|
||||
package query
|
||||
|
||||
//go:generate go run ../../fixtures/protocol/generate.go ../../fixtures/protocol/input/query.json build_test.go
|
||||
|
||||
import (
|
||||
"net/url"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/aws/awserr"
|
||||
"github.com/aws/aws-sdk-go/internal/protocol/query/queryutil"
|
||||
)
|
||||
|
||||
// Build builds a request for an AWS Query service.
|
||||
func Build(r *aws.Request) {
|
||||
body := url.Values{
|
||||
"Action": {r.Operation.Name},
|
||||
"Version": {r.Service.APIVersion},
|
||||
}
|
||||
if err := queryutil.Parse(body, r.Params, false); err != nil {
|
||||
r.Error = awserr.New("SerializationError", "failed encoding Query request", err)
|
||||
return
|
||||
}
|
||||
|
||||
if r.ExpireTime == 0 {
|
||||
r.HTTPRequest.Method = "POST"
|
||||
r.HTTPRequest.Header.Set("Content-Type", "application/x-www-form-urlencoded; charset=utf-8")
|
||||
r.SetBufferBody([]byte(body.Encode()))
|
||||
} else { // This is a pre-signed request
|
||||
r.HTTPRequest.Method = "GET"
|
||||
r.HTTPRequest.URL.RawQuery = body.Encode()
|
||||
}
|
||||
}
|
||||
1482
Godeps/_workspace/src/github.com/aws/aws-sdk-go/internal/protocol/query/build_test.go
generated
vendored
Normal file
1482
Godeps/_workspace/src/github.com/aws/aws-sdk-go/internal/protocol/query/build_test.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
223
Godeps/_workspace/src/github.com/aws/aws-sdk-go/internal/protocol/query/queryutil/queryutil.go
generated
vendored
Normal file
223
Godeps/_workspace/src/github.com/aws/aws-sdk-go/internal/protocol/query/queryutil/queryutil.go
generated
vendored
Normal file
@@ -0,0 +1,223 @@
|
||||
package queryutil
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"reflect"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Parse parses an object i and fills a url.Values object. The isEC2 flag
|
||||
// indicates if this is the EC2 Query sub-protocol.
|
||||
func Parse(body url.Values, i interface{}, isEC2 bool) error {
|
||||
q := queryParser{isEC2: isEC2}
|
||||
return q.parseValue(body, reflect.ValueOf(i), "", "")
|
||||
}
|
||||
|
||||
func elemOf(value reflect.Value) reflect.Value {
|
||||
for value.Kind() == reflect.Ptr {
|
||||
value = value.Elem()
|
||||
}
|
||||
return value
|
||||
}
|
||||
|
||||
type queryParser struct {
|
||||
isEC2 bool
|
||||
}
|
||||
|
||||
func (q *queryParser) parseValue(v url.Values, value reflect.Value, prefix string, tag reflect.StructTag) error {
|
||||
value = elemOf(value)
|
||||
|
||||
// no need to handle zero values
|
||||
if !value.IsValid() {
|
||||
return nil
|
||||
}
|
||||
|
||||
t := tag.Get("type")
|
||||
if t == "" {
|
||||
switch value.Kind() {
|
||||
case reflect.Struct:
|
||||
t = "structure"
|
||||
case reflect.Slice:
|
||||
t = "list"
|
||||
case reflect.Map:
|
||||
t = "map"
|
||||
}
|
||||
}
|
||||
|
||||
switch t {
|
||||
case "structure":
|
||||
return q.parseStruct(v, value, prefix)
|
||||
case "list":
|
||||
return q.parseList(v, value, prefix, tag)
|
||||
case "map":
|
||||
return q.parseMap(v, value, prefix, tag)
|
||||
default:
|
||||
return q.parseScalar(v, value, prefix, tag)
|
||||
}
|
||||
}
|
||||
|
||||
func (q *queryParser) parseStruct(v url.Values, value reflect.Value, prefix string) error {
|
||||
if !value.IsValid() {
|
||||
return nil
|
||||
}
|
||||
|
||||
t := value.Type()
|
||||
for i := 0; i < value.NumField(); i++ {
|
||||
if c := t.Field(i).Name[0:1]; strings.ToLower(c) == c {
|
||||
continue // ignore unexported fields
|
||||
}
|
||||
|
||||
value := elemOf(value.Field(i))
|
||||
field := t.Field(i)
|
||||
var name string
|
||||
|
||||
if q.isEC2 {
|
||||
name = field.Tag.Get("queryName")
|
||||
}
|
||||
if name == "" {
|
||||
if field.Tag.Get("flattened") != "" && field.Tag.Get("locationNameList") != "" {
|
||||
name = field.Tag.Get("locationNameList")
|
||||
} else if locName := field.Tag.Get("locationName"); locName != "" {
|
||||
name = locName
|
||||
}
|
||||
if name != "" && q.isEC2 {
|
||||
name = strings.ToUpper(name[0:1]) + name[1:]
|
||||
}
|
||||
}
|
||||
if name == "" {
|
||||
name = field.Name
|
||||
}
|
||||
|
||||
if prefix != "" {
|
||||
name = prefix + "." + name
|
||||
}
|
||||
|
||||
if err := q.parseValue(v, value, name, field.Tag); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (q *queryParser) parseList(v url.Values, value reflect.Value, prefix string, tag reflect.StructTag) error {
|
||||
// If it's empty, generate an empty value
|
||||
if !value.IsNil() && value.Len() == 0 {
|
||||
v.Set(prefix, "")
|
||||
return nil
|
||||
}
|
||||
|
||||
// check for unflattened list member
|
||||
if !q.isEC2 && tag.Get("flattened") == "" {
|
||||
prefix += ".member"
|
||||
}
|
||||
|
||||
for i := 0; i < value.Len(); i++ {
|
||||
slicePrefix := prefix
|
||||
if slicePrefix == "" {
|
||||
slicePrefix = strconv.Itoa(i + 1)
|
||||
} else {
|
||||
slicePrefix = slicePrefix + "." + strconv.Itoa(i+1)
|
||||
}
|
||||
if err := q.parseValue(v, value.Index(i), slicePrefix, ""); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (q *queryParser) parseMap(v url.Values, value reflect.Value, prefix string, tag reflect.StructTag) error {
|
||||
// If it's empty, generate an empty value
|
||||
if !value.IsNil() && value.Len() == 0 {
|
||||
v.Set(prefix, "")
|
||||
return nil
|
||||
}
|
||||
|
||||
// check for unflattened list member
|
||||
if !q.isEC2 && tag.Get("flattened") == "" {
|
||||
prefix += ".entry"
|
||||
}
|
||||
|
||||
// sort keys for improved serialization consistency.
|
||||
// this is not strictly necessary for protocol support.
|
||||
mapKeyValues := value.MapKeys()
|
||||
mapKeys := map[string]reflect.Value{}
|
||||
mapKeyNames := make([]string, len(mapKeyValues))
|
||||
for i, mapKey := range mapKeyValues {
|
||||
name := mapKey.String()
|
||||
mapKeys[name] = mapKey
|
||||
mapKeyNames[i] = name
|
||||
}
|
||||
sort.Strings(mapKeyNames)
|
||||
|
||||
for i, mapKeyName := range mapKeyNames {
|
||||
mapKey := mapKeys[mapKeyName]
|
||||
mapValue := value.MapIndex(mapKey)
|
||||
|
||||
kname := tag.Get("locationNameKey")
|
||||
if kname == "" {
|
||||
kname = "key"
|
||||
}
|
||||
vname := tag.Get("locationNameValue")
|
||||
if vname == "" {
|
||||
vname = "value"
|
||||
}
|
||||
|
||||
// serialize key
|
||||
var keyName string
|
||||
if prefix == "" {
|
||||
keyName = strconv.Itoa(i+1) + "." + kname
|
||||
} else {
|
||||
keyName = prefix + "." + strconv.Itoa(i+1) + "." + kname
|
||||
}
|
||||
|
||||
if err := q.parseValue(v, mapKey, keyName, ""); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// serialize value
|
||||
var valueName string
|
||||
if prefix == "" {
|
||||
valueName = strconv.Itoa(i+1) + "." + vname
|
||||
} else {
|
||||
valueName = prefix + "." + strconv.Itoa(i+1) + "." + vname
|
||||
}
|
||||
|
||||
if err := q.parseValue(v, mapValue, valueName, ""); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (q *queryParser) parseScalar(v url.Values, r reflect.Value, name string, tag reflect.StructTag) error {
|
||||
switch value := r.Interface().(type) {
|
||||
case string:
|
||||
v.Set(name, value)
|
||||
case []byte:
|
||||
if !r.IsNil() {
|
||||
v.Set(name, base64.StdEncoding.EncodeToString(value))
|
||||
}
|
||||
case bool:
|
||||
v.Set(name, strconv.FormatBool(value))
|
||||
case int64:
|
||||
v.Set(name, strconv.FormatInt(value, 10))
|
||||
case int:
|
||||
v.Set(name, strconv.Itoa(value))
|
||||
case float64:
|
||||
v.Set(name, strconv.FormatFloat(value, 'f', -1, 64))
|
||||
case float32:
|
||||
v.Set(name, strconv.FormatFloat(float64(value), 'f', -1, 32))
|
||||
case time.Time:
|
||||
const ISO8601UTC = "2006-01-02T15:04:05Z"
|
||||
v.Set(name, value.UTC().Format(ISO8601UTC))
|
||||
default:
|
||||
return fmt.Errorf("unsupported value for param %s: %v (%s)", name, r.Interface(), r.Type().Name())
|
||||
}
|
||||
return nil
|
||||
}
|
||||
29
Godeps/_workspace/src/github.com/aws/aws-sdk-go/internal/protocol/query/unmarshal.go
generated
vendored
Normal file
29
Godeps/_workspace/src/github.com/aws/aws-sdk-go/internal/protocol/query/unmarshal.go
generated
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
package query
|
||||
|
||||
//go:generate go run ../../fixtures/protocol/generate.go ../../fixtures/protocol/output/query.json unmarshal_test.go
|
||||
|
||||
import (
|
||||
"encoding/xml"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/aws/awserr"
|
||||
"github.com/aws/aws-sdk-go/internal/protocol/xml/xmlutil"
|
||||
)
|
||||
|
||||
// Unmarshal unmarshals a response for an AWS Query service.
|
||||
func Unmarshal(r *aws.Request) {
|
||||
defer r.HTTPResponse.Body.Close()
|
||||
if r.DataFilled() {
|
||||
decoder := xml.NewDecoder(r.HTTPResponse.Body)
|
||||
err := xmlutil.UnmarshalXML(r.Data, decoder, r.Operation.Name+"Result")
|
||||
if err != nil {
|
||||
r.Error = awserr.New("SerializationError", "failed decoding Query response", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// UnmarshalMeta unmarshals header response values for an AWS Query service.
|
||||
func UnmarshalMeta(r *aws.Request) {
|
||||
// TODO implement unmarshaling of request IDs
|
||||
}
|
||||
33
Godeps/_workspace/src/github.com/aws/aws-sdk-go/internal/protocol/query/unmarshal_error.go
generated
vendored
Normal file
33
Godeps/_workspace/src/github.com/aws/aws-sdk-go/internal/protocol/query/unmarshal_error.go
generated
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
package query
|
||||
|
||||
import (
|
||||
"encoding/xml"
|
||||
"io"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/aws/awserr"
|
||||
)
|
||||
|
||||
type xmlErrorResponse struct {
|
||||
XMLName xml.Name `xml:"ErrorResponse"`
|
||||
Code string `xml:"Error>Code"`
|
||||
Message string `xml:"Error>Message"`
|
||||
RequestID string `xml:"RequestId"`
|
||||
}
|
||||
|
||||
// UnmarshalError unmarshals an error response for an AWS Query service.
|
||||
func UnmarshalError(r *aws.Request) {
|
||||
defer r.HTTPResponse.Body.Close()
|
||||
|
||||
resp := &xmlErrorResponse{}
|
||||
err := xml.NewDecoder(r.HTTPResponse.Body).Decode(resp)
|
||||
if err != nil && err != io.EOF {
|
||||
r.Error = awserr.New("SerializationError", "failed to decode query XML error response", err)
|
||||
} else {
|
||||
r.Error = awserr.NewRequestFailure(
|
||||
awserr.New(resp.Code, resp.Message, nil),
|
||||
r.HTTPResponse.StatusCode,
|
||||
resp.RequestID,
|
||||
)
|
||||
}
|
||||
}
|
||||
1418
Godeps/_workspace/src/github.com/aws/aws-sdk-go/internal/protocol/query/unmarshal_test.go
generated
vendored
Normal file
1418
Godeps/_workspace/src/github.com/aws/aws-sdk-go/internal/protocol/query/unmarshal_test.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
217
Godeps/_workspace/src/github.com/aws/aws-sdk-go/internal/protocol/rest/build.go
generated
vendored
Normal file
217
Godeps/_workspace/src/github.com/aws/aws-sdk-go/internal/protocol/rest/build.go
generated
vendored
Normal file
@@ -0,0 +1,217 @@
|
||||
// Package rest provides RESTful serialisation of AWS requests and responses.
|
||||
package rest
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/url"
|
||||
"path"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/aws/awserr"
|
||||
)
|
||||
|
||||
// RFC822 returns an RFC822 formatted timestamp for AWS protocols
|
||||
const RFC822 = "Mon, 2 Jan 2006 15:04:05 GMT"
|
||||
|
||||
// Whether the byte value can be sent without escaping in AWS URLs
|
||||
var noEscape [256]bool
|
||||
|
||||
func init() {
|
||||
for i := 0; i < len(noEscape); i++ {
|
||||
// AWS expects every character except these to be escaped
|
||||
noEscape[i] = (i >= 'A' && i <= 'Z') ||
|
||||
(i >= 'a' && i <= 'z') ||
|
||||
(i >= '0' && i <= '9') ||
|
||||
i == '-' ||
|
||||
i == '.' ||
|
||||
i == '_' ||
|
||||
i == '~'
|
||||
}
|
||||
}
|
||||
|
||||
// Build builds the REST component of a service request.
|
||||
func Build(r *aws.Request) {
|
||||
if r.ParamsFilled() {
|
||||
v := reflect.ValueOf(r.Params).Elem()
|
||||
buildLocationElements(r, v)
|
||||
buildBody(r, v)
|
||||
}
|
||||
}
|
||||
|
||||
func buildLocationElements(r *aws.Request, v reflect.Value) {
|
||||
query := r.HTTPRequest.URL.Query()
|
||||
|
||||
for i := 0; i < v.NumField(); i++ {
|
||||
m := v.Field(i)
|
||||
if n := v.Type().Field(i).Name; n[0:1] == strings.ToLower(n[0:1]) {
|
||||
continue
|
||||
}
|
||||
|
||||
if m.IsValid() {
|
||||
field := v.Type().Field(i)
|
||||
name := field.Tag.Get("locationName")
|
||||
if name == "" {
|
||||
name = field.Name
|
||||
}
|
||||
if m.Kind() == reflect.Ptr {
|
||||
m = m.Elem()
|
||||
}
|
||||
if !m.IsValid() {
|
||||
continue
|
||||
}
|
||||
|
||||
switch field.Tag.Get("location") {
|
||||
case "headers": // header maps
|
||||
buildHeaderMap(r, m, field.Tag.Get("locationName"))
|
||||
case "header":
|
||||
buildHeader(r, m, name)
|
||||
case "uri":
|
||||
buildURI(r, m, name)
|
||||
case "querystring":
|
||||
buildQueryString(r, m, name, query)
|
||||
}
|
||||
}
|
||||
if r.Error != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
r.HTTPRequest.URL.RawQuery = query.Encode()
|
||||
updatePath(r.HTTPRequest.URL, r.HTTPRequest.URL.Path)
|
||||
}
|
||||
|
||||
func buildBody(r *aws.Request, v reflect.Value) {
|
||||
if field, ok := v.Type().FieldByName("SDKShapeTraits"); ok {
|
||||
if payloadName := field.Tag.Get("payload"); payloadName != "" {
|
||||
pfield, _ := v.Type().FieldByName(payloadName)
|
||||
if ptag := pfield.Tag.Get("type"); ptag != "" && ptag != "structure" {
|
||||
payload := reflect.Indirect(v.FieldByName(payloadName))
|
||||
if payload.IsValid() && payload.Interface() != nil {
|
||||
switch reader := payload.Interface().(type) {
|
||||
case io.ReadSeeker:
|
||||
r.SetReaderBody(reader)
|
||||
case []byte:
|
||||
r.SetBufferBody(reader)
|
||||
case string:
|
||||
r.SetStringBody(reader)
|
||||
default:
|
||||
r.Error = awserr.New("SerializationError",
|
||||
"failed to encode REST request",
|
||||
fmt.Errorf("unknown payload type %s", payload.Type()))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func buildHeader(r *aws.Request, v reflect.Value, name string) {
|
||||
str, err := convertType(v)
|
||||
if err != nil {
|
||||
r.Error = awserr.New("SerializationError", "failed to encode REST request", err)
|
||||
} else if str != nil {
|
||||
r.HTTPRequest.Header.Add(name, *str)
|
||||
}
|
||||
}
|
||||
|
||||
func buildHeaderMap(r *aws.Request, v reflect.Value, prefix string) {
|
||||
for _, key := range v.MapKeys() {
|
||||
str, err := convertType(v.MapIndex(key))
|
||||
if err != nil {
|
||||
r.Error = awserr.New("SerializationError", "failed to encode REST request", err)
|
||||
} else if str != nil {
|
||||
r.HTTPRequest.Header.Add(prefix+key.String(), *str)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func buildURI(r *aws.Request, v reflect.Value, name string) {
|
||||
value, err := convertType(v)
|
||||
if err != nil {
|
||||
r.Error = awserr.New("SerializationError", "failed to encode REST request", err)
|
||||
} else if value != nil {
|
||||
uri := r.HTTPRequest.URL.Path
|
||||
uri = strings.Replace(uri, "{"+name+"}", EscapePath(*value, true), -1)
|
||||
uri = strings.Replace(uri, "{"+name+"+}", EscapePath(*value, false), -1)
|
||||
r.HTTPRequest.URL.Path = uri
|
||||
}
|
||||
}
|
||||
|
||||
func buildQueryString(r *aws.Request, v reflect.Value, name string, query url.Values) {
|
||||
str, err := convertType(v)
|
||||
if err != nil {
|
||||
r.Error = awserr.New("SerializationError", "failed to encode REST request", err)
|
||||
} else if str != nil {
|
||||
query.Set(name, *str)
|
||||
}
|
||||
}
|
||||
|
||||
func updatePath(url *url.URL, urlPath string) {
|
||||
scheme, query := url.Scheme, url.RawQuery
|
||||
|
||||
hasSlash := strings.HasSuffix(urlPath, "/")
|
||||
|
||||
// clean up path
|
||||
urlPath = path.Clean(urlPath)
|
||||
if hasSlash && !strings.HasSuffix(urlPath, "/") {
|
||||
urlPath += "/"
|
||||
}
|
||||
|
||||
// get formatted URL minus scheme so we can build this into Opaque
|
||||
url.Scheme, url.Path, url.RawQuery = "", "", ""
|
||||
s := url.String()
|
||||
url.Scheme = scheme
|
||||
url.RawQuery = query
|
||||
|
||||
// build opaque URI
|
||||
url.Opaque = s + urlPath
|
||||
}
|
||||
|
||||
// EscapePath escapes part of a URL path in Amazon style
|
||||
func EscapePath(path string, encodeSep bool) string {
|
||||
var buf bytes.Buffer
|
||||
for i := 0; i < len(path); i++ {
|
||||
c := path[i]
|
||||
if noEscape[c] || (c == '/' && !encodeSep) {
|
||||
buf.WriteByte(c)
|
||||
} else {
|
||||
buf.WriteByte('%')
|
||||
buf.WriteString(strings.ToUpper(strconv.FormatUint(uint64(c), 16)))
|
||||
}
|
||||
}
|
||||
return buf.String()
|
||||
}
|
||||
|
||||
func convertType(v reflect.Value) (*string, error) {
|
||||
v = reflect.Indirect(v)
|
||||
if !v.IsValid() {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
var str string
|
||||
switch value := v.Interface().(type) {
|
||||
case string:
|
||||
str = value
|
||||
case []byte:
|
||||
str = base64.StdEncoding.EncodeToString(value)
|
||||
case bool:
|
||||
str = strconv.FormatBool(value)
|
||||
case int64:
|
||||
str = strconv.FormatInt(value, 10)
|
||||
case float64:
|
||||
str = strconv.FormatFloat(value, 'f', -1, 64)
|
||||
case time.Time:
|
||||
str = value.UTC().Format(RFC822)
|
||||
default:
|
||||
err := fmt.Errorf("Unsupported value for param %v (%s)", v.Interface(), v.Type())
|
||||
return nil, err
|
||||
}
|
||||
return &str, nil
|
||||
}
|
||||
45
Godeps/_workspace/src/github.com/aws/aws-sdk-go/internal/protocol/rest/payload.go
generated
vendored
Normal file
45
Godeps/_workspace/src/github.com/aws/aws-sdk-go/internal/protocol/rest/payload.go
generated
vendored
Normal file
@@ -0,0 +1,45 @@
|
||||
package rest
|
||||
|
||||
import "reflect"
|
||||
|
||||
// PayloadMember returns the payload field member of i if there is one, or nil.
|
||||
func PayloadMember(i interface{}) interface{} {
|
||||
if i == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
v := reflect.ValueOf(i).Elem()
|
||||
if !v.IsValid() {
|
||||
return nil
|
||||
}
|
||||
if field, ok := v.Type().FieldByName("SDKShapeTraits"); ok {
|
||||
if payloadName := field.Tag.Get("payload"); payloadName != "" {
|
||||
field, _ := v.Type().FieldByName(payloadName)
|
||||
if field.Tag.Get("type") != "structure" {
|
||||
return nil
|
||||
}
|
||||
|
||||
payload := v.FieldByName(payloadName)
|
||||
if payload.IsValid() || (payload.Kind() == reflect.Ptr && !payload.IsNil()) {
|
||||
return payload.Interface()
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// PayloadType returns the type of a payload field member of i if there is one, or "".
|
||||
func PayloadType(i interface{}) string {
|
||||
v := reflect.Indirect(reflect.ValueOf(i))
|
||||
if !v.IsValid() {
|
||||
return ""
|
||||
}
|
||||
if field, ok := v.Type().FieldByName("SDKShapeTraits"); ok {
|
||||
if payloadName := field.Tag.Get("payload"); payloadName != "" {
|
||||
if member, ok := v.Type().FieldByName(payloadName); ok {
|
||||
return member.Tag.Get("type")
|
||||
}
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user