ffi-hydrogen 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (160) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +13 -0
  3. data/.rspec +3 -0
  4. data/.rubocop.yml +30 -0
  5. data/.travis.yml +10 -0
  6. data/Gemfile +6 -0
  7. data/LICENSE.txt +21 -0
  8. data/README.md +72 -0
  9. data/Rakefile +46 -0
  10. data/bench/both.rb +86 -0
  11. data/bench/encode.rb +57 -0
  12. data/bench/encrypt.rb +80 -0
  13. data/bench/init.rb +5 -0
  14. data/bin/console +14 -0
  15. data/bin/setup +8 -0
  16. data/ffi-hydrogen.gemspec +31 -0
  17. data/lib/ffi/hydrogen.rb +216 -0
  18. data/vendor/.clang-format +2 -0
  19. data/vendor/.gitignore +3 -0
  20. data/vendor/README.md +2 -0
  21. data/vendor/libhydrogen/.clang-format +95 -0
  22. data/vendor/libhydrogen/.gitignore +32 -0
  23. data/vendor/libhydrogen/.travis.yml +22 -0
  24. data/vendor/libhydrogen/LICENSE +18 -0
  25. data/vendor/libhydrogen/Makefile +61 -0
  26. data/vendor/libhydrogen/Makefile.arduino +51 -0
  27. data/vendor/libhydrogen/README.md +29 -0
  28. data/vendor/libhydrogen/hydrogen.c +18 -0
  29. data/vendor/libhydrogen/hydrogen.h +317 -0
  30. data/vendor/libhydrogen/impl/common.h +316 -0
  31. data/vendor/libhydrogen/impl/core.h +220 -0
  32. data/vendor/libhydrogen/impl/gimli-core/portable.h +39 -0
  33. data/vendor/libhydrogen/impl/gimli-core/sse2.h +97 -0
  34. data/vendor/libhydrogen/impl/gimli-core.h +25 -0
  35. data/vendor/libhydrogen/impl/hash.h +138 -0
  36. data/vendor/libhydrogen/impl/hydrogen_p.h +83 -0
  37. data/vendor/libhydrogen/impl/kdf.h +20 -0
  38. data/vendor/libhydrogen/impl/kx.h +441 -0
  39. data/vendor/libhydrogen/impl/pwhash.h +281 -0
  40. data/vendor/libhydrogen/impl/random.h +376 -0
  41. data/vendor/libhydrogen/impl/secretbox.h +236 -0
  42. data/vendor/libhydrogen/impl/sign.h +207 -0
  43. data/vendor/libhydrogen/impl/x25519.h +383 -0
  44. data/vendor/libhydrogen/library.properties +10 -0
  45. data/vendor/libhydrogen/logo.png +0 -0
  46. data/vendor/libhydrogen/tests/tests.c +431 -0
  47. data/vendor/main.c +140 -0
  48. data/vendor/stringencoders/.gitignore +25 -0
  49. data/vendor/stringencoders/.travis.yml +13 -0
  50. data/vendor/stringencoders/AUTHORS +1 -0
  51. data/vendor/stringencoders/COPYING +2 -0
  52. data/vendor/stringencoders/ChangeLog +170 -0
  53. data/vendor/stringencoders/Doxyfile +276 -0
  54. data/vendor/stringencoders/INSTALL +119 -0
  55. data/vendor/stringencoders/LICENSE +22 -0
  56. data/vendor/stringencoders/Makefile.am +3 -0
  57. data/vendor/stringencoders/NEWS +3 -0
  58. data/vendor/stringencoders/README +2 -0
  59. data/vendor/stringencoders/README.md +32 -0
  60. data/vendor/stringencoders/bootstrap.sh +3 -0
  61. data/vendor/stringencoders/configure-gcc-hardened.sh +16 -0
  62. data/vendor/stringencoders/configure.ac +44 -0
  63. data/vendor/stringencoders/doxy/footer.html +34 -0
  64. data/vendor/stringencoders/doxy/header.html +85 -0
  65. data/vendor/stringencoders/indent.sh +9 -0
  66. data/vendor/stringencoders/javascript/base64-speed.html +43 -0
  67. data/vendor/stringencoders/javascript/base64-test.html +209 -0
  68. data/vendor/stringencoders/javascript/base64.html +18 -0
  69. data/vendor/stringencoders/javascript/base64.js +176 -0
  70. data/vendor/stringencoders/javascript/qunit.css +119 -0
  71. data/vendor/stringencoders/javascript/qunit.js +1062 -0
  72. data/vendor/stringencoders/javascript/urlparse-test.html +367 -0
  73. data/vendor/stringencoders/javascript/urlparse.js +328 -0
  74. data/vendor/stringencoders/make-ci.sh +13 -0
  75. data/vendor/stringencoders/makerelease.sh +16 -0
  76. data/vendor/stringencoders/python/b85.py +176 -0
  77. data/vendor/stringencoders/src/Makefile.am +134 -0
  78. data/vendor/stringencoders/src/arraytoc.c +85 -0
  79. data/vendor/stringencoders/src/arraytoc.h +43 -0
  80. data/vendor/stringencoders/src/extern_c_begin.h +3 -0
  81. data/vendor/stringencoders/src/extern_c_end.h +3 -0
  82. data/vendor/stringencoders/src/html_named_entities_generator.py +203 -0
  83. data/vendor/stringencoders/src/modp_ascii.c +159 -0
  84. data/vendor/stringencoders/src/modp_ascii.h +162 -0
  85. data/vendor/stringencoders/src/modp_ascii_data.h +84 -0
  86. data/vendor/stringencoders/src/modp_ascii_gen.c +55 -0
  87. data/vendor/stringencoders/src/modp_b16.c +125 -0
  88. data/vendor/stringencoders/src/modp_b16.h +148 -0
  89. data/vendor/stringencoders/src/modp_b16_data.h +104 -0
  90. data/vendor/stringencoders/src/modp_b16_gen.c +65 -0
  91. data/vendor/stringencoders/src/modp_b2.c +69 -0
  92. data/vendor/stringencoders/src/modp_b2.h +130 -0
  93. data/vendor/stringencoders/src/modp_b2_data.h +44 -0
  94. data/vendor/stringencoders/src/modp_b2_gen.c +36 -0
  95. data/vendor/stringencoders/src/modp_b36.c +108 -0
  96. data/vendor/stringencoders/src/modp_b36.h +170 -0
  97. data/vendor/stringencoders/src/modp_b64.c +254 -0
  98. data/vendor/stringencoders/src/modp_b64.h +236 -0
  99. data/vendor/stringencoders/src/modp_b64_data.h +477 -0
  100. data/vendor/stringencoders/src/modp_b64_gen.c +168 -0
  101. data/vendor/stringencoders/src/modp_b64r.c +254 -0
  102. data/vendor/stringencoders/src/modp_b64r.h +242 -0
  103. data/vendor/stringencoders/src/modp_b64r_data.h +477 -0
  104. data/vendor/stringencoders/src/modp_b64w.c +254 -0
  105. data/vendor/stringencoders/src/modp_b64w.h +231 -0
  106. data/vendor/stringencoders/src/modp_b64w_data.h +477 -0
  107. data/vendor/stringencoders/src/modp_b85.c +109 -0
  108. data/vendor/stringencoders/src/modp_b85.h +171 -0
  109. data/vendor/stringencoders/src/modp_b85_data.h +36 -0
  110. data/vendor/stringencoders/src/modp_b85_gen.c +65 -0
  111. data/vendor/stringencoders/src/modp_bjavascript.c +65 -0
  112. data/vendor/stringencoders/src/modp_bjavascript.h +105 -0
  113. data/vendor/stringencoders/src/modp_bjavascript_data.h +84 -0
  114. data/vendor/stringencoders/src/modp_bjavascript_gen.c +58 -0
  115. data/vendor/stringencoders/src/modp_burl.c +228 -0
  116. data/vendor/stringencoders/src/modp_burl.h +259 -0
  117. data/vendor/stringencoders/src/modp_burl_data.h +136 -0
  118. data/vendor/stringencoders/src/modp_burl_gen.c +121 -0
  119. data/vendor/stringencoders/src/modp_html.c +128 -0
  120. data/vendor/stringencoders/src/modp_html.h +53 -0
  121. data/vendor/stringencoders/src/modp_html_named_entities.h +9910 -0
  122. data/vendor/stringencoders/src/modp_json.c +315 -0
  123. data/vendor/stringencoders/src/modp_json.h +103 -0
  124. data/vendor/stringencoders/src/modp_json_data.h +57 -0
  125. data/vendor/stringencoders/src/modp_json_gen.py +60 -0
  126. data/vendor/stringencoders/src/modp_mainpage.h +120 -0
  127. data/vendor/stringencoders/src/modp_numtoa.c +350 -0
  128. data/vendor/stringencoders/src/modp_numtoa.h +100 -0
  129. data/vendor/stringencoders/src/modp_qsiter.c +76 -0
  130. data/vendor/stringencoders/src/modp_qsiter.h +71 -0
  131. data/vendor/stringencoders/src/modp_stdint.h +43 -0
  132. data/vendor/stringencoders/src/modp_utf8.c +88 -0
  133. data/vendor/stringencoders/src/modp_utf8.h +38 -0
  134. data/vendor/stringencoders/src/modp_xml.c +311 -0
  135. data/vendor/stringencoders/src/modp_xml.h +166 -0
  136. data/vendor/stringencoders/src/stringencoders.pc +10 -0
  137. data/vendor/stringencoders/src/stringencoders.pc.in +10 -0
  138. data/vendor/stringencoders/test/Makefile.am +113 -0
  139. data/vendor/stringencoders/test/apr_base64.c +262 -0
  140. data/vendor/stringencoders/test/apr_base64.h +120 -0
  141. data/vendor/stringencoders/test/cxx_test.cc +482 -0
  142. data/vendor/stringencoders/test/minunit.h +82 -0
  143. data/vendor/stringencoders/test/modp_ascii_test.c +281 -0
  144. data/vendor/stringencoders/test/modp_b16_test.c +288 -0
  145. data/vendor/stringencoders/test/modp_b2_test.c +250 -0
  146. data/vendor/stringencoders/test/modp_b64_test.c +266 -0
  147. data/vendor/stringencoders/test/modp_b85_test.c +130 -0
  148. data/vendor/stringencoders/test/modp_bjavascript_test.c +137 -0
  149. data/vendor/stringencoders/test/modp_burl_test.c +423 -0
  150. data/vendor/stringencoders/test/modp_html_test.c +296 -0
  151. data/vendor/stringencoders/test/modp_json_test.c +336 -0
  152. data/vendor/stringencoders/test/modp_numtoa_test.c +545 -0
  153. data/vendor/stringencoders/test/modp_qsiter_test.c +280 -0
  154. data/vendor/stringencoders/test/modp_utf8_test.c +188 -0
  155. data/vendor/stringencoders/test/modp_xml_test.c +339 -0
  156. data/vendor/stringencoders/test/speedtest.c +241 -0
  157. data/vendor/stringencoders/test/speedtest_ascii.c +345 -0
  158. data/vendor/stringencoders/test/speedtest_msg.c +78 -0
  159. data/vendor/stringencoders/test/speedtest_numtoa.c +276 -0
  160. metadata +314 -0
@@ -0,0 +1,367 @@
1
+ <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
2
+ "http://www.w3.org/TR/html4/loose.dtd">
3
+ <html>
4
+ <head>
5
+ <title>urlparse test</title>
6
+ <script src="http://code.jquery.com/jquery-latest.js"></script>
7
+ <script src="urlparse.js"></script>
8
+ <link rel="stylesheet" href="qunit.css" type="text/css" media="screen" />
9
+ <script type="text/javascript" src="qunit.js"></script>
10
+ <script type="text/javascript">
11
+
12
+ $(document).ready(function(){
13
+
14
+ var urlsplit = urlparse.urlsplit;
15
+ var urlunsplit = urlparse.urlunsplit;
16
+ var urljoin = urlparse.urljoin;
17
+ var urldefrag = urlparse.urldefrag;
18
+ var urlnormalize = urlparse.urlnormalize;
19
+ var normalizepath = urlparse.normalizepath;
20
+
21
+ test('urlsplit-full', function() {
22
+ var parts = urlsplit('http://www.abc.com:80/def/ghi?query#frag');
23
+ equals(parts.scheme, 'http');
24
+ equals(parts.netloc, 'www.abc.com:80');
25
+ equals(parts.hostname, 'www.abc.com');
26
+ equals(parts.port, 80);
27
+ equals(typeof parts.port, 'number', 'port is a number, not string');
28
+ equals(parts.path, '/def/ghi');
29
+ equals(parts.query, 'query');
30
+ equals(parts.fragment, 'frag');
31
+ equals(urlunsplit(parts), 'http://www.abc.com:80/def/ghi?query#frag');
32
+ });
33
+
34
+ // all caps to see what, if any normaization is done
35
+ test('urlsplit-full-allcaps', function() {
36
+ var parts = urlsplit('HTTP://WWW.ABC.COM:80/DEF/GHI?QUERY#FRAG');
37
+ equals(parts.scheme, 'http');
38
+ equals(parts.netloc, 'WWW.ABC.COM:80');
39
+ equals(parts.hostname, 'www.abc.com');
40
+ equals(parts.port, 80);
41
+ equals(parts.path, '/DEF/GHI');
42
+ equals(parts.query, 'QUERY');
43
+ equals(parts.fragment, 'FRAG');
44
+ equals(urlunsplit(parts), 'http://WWW.ABC.COM:80/DEF/GHI?QUERY#FRAG');
45
+ });
46
+
47
+ test('urlsplit-full-emptyfrag', function() {
48
+ var parts = urlsplit('http://www.abc.com:80/def/ghi?query#');
49
+ equals(parts.scheme, 'http');
50
+ equals(parts.netloc, 'www.abc.com:80');
51
+ equals(parts.hostname, 'www.abc.com');
52
+ equals(parts.port, 80);
53
+ equals(parts.path, '/def/ghi');
54
+ equals(parts.query, 'query');
55
+ equals(parts.fragment, '');
56
+ equals(urlunsplit(parts), 'http://www.abc.com:80/def/ghi?query');
57
+ });
58
+
59
+ test('urlsplit-path-empty-query', function() {
60
+ var parts = urlsplit('http://www.abc.com:80/def/ghi?');
61
+ equals(parts.scheme, 'http');
62
+ equals(parts.netloc, 'www.abc.com:80');
63
+ equals(parts.hostname, 'www.abc.com');
64
+ equals(parts.port, 80);
65
+ equals(parts.path, '/def/ghi');
66
+ equals(parts.query, '');
67
+ equals(parts.fragment, '');
68
+ equals(urlunsplit(parts), 'http://www.abc.com:80/def/ghi');
69
+ });
70
+
71
+ test('urlsplit-full-nofrag', function() {
72
+ var parts = urlsplit('http://www.abc.com:80/def/ghi?query');
73
+ equals(parts.scheme, 'http');
74
+ equals(parts.netloc, 'www.abc.com:80');
75
+ equals(parts.hostname, 'www.abc.com');
76
+ equals(parts.port, 80);
77
+ equals(parts.path, '/def/ghi');
78
+ equals(parts.query, 'query');
79
+ equals(parts.fragment, '');
80
+ equals(urlunsplit(parts), 'http://www.abc.com:80/def/ghi?query');
81
+ });
82
+
83
+ test('urlsplit-path', function() {
84
+ var parts = urlsplit('http://www.abc.com:80/def/ghi');
85
+ equals(parts.scheme, 'http');
86
+ equals(parts.netloc, 'www.abc.com:80');
87
+ equals(parts.hostname, 'www.abc.com');
88
+ equals(parts.port, 80);
89
+ equals(parts.path, '/def/ghi');
90
+ equals(parts.query, '');
91
+ equals(parts.fragment, '');
92
+ equals(urlunsplit(parts), 'http://www.abc.com:80/def/ghi');
93
+ });
94
+
95
+ test('urlsplit-path-frag', function() {
96
+ var parts = urlsplit('http://www.abc.com:80/def/ghi#frag');
97
+ equals(parts.scheme, 'http');
98
+ equals(parts.netloc, 'www.abc.com:80');
99
+ equals(parts.hostname, 'www.abc.com');
100
+ equals(parts.port, 80);
101
+ equals(parts.path, '/def/ghi');
102
+ equals(parts.query, '');
103
+ equals(parts.fragment, 'frag');
104
+ equals(urlunsplit(parts), 'http://www.abc.com:80/def/ghi#frag');
105
+ });
106
+
107
+ test('urlsplit-nopath-frag', function() {
108
+ var parts = urlsplit('http://www.abc.com:80/#frag');
109
+ equals(parts.scheme, 'http');
110
+ equals(parts.netloc, 'www.abc.com:80');
111
+ equals(parts.hostname, 'www.abc.com');
112
+ equals(parts.port, 80);
113
+ equals(parts.path, '/');
114
+ equals(parts.query, '');
115
+ equals(parts.fragment, 'frag');
116
+ equals(urlunsplit(parts), 'http://www.abc.com:80/#frag');
117
+ });
118
+
119
+ test('urlsplit-nopath-query', function() {
120
+ var parts = urlsplit('http://www.abc.com:80/?query');
121
+ equals(parts.scheme, 'http');
122
+ equals(parts.netloc, 'www.abc.com:80');
123
+ equals(parts.hostname, 'www.abc.com');
124
+ equals(parts.port, 80);
125
+ equals(parts.path, '/');
126
+ equals(parts.query, 'query');
127
+ equals(parts.fragment, '');
128
+ equals(urlunsplit(parts), 'http://www.abc.com:80/?query');
129
+ });
130
+
131
+ test('urlsplit-nopath-1', function() {
132
+ var parts = urlsplit('http://www.abc.com:80/');
133
+ equals(parts.scheme, 'http');
134
+ equals(parts.netloc, 'www.abc.com:80');
135
+ equals(parts.hostname, 'www.abc.com');
136
+ equals(parts.port, 80);
137
+ equals(parts.path, '/');
138
+ equals(parts.query, '');
139
+ equals(parts.fragment, '');
140
+ equals(urlunsplit(parts), 'http://www.abc.com:80/');
141
+ });
142
+
143
+ test('urlsplit-nopath-2', function() {
144
+ var parts = urlsplit('http://www.abc.com:80');
145
+ equals(parts.scheme, 'http');
146
+ equals(parts.netloc, 'www.abc.com:80');
147
+ equals(parts.hostname, 'www.abc.com');
148
+ equals(parts.port, 80);
149
+ equals(parts.path, '');
150
+ equals(parts.query, '');
151
+ equals(parts.fragment, '');
152
+ equals(urlunsplit(parts), 'http://www.abc.com:80');
153
+ });
154
+
155
+ test('urlsplit-nopath-3', function() {
156
+ var parts = urlsplit('http://www.abc.com');
157
+ equals(parts.scheme, 'http');
158
+ equals(parts.netloc, 'www.abc.com');
159
+ equals(parts.path, '');
160
+ equals(parts.query, '');
161
+ equals(parts.fragment, '');
162
+ equals(urlunsplit(parts), 'http://www.abc.com');
163
+ });
164
+
165
+ test('urlsplit-nopath-query', function() {
166
+ var parts = urlsplit('http://www.abc.com?query');
167
+ equals(parts.scheme, 'http');
168
+ equals(parts.netloc, 'www.abc.com');
169
+ equals(parts.path, '');
170
+ equals(parts.query, 'query');
171
+ equals(parts.fragment, '');
172
+ equals(urlunsplit(parts), 'http://www.abc.com?query');
173
+ });
174
+
175
+ test('urlsplit-nopath-frag', function() {
176
+ var parts = urlsplit('http://www.abc.com#frag');
177
+ equals(parts.scheme, 'http');
178
+ equals(parts.netloc, 'www.abc.com');
179
+ equals(parts.path, '');
180
+ equals(parts.query, '');
181
+ equals(parts.fragment, 'frag');
182
+ equals(urlunsplit(parts), 'http://www.abc.com#frag');
183
+ });
184
+
185
+ // test to make sure implementation (regexp) will match numbers too
186
+ test('urlsplit-ipaddress', function() {
187
+ var parts = urlsplit('http://127.0.0.1');
188
+ equals(parts.scheme, 'http');
189
+ equals(parts.netloc, '127.0.0.1');
190
+ equals(parts.path, '');
191
+ equals(parts.query, '');
192
+ equals(parts.fragment, '');
193
+ equals(urlunsplit(parts), 'http://127.0.0.1');
194
+ });
195
+
196
+ // test to make sure implementation (regexp) will match numbers too
197
+ test('urlsplit-ipaddress-path', function() {
198
+ var parts = urlsplit('http://127.0.0.1/');
199
+ equals(parts.scheme, 'http');
200
+ equals(parts.netloc, '127.0.0.1');
201
+ equals(parts.path, '/');
202
+ equals(parts.query, '');
203
+ equals(parts.fragment, '');
204
+ equals(urlunsplit(parts), 'http://127.0.0.1/');
205
+ });
206
+
207
+ // make sure single words are ok for host
208
+ test('urlsplit-localhost', function() {
209
+ var parts = urlsplit('http://localhost');
210
+ equals(parts.scheme, 'http');
211
+ equals(parts.netloc, 'localhost');
212
+ equals(parts.path, '');
213
+ equals(parts.query, '');
214
+ equals(parts.fragment, '');
215
+
216
+ equals(urlunsplit(parts), 'http://localhost');
217
+ });
218
+
219
+ // make sure single words are ok for host
220
+ test('urlsplit-localhost-path', function() {
221
+ var parts = urlsplit('http://localhost/');
222
+ equals(parts.scheme, 'http');
223
+ equals(parts.netloc, 'localhost');
224
+ equals(parts.path, '/');
225
+ equals(parts.query, '');
226
+ equals(parts.fragment, '');
227
+
228
+ equals(urlunsplit(parts), 'http://localhost/');
229
+ });
230
+
231
+
232
+ // test bogus all empty case
233
+ test('urlsplit-empty', function() {
234
+ var parts = urlsplit('');
235
+ equals(parts.scheme, '');
236
+ equals(parts.netloc, '');
237
+ equals(parts.path, '');
238
+ equals(parts.query, '');
239
+ equals(parts.fragment, '');
240
+
241
+ equals(urlunsplit(parts), '');
242
+ });
243
+
244
+
245
+ // just making sure the triple slash is ok
246
+ test('urlsplit-file', function() {
247
+ var parts = urlsplit('file:///foo/bar');
248
+ equals(parts.scheme, 'file');
249
+ equals(parts.netloc, '');
250
+ equals(parts.path, '/foo/bar');
251
+ });
252
+
253
+ test('urlsplit-noscheme', function() {
254
+ var parts = urlsplit('//abc.com/foo');
255
+ equals(parts.scheme, '');
256
+ equals(parts.netloc, 'abc.com');
257
+ equals(parts.path, '/foo');
258
+ equals(urlunsplit(parts), '//abc.com/foo');
259
+ });
260
+
261
+ test('url-defaut-scheme1', function() {
262
+ // should ignore the default scheme is the input is fully specified
263
+ var parts = urlsplit('http://www.abc.com/', 'file');
264
+ equals(parts.scheme, 'http');
265
+ equals(urlunsplit(parts), 'http://www.abc.com/');
266
+
267
+ var parts = urlsplit('//abc.com/foo', 'http');
268
+ equals(parts.scheme, 'http');
269
+ equals(parts.netloc, 'abc.com');
270
+ equals(parts.path, '/foo');
271
+ equals(urlunsplit(parts), 'http://abc.com/foo');
272
+
273
+ // this is not that useful
274
+ var parts = urlsplit('/foo', 'http');
275
+ equals(parts.scheme, 'http');
276
+ equals(parts.netloc, '');
277
+ equals(parts.path, '/foo');
278
+ equals(urlunsplit(parts), 'http:///foo');
279
+
280
+ });
281
+
282
+ test('urljoin', function() {
283
+ equals(urljoin('http://abc.com/', 'shows/lost'), 'http://abc.com/shows/lost');
284
+ equals(urljoin('http://abc.com', 'shows/lost'), 'http://abc.com/shows/lost');
285
+ equals(urljoin('http://abc.com', '/shows/lost'), 'http://abc.com/shows/lost');
286
+ equals(urljoin('http://abc.com/', '/shows/lost'), 'http://abc.com/shows/lost');
287
+ equals(urljoin('http://abc.com/', '/shows/./lost'), 'http://abc.com/shows/lost');
288
+ equals(urljoin('http://abc.com/', './shows/lost'), 'http://abc.com/shows/lost');
289
+ equals(urljoin('http://abc.com', './shows/lost'), 'http://abc.com/shows/lost');
290
+ equals(urljoin('http://abc.com/shows/', 'lost'), 'http://abc.com/shows/lost');
291
+ equals(urljoin('http://abc.com/shows/', './lost'), 'http://abc.com/shows/lost');
292
+ equals(urljoin('http://abc.com/shows', './lost'), 'http://abc.com/lost');
293
+
294
+ equals(urljoin('http://abc.com/shows', '/lost'), 'http://abc.com/lost');
295
+
296
+ equals(urljoin('http://abc.com/shows/lost', 'scrubs'), 'http://abc.com/shows/scrubs');
297
+
298
+ equals(urljoin('http://abc.com/shows/lost', '../shop'), 'http://abc.com/shop');
299
+
300
+ // this is behavior of python.
301
+ equals(urljoin('http://abc.com/shows/lost', '../../shop'), 'http://abc.com/../shop');
302
+
303
+ equals(urljoin('http://abc.com/shows/lost', ''), 'http://abc.com/shows/lost');
304
+ equals(urljoin('http://abc.com/shows/./lost', ''), 'http://abc.com/shows/lost');
305
+ equals(urljoin('http://abc.com/shows/../lost', ''), 'http://abc.com/lost');
306
+
307
+ equals(urljoin('http://abc.com/shows/', 'http://nbc.com/'), 'http://nbc.com/');
308
+
309
+ });
310
+
311
+ test('urlnormalize', function() {
312
+ equals(urlnormalize('http://foo.com'), 'http://foo.com/');
313
+ equals(urlnormalize('http://foo.com:80'), 'http://foo.com/');
314
+ equals(urlnormalize('https://foo.com:443'), 'https://foo.com/');
315
+ equals(urlnormalize('https://foo.com:443/foo/.././bar'),'https://foo.com/bar');
316
+ equals(urlnormalize('file:///foo/bar?junk'), 'file:///foo/bar');
317
+ equals(urlnormalize('file:///foo/bar?junk#frag'), 'file:///foo/bar');
318
+ equals(urlnormalize('file:///foo/bar#frag'), 'file:///foo/bar');
319
+ });
320
+
321
+ test('normalizepath', function() {
322
+ equals(normalizepath(''), '/');
323
+ equals(normalizepath('/'), '/');
324
+ equals(normalizepath('/foo'), '/foo');
325
+
326
+ // we assume everything is absolute in this function
327
+ equals(normalizepath('foo'), '/foo');
328
+
329
+ equals(normalizepath('.'), '/');
330
+
331
+ // not sure what the right answer is here
332
+ equals(normalizepath('/.'), '/');
333
+
334
+ equals(normalizepath('/./'), '/');
335
+ equals(normalizepath('..'), '/..');
336
+ equals(normalizepath('/..'), '/..');
337
+
338
+ equals(normalizepath('/foo/..'), '/');
339
+ equals(normalizepath('/foo/../bar'), '/bar');
340
+ equals(normalizepath('/foo/./bar'), '/foo/bar');
341
+ equals(normalizepath('/foo/./bar/'), '/foo/bar/');
342
+
343
+ });
344
+
345
+ test('urldefrag', function() {
346
+ var parts;
347
+ parts = urldefrag('foo#bar');
348
+ equals(parts[0], 'foo');
349
+ equals(parts[1], 'bar');
350
+ parts = urldefrag('foo#');
351
+ equals(parts[0], 'foo');
352
+ equals(parts[1], '');
353
+ parts = urldefrag('foo');
354
+ equals(parts[0], 'foo');
355
+ equals(parts[1], '');
356
+ });
357
+
358
+ });
359
+ </script>
360
+ </head>
361
+ <body>
362
+ <h1 id="qunit-header">urlparse tests</h1>
363
+ <h2 id="qunit-banner"></h2>
364
+ <h2 id="qunit-userAgent"></h2>
365
+ <ol id="qunit-tests"></ol>
366
+ </body>
367
+ </html>
@@ -0,0 +1,328 @@
1
+ /*
2
+ * Copyright (c) 2010 Nick Galbreath
3
+ * http://code.google.com/p/stringencoders/source/browse/#svn/trunk/javascript
4
+ *
5
+ * Permission is hereby granted, free of charge, to any person
6
+ * obtaining a copy of this software and associated documentation
7
+ * files (the "Software"), to deal in the Software without
8
+ * restriction, including without limitation the rights to use,
9
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ * copies of the Software, and to permit persons to whom the
11
+ * Software is furnished to do so, subject to the following
12
+ * conditions:
13
+ *
14
+ * The above copyright notice and this permission notice shall be
15
+ * included in all copies or substantial portions of the Software.
16
+ *
17
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
19
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
21
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
22
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
24
+ * OTHER DEALINGS IN THE SOFTWARE.
25
+ */
26
+
27
+ /*
28
+ * url processing in the spirit of python's urlparse module
29
+ * see `pydoc urlparse` or
30
+ * http://docs.python.org/library/urlparse.html
31
+ *
32
+ * urlsplit: break apart a URL into components
33
+ * urlunsplit: reconsistute a URL from componets
34
+ * urljoin: join an absolute and another URL
35
+ * urldefrag: remove the fragment from a URL
36
+ *
37
+ * Take a look at the tests in urlparse-test.html
38
+ *
39
+ * On URL Normalization:
40
+ *
41
+ * urlsplit only does minor normalization the components Only scheme
42
+ * and hostname are lowercased urljoin does a bit more, normalizing
43
+ * paths with "." and "..".
44
+
45
+ * urlnormalize adds additional normalization
46
+ *
47
+ * * removes default port numbers
48
+ * http://abc.com:80/ -> http://abc.com/, etc
49
+ * * normalizes path
50
+ * http://abc.com -> http://abc.com/
51
+ * and other "." and ".." cleanups
52
+ * * if file, remove query and fragment
53
+ *
54
+ * It does not do:
55
+ * * normalizes escaped hex values
56
+ * http://abc.com/%7efoo -> http://abc.com/%7Efoo
57
+ * * normalize '+' <--> '%20'
58
+ *
59
+ * Differences with Python
60
+ *
61
+ * The javascript urlsplit returns a normal object with the following
62
+ * properties: scheme, netloc, hostname, port, path, query, fragment.
63
+ * All properties are read-write.
64
+ *
65
+ * In python, the resulting object is not a dict, but a specialized,
66
+ * read-only, and has alternative tuple interface (e.g. obj[0] ==
67
+ * obj.scheme). It's not clear why such a simple function requires
68
+ * a unique datastructure.
69
+ *
70
+ * urlunsplit in javascript takes an duck-typed object,
71
+ * { scheme: 'http', netloc: 'abc.com', ...}
72
+ * while in * python it takes a list-like object.
73
+ * ['http', 'abc.com'... ]
74
+ *
75
+ * For all functions, the javascript version use
76
+ * hostname+port if netloc is missing. In python
77
+ * hostname+port were always ignored.
78
+ *
79
+ * Similar functionality in different languages:
80
+ *
81
+ * http://php.net/manual/en/function.parse-url.php
82
+ * returns assocative array but cannot handle relative URL
83
+ *
84
+ * TODO: test allowfragments more
85
+ * TODO: test netloc missing, but hostname present
86
+ */
87
+
88
+ var urlparse = {};
89
+
90
+ // Unlike to be useful standalone
91
+ //
92
+ // NORMALIZE PATH with "../" and "./"
93
+ // http://en.wikipedia.org/wiki/URL_normalization
94
+ // http://tools.ietf.org/html/rfc3986#section-5.2.3
95
+ //
96
+ urlparse.normalizepath = function(path)
97
+ {
98
+ if (!path || path === '/') {
99
+ return '/';
100
+ }
101
+
102
+ var parts = path.split('/');
103
+
104
+ var newparts = [];
105
+ // make sure path always starts with '/'
106
+ if (parts[0]) {
107
+ newparts.push('');
108
+ }
109
+
110
+ for (var i = 0; i < parts.length; ++i) {
111
+ if (parts[i] === '..') {
112
+ if (newparts.length > 1) {
113
+ newparts.pop();
114
+ } else {
115
+ newparts.push(parts[i]);
116
+ }
117
+ } else if (parts[i] != '.') {
118
+ newparts.push(parts[i]);
119
+ }
120
+ }
121
+
122
+ path = newparts.join('/');
123
+ if (!path) {
124
+ path = '/';
125
+ }
126
+ return path;
127
+ };
128
+
129
+ //
130
+ // Does many of the normalizations that the stock
131
+ // python urlsplit/urlunsplit/urljoin neglects
132
+ //
133
+ // Doesn't do hex-escape normalization on path or query
134
+ // %7e -> %7E
135
+ // Nor, '+' <--> %20 translation
136
+ //
137
+ urlparse.urlnormalize = function(url)
138
+ {
139
+ var parts = urlparse.urlsplit(url);
140
+ switch (parts.scheme) {
141
+ case 'file':
142
+ // files can't have query strings
143
+ // and we don't bother with fragments
144
+ parts.query = '';
145
+ parts.fragment = '';
146
+ break;
147
+ case 'http':
148
+ case 'https':
149
+ // remove default port
150
+ if ((parts.scheme === 'http' && parts.port == 80) ||
151
+ (parts.scheme === 'https' && parts.port == 443)) {
152
+ delete parts.port;
153
+ // hostname is already lower case
154
+ parts.netloc = parts.hostname;
155
+ }
156
+ break;
157
+ default:
158
+ // if we don't have specific normalizations for this
159
+ // scheme, return the original url unmolested
160
+ return url;
161
+ }
162
+
163
+ // for [file|http|https]. Not sure about other schemes
164
+ parts.path = urlparse.normalizepath(parts.path);
165
+
166
+ return urlparse.urlunsplit(parts);
167
+ };
168
+
169
+ urlparse.urldefrag = function(url)
170
+ {
171
+ var idx = url.indexOf('#');
172
+ if (idx == -1) {
173
+ return [ url, '' ];
174
+ } else {
175
+ return [ url.substr(0,idx), url.substr(idx+1) ];
176
+ }
177
+ };
178
+
179
+ urlparse.urlsplit = function(url, default_scheme, allow_fragments)
180
+ {
181
+ var leftover;
182
+ if (typeof allow_fragments === 'undefined') {
183
+ allow_fragments = true;
184
+ }
185
+
186
+ // scheme (optional), host, port
187
+ var fullurl = /^([A-Za-z]+)?(:?\/\/)([0-9.\-A-Za-z]*)(?::(\d+))?(.*)$/;
188
+ // path, query, fragment
189
+ var parse_leftovers = /([^?#]*)?(?:\?([^#]*))?(?:#(.*))?$/;
190
+
191
+ var o = {};
192
+
193
+ var parts = url.match(fullurl);
194
+ if (parts) {
195
+ o.scheme = parts[1] || default_scheme || '';
196
+ o.hostname = parts[3].toLowerCase() || '';
197
+ o.port = parseInt(parts[4],10) || '';
198
+ // Probably should grab the netloc from regexp
199
+ // and then parse again for hostname/port
200
+
201
+ o.netloc = parts[3];
202
+ if (parts[4]) {
203
+ o.netloc += ':' + parts[4];
204
+ }
205
+
206
+ leftover = parts[5];
207
+ } else {
208
+ o.scheme = default_scheme || '';
209
+ o.netloc = '';
210
+ o.hostname = '';
211
+ leftover = url;
212
+ }
213
+ o.scheme = o.scheme.toLowerCase();
214
+
215
+ parts = leftover.match(parse_leftovers);
216
+
217
+ o.path = parts[1] || '';
218
+ o.query = parts[2] || '';
219
+
220
+ if (allow_fragments) {
221
+ o.fragment = parts[3] || '';
222
+ } else {
223
+ o.fragment = '';
224
+ }
225
+
226
+ return o;
227
+ }
228
+
229
+ urlparse.urlunsplit = function(o) {
230
+ var s = '';
231
+ if (o.scheme) {
232
+ s += o.scheme + '://';
233
+ }
234
+
235
+ if (o.netloc) {
236
+ if (s == '') {
237
+ s += '//';
238
+ }
239
+ s += o.netloc;
240
+ } else if (o.hostname) {
241
+ // extension. Python only uses netloc
242
+ if (s == '') {
243
+ s += '//';
244
+ }
245
+ s += o.hostname;
246
+ if (o.port) {
247
+ s += ':' + o.port;
248
+ }
249
+ }
250
+
251
+ if (o.path) {
252
+ s += o.path;
253
+ }
254
+
255
+ if (o.query) {
256
+ s += '?' + o.query;
257
+ }
258
+ if (o.fragment) {
259
+ s += '#' + o.fragment;
260
+ }
261
+ return s;
262
+ }
263
+
264
+ urlparse.urljoin = function(base, url, allow_fragments)
265
+ {
266
+ if (typeof allow_fragments === 'undefined') {
267
+ allow_fragments = true;
268
+ }
269
+
270
+ var url_parts = urlparse.urlsplit(url);
271
+
272
+ // if url parts has a scheme (i.e. absolute)
273
+ // then nothing to do
274
+ if (url_parts.scheme) {
275
+ if (! allow_fragments) {
276
+ return url;
277
+ } else {
278
+ return urlparse.urldefrag(url)[0];
279
+ }
280
+ }
281
+ var base_parts = urlparse.urlsplit(base);
282
+
283
+ // copy base, only if not present
284
+ if (!base_parts.scheme) {
285
+ base_parts.scheme = url_parts.scheme;
286
+ }
287
+
288
+ // copy netloc, only if not present
289
+ if (!base_parts.netloc || !base_parts.hostname) {
290
+ base_parts.netloc = url_parts.netloc;
291
+ base_parts.hostname = url_parts.hostname;
292
+ base_parts.port = url_parts.port;
293
+ }
294
+
295
+ // paths
296
+ if (url_parts.path.length > 0) {
297
+ if (url_parts.path.charAt(0) == '/') {
298
+ base_parts.path = url_parts.path;
299
+ } else {
300
+ // relative path.. get rid of "current filename" and
301
+ // replace. Same as var parts =
302
+ // base_parts.path.split('/'); parts[parts.length-1] =
303
+ // url_parts.path; base_parts.path = parts.join('/');
304
+ var idx = base_parts.path.lastIndexOf('/');
305
+ if (idx == -1) {
306
+ base_parts.path = url_parts.path;
307
+ } else {
308
+ base_parts.path = base_parts.path.substr(0,idx) + '/' +
309
+ url_parts.path;
310
+ }
311
+ }
312
+ }
313
+
314
+ // clean up path
315
+ base_parts.path = urlparse.normalizepath(base_parts.path);
316
+
317
+ // copy query string
318
+ base_parts.query = url_parts.query;
319
+
320
+ // copy fragments
321
+ if (allow_fragments) {
322
+ base_parts.fragment = url_parts.fragment;
323
+ } else {
324
+ base_parts.fragment = '';
325
+ }
326
+
327
+ return urlparse.urlunsplit(base_parts);
328
+ }