glebtv-httpclient 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (59) hide show
  1. checksums.yaml +7 -0
  2. data/README.rdoc +108 -0
  3. data/bin/httpclient +65 -0
  4. data/lib/glebtv-httpclient.rb +1 -0
  5. data/lib/hexdump.rb +50 -0
  6. data/lib/http-access2/cookie.rb +1 -0
  7. data/lib/http-access2/http.rb +1 -0
  8. data/lib/http-access2.rb +55 -0
  9. data/lib/httpclient/auth.rb +899 -0
  10. data/lib/httpclient/cacert.p7s +1912 -0
  11. data/lib/httpclient/connection.rb +88 -0
  12. data/lib/httpclient/cookie.rb +438 -0
  13. data/lib/httpclient/http.rb +1050 -0
  14. data/lib/httpclient/include_client.rb +83 -0
  15. data/lib/httpclient/session.rb +1031 -0
  16. data/lib/httpclient/ssl_config.rb +403 -0
  17. data/lib/httpclient/timeout.rb +140 -0
  18. data/lib/httpclient/util.rb +186 -0
  19. data/lib/httpclient/version.rb +3 -0
  20. data/lib/httpclient.rb +1157 -0
  21. data/lib/oauthclient.rb +110 -0
  22. data/sample/async.rb +8 -0
  23. data/sample/auth.rb +11 -0
  24. data/sample/cookie.rb +18 -0
  25. data/sample/dav.rb +103 -0
  26. data/sample/howto.rb +49 -0
  27. data/sample/oauth_buzz.rb +57 -0
  28. data/sample/oauth_friendfeed.rb +59 -0
  29. data/sample/oauth_twitter.rb +61 -0
  30. data/sample/ssl/0cert.pem +22 -0
  31. data/sample/ssl/0key.pem +30 -0
  32. data/sample/ssl/1000cert.pem +19 -0
  33. data/sample/ssl/1000key.pem +18 -0
  34. data/sample/ssl/htdocs/index.html +10 -0
  35. data/sample/ssl/ssl_client.rb +22 -0
  36. data/sample/ssl/webrick_httpsd.rb +29 -0
  37. data/sample/stream.rb +21 -0
  38. data/sample/thread.rb +27 -0
  39. data/sample/wcat.rb +21 -0
  40. data/test/ca-chain.cert +44 -0
  41. data/test/ca.cert +23 -0
  42. data/test/client.cert +19 -0
  43. data/test/client.key +15 -0
  44. data/test/helper.rb +129 -0
  45. data/test/htdigest +1 -0
  46. data/test/htpasswd +2 -0
  47. data/test/runner.rb +2 -0
  48. data/test/server.cert +19 -0
  49. data/test/server.key +15 -0
  50. data/test/sslsvr.rb +65 -0
  51. data/test/subca.cert +21 -0
  52. data/test/test_auth.rb +321 -0
  53. data/test/test_cookie.rb +412 -0
  54. data/test/test_hexdump.rb +14 -0
  55. data/test/test_http-access2.rb +507 -0
  56. data/test/test_httpclient.rb +1801 -0
  57. data/test/test_include_client.rb +52 -0
  58. data/test/test_ssl.rb +235 -0
  59. metadata +102 -0
@@ -0,0 +1,412 @@
1
+ require 'test/unit'
2
+ require 'uri'
3
+
4
+ require 'httpclient/cookie'
5
+
6
+ class TestCookie < Test::Unit::TestCase
7
+ include HTTPClient::Util
8
+
9
+ def setup()
10
+ @c = WebAgent::Cookie.new()
11
+ end
12
+
13
+ def test_s_new()
14
+ assert_instance_of(WebAgent::Cookie, @c)
15
+ end
16
+
17
+ def test_discard?
18
+ assert_equal(false, !!(@c.discard?))
19
+ @c.discard = true
20
+ assert_equal(true, !!(@c.discard?))
21
+ end
22
+
23
+ def test_match()
24
+ url = urify('http://www.rubycolor.org/hoge/funi/#919191')
25
+
26
+ @c.domain = 'www.rubycolor.org'
27
+ assert_equal(true, @c.match?(url))
28
+
29
+ @c.domain = '.rubycolor.org'
30
+ assert_equal(true, @c.match?(url))
31
+
32
+ @c.domain = 'aaa.www.rubycolor.org'
33
+ assert_equal(false, @c.match?(url))
34
+
35
+ @c.domain = 'aaa.www.rubycolor.org'
36
+ assert_equal(false, @c.match?(url))
37
+
38
+ @c.domain = 'www.rubycolor.org'
39
+ @c.path = '/'
40
+ assert_equal(true, @c.match?(url))
41
+
42
+ @c.domain = 'www.rubycolor.org'
43
+ @c.path = '/hoge'
44
+ assert_equal(true, @c.match?(url))
45
+
46
+ @c.domain = 'www.rubycolor.org'
47
+ @c.path = '/hoge/hoge'
48
+ assert_equal(false, @c.match?(url))
49
+
50
+ @c.domain = 'www.rubycolor.org'
51
+ @c.path = '/hoge'
52
+ @c.secure = true
53
+ assert_equal(false, @c.match?(url))
54
+
55
+ url2 = urify('https://www.rubycolor.org/hoge/funi/#919191')
56
+ @c.domain = 'www.rubycolor.org'
57
+ @c.path = '/hoge'
58
+ @c.secure = true
59
+ assert_equal(true, @c.match?(url2))
60
+
61
+ @c.domain = 'www.rubycolor.org'
62
+ @c.path = '/hoge'
63
+ @c.secure = nil
64
+ assert_equal(true, @c.match?(url2)) ## not false!
65
+
66
+ url.port = 80
67
+ @c.domain = 'www.rubycolor.org'
68
+ @c.path = '/hoge'
69
+ # @c.port = [80,8080]
70
+ assert_equal(true, @c.match?(url))
71
+
72
+ url_nopath = URI.parse('http://www.rubycolor.org')
73
+ @c.domain = 'www.rubycolor.org'
74
+ @c.path = '/'
75
+ assert_equal(true, @c.match?(url_nopath))
76
+
77
+ end
78
+
79
+ def test_head_match?()
80
+ assert_equal(true, @c.head_match?("",""))
81
+ assert_equal(false, @c.head_match?("a",""))
82
+ assert_equal(true, @c.head_match?("","a"))
83
+ assert_equal(true, @c.head_match?("abcde","abcde"))
84
+ assert_equal(true, @c.head_match?("abcde","abcdef"))
85
+ assert_equal(false, @c.head_match?("abcdef","abcde"))
86
+ assert_equal(false, @c.head_match?("abcde","bcde"))
87
+ assert_equal(false, @c.head_match?("bcde","abcde"))
88
+ end
89
+
90
+ def test_tail_match?()
91
+ assert_equal(true, @c.tail_match?("",""))
92
+ assert_equal(false, @c.tail_match?("a",""))
93
+ assert_equal(true, @c.tail_match?("","a"))
94
+ assert_equal(true, @c.tail_match?("abcde","abcde"))
95
+ assert_equal(false, @c.tail_match?("abcde","abcdef"))
96
+ assert_equal(false, @c.tail_match?("abcdef","abcde"))
97
+ assert_equal(false, @c.tail_match?("abcde","bcde"))
98
+ assert_equal(true, @c.tail_match?("bcde","abcde"))
99
+ end
100
+
101
+
102
+ def test_domain_match()
103
+ extend WebAgent::CookieUtils
104
+ assert_equal(true, !!domain_match("hoge.co.jp","."))
105
+ # assert_equal(true, !!domain_match("locahost",".local"))
106
+ assert_equal(true, !!domain_match("192.168.10.1","192.168.10.1"))
107
+ assert_equal(false, !!domain_match("192.168.10.1","192.168.10.2"))
108
+ # assert_equal(false, !!domain_match("hoge.co.jp",".hoge.co.jp"))
109
+ # allows; host == rubyforge.org, domain == .rubyforge.org
110
+ assert_equal(true, !!domain_match("hoge.co.jp",".hoge.co.jp"))
111
+ assert_equal(true, !!domain_match("www.hoge.co.jp", "www.hoge.co.jp"))
112
+ assert_equal(false, !!domain_match("www.hoge.co.jp", "www2.hoge.co.jp"))
113
+ assert_equal(true, !!domain_match("www.hoge.co.jp", ".hoge.co.jp"))
114
+ assert_equal(true, !!domain_match("www.aa.hoge.co.jp", ".hoge.co.jp"))
115
+ assert_equal(false, !!domain_match("www.hoge.co.jp", "hoge.co.jp"))
116
+ end
117
+
118
+ def test_join_quotedstr()
119
+ arr1 = ['hoge=funi', 'hoge2=funi2']
120
+ assert_equal(arr1, @c.instance_eval{join_quotedstr(arr1,';')})
121
+ arr2 = ['hoge="fu', 'ni"', 'funi=funi']
122
+ assert_equal(['hoge="fu;ni"','funi=funi'],
123
+ @c.instance_eval{join_quotedstr(arr2,';')})
124
+ arr3 = ['hoge="funi";hoge2="fu','ni2";hoge3="hoge"', 'funi="funi"']
125
+ assert_equal(['hoge="funi";hoge2="fu,ni2";hoge3="hoge"', 'funi="funi"'],
126
+ @c.instance_eval{join_quotedstr(arr3,',')})
127
+ end
128
+
129
+ end
130
+
131
+ class TestCookieManager < Test::Unit::TestCase
132
+ include HTTPClient::Util
133
+
134
+ def setup()
135
+ @cm = WebAgent::CookieManager.new()
136
+ end
137
+
138
+ def teardown()
139
+ end
140
+
141
+ def test_parse()
142
+ str = "inkid=n92b0ADOgACIgUb9lsjHqAAAHu2a; expires=Wed, 01-Dec-2010 00:00:00 GMT; path=/"
143
+ @cm.parse(str, urify('http://www.test.jp'))
144
+ cookie = @cm.cookies[0]
145
+ assert_instance_of(WebAgent::Cookie, cookie)
146
+ assert_equal("inkid", cookie.name)
147
+ assert_equal("n92b0ADOgACIgUb9lsjHqAAAHu2a", cookie.value)
148
+ assert_equal(Time.gm(2010, 12, 1, 0,0,0), cookie.expires)
149
+ assert_equal("/", cookie.path)
150
+ end
151
+
152
+ def test_parse2()
153
+ str = "xmen=off,0,0,1; path=/; domain=.excite.co.jp; expires=Wednesday, 31-Dec-2037 12:00:00 GMT"
154
+ @cm.parse(str, urify('http://www.excite.co.jp'))
155
+ cookie = @cm.cookies[0]
156
+ assert_instance_of(WebAgent::Cookie, cookie)
157
+ assert_equal("xmen", cookie.name)
158
+ assert_equal("off,0,0,1", cookie.value)
159
+ assert_equal("/", cookie.path)
160
+ assert_equal(".excite.co.jp", cookie.domain)
161
+ assert_equal(Time.gm(2037,12,31,12,0,0), cookie.expires)
162
+ end
163
+
164
+ def test_parse3()
165
+ str = "xmen=off,0,0,1; path=/; domain=.excite.co.jp; expires=Wednesday, 31-Dec-2037 12:00:00 GMT;Secure;HTTPOnly"
166
+ @cm.parse(str, urify('http://www.excite.co.jp'))
167
+ cookie = @cm.cookies[0]
168
+ assert_instance_of(WebAgent::Cookie, cookie)
169
+ assert_equal("xmen", cookie.name)
170
+ assert_equal("off,0,0,1", cookie.value)
171
+ assert_equal("/", cookie.path)
172
+ assert_equal(".excite.co.jp", cookie.domain)
173
+ assert_equal(Time.gm(2037,12,31,12,0,0), cookie.expires)
174
+ assert_equal(true, cookie.secure?)
175
+ assert_equal(true, cookie.http_only?)
176
+ end
177
+
178
+ def test_parse_double_semicolon()
179
+ str = "xmen=off,0,0,1;; path=\"/;;\"; domain=.excite.co.jp; expires=Wednesday, 31-Dec-2037 12:00:00 GMT"
180
+ @cm.parse(str, urify('http://www.excite.co.jp'))
181
+ cookie = @cm.cookies[0]
182
+ assert_instance_of(WebAgent::Cookie, cookie)
183
+ assert_equal("xmen", cookie.name)
184
+ assert_equal("off,0,0,1", cookie.value)
185
+ assert_equal("/;;", cookie.path)
186
+ assert_equal(".excite.co.jp", cookie.domain)
187
+ assert_equal(Time.gm(2037,12,31,12,0,0), cookie.expires)
188
+ end
189
+
190
+ # def test_make_portlist()
191
+ # assert_equal([80,8080], @cm.instance_eval{make_portlist("80,8080")})
192
+ # assert_equal([80], @cm.instance_eval{make_portlist("80")})
193
+ # assert_equal([80,8080,10080], @cm.instance_eval{make_portlist(" 80, 8080, 10080 \n")})
194
+ # end
195
+
196
+ def test_check_expired_cookies()
197
+ c1 = WebAgent::Cookie.new()
198
+ c2 = c1.dup
199
+ c3 = c1.dup
200
+ c4 = c1.dup
201
+ c1.expires = Time.now - 100
202
+ c2.expires = Time.now + 100
203
+ c3.expires = Time.now - 10
204
+ c4.expires = nil
205
+ cookies = [c1,c2,c3,c4]
206
+ @cm.cookies = cookies
207
+ @cm.check_expired_cookies()
208
+ # expires == nil cookies (session cookie) exists.
209
+ assert_equal([c2,c4], @cm.cookies)
210
+ end
211
+
212
+ def test_parse_expires
213
+ str = "inkid=n92b0ADOgACIgUb9lsjHqAAAHu2a; expires=; path=/"
214
+ @cm.parse(str, urify('http://www.test.jp'))
215
+ cookie = @cm.cookies[0]
216
+ assert_equal("inkid", cookie.name)
217
+ assert_equal("n92b0ADOgACIgUb9lsjHqAAAHu2a", cookie.value)
218
+ assert_equal(nil, cookie.expires)
219
+ assert_equal("/", cookie.path)
220
+ #
221
+ str = "inkid=n92b0ADOgACIgUb9lsjHqAAAHu2a; path=/; expires="
222
+ @cm.parse(str, urify('http://www.test.jp'))
223
+ cookie = @cm.cookies[0]
224
+ assert_equal("inkid", cookie.name)
225
+ assert_equal("n92b0ADOgACIgUb9lsjHqAAAHu2a", cookie.value)
226
+ assert_equal(nil, cookie.expires)
227
+ assert_equal("/", cookie.path)
228
+ #
229
+ str = "inkid=n92b0ADOgACIgUb9lsjHqAAAHu2a; path=/; expires=\"\""
230
+ @cm.parse(str, urify('http://www.test.jp'))
231
+ cookie = @cm.cookies[0]
232
+ assert_equal("inkid", cookie.name)
233
+ assert_equal("n92b0ADOgACIgUb9lsjHqAAAHu2a", cookie.value)
234
+ assert_equal(nil, cookie.expires)
235
+ assert_equal("/", cookie.path)
236
+ end
237
+
238
+ def test_parse_after_expiration
239
+ str = "inkid=n92b0ADOgACIgUb9lsjHqAAAHu2a; expires=Wed, 01-Dec-2010 00:00:00 GMT; path=/"
240
+ @cm.parse(str, urify('http://www.test.jp'))
241
+ cookie = @cm.cookies[0]
242
+ assert_instance_of(WebAgent::Cookie, cookie)
243
+ assert_equal("inkid", cookie.name)
244
+ assert_equal("n92b0ADOgACIgUb9lsjHqAAAHu2a", cookie.value)
245
+ assert_equal(Time.gm(2010, 12, 1, 0,0,0), cookie.expires)
246
+ assert_equal("/", cookie.path)
247
+
248
+ time = Time.now.utc.round + 60
249
+ expires = time.strftime("%a, %d-%b-%Y %H:%M:%S GMT")
250
+ str = "inkid=n92b0ADOgACIgUb9lsjHqAAAHu2a; expires=#{expires}; path=/"
251
+ @cm.parse(str, urify('http://www.test.jp'))
252
+ cookie = @cm.cookies[0]
253
+ assert_equal("inkid", cookie.name)
254
+ assert_equal("n92b0ADOgACIgUb9lsjHqAAAHu2a", cookie.value)
255
+ assert_equal(time, cookie.expires)
256
+ assert_equal("/", cookie.path)
257
+ end
258
+
259
+ def test_find_cookie()
260
+ str = "xmen=off,0,0,1; path=/; domain=.excite2.co.jp; expires=Wednesday, 31-Dec-2037 12:00:00 GMT"
261
+ @cm.parse(str, urify("http://www.excite2.co.jp/"))
262
+
263
+ str = "xmen=off,0,0,2; path=/; domain=.excite.co.jp; expires=Wednesday, 31-Dec-2037 12:00:00 GMT"
264
+ @cm.parse(str, urify("http://www.excite.co.jp/"))
265
+
266
+ @cm.cookies[0].use = true
267
+ @cm.cookies[1].use = true
268
+
269
+ url = urify('http://www.excite.co.jp/hoge/funi/')
270
+ cookie_str = @cm.find(url)
271
+ assert_equal("xmen=off,0,0,2", cookie_str)
272
+ end
273
+
274
+ def test_load_cookies()
275
+ begin
276
+ File.open("tmp_test.tmp","w") {|f|
277
+ f.write <<EOF
278
+ http://www.zdnet.co.jp/news/0106/08/e_gibson.html NGUserID d29b8f49-10875-992421294-1 2145801600 www.zdnet.co.jp / 9 0
279
+ http://www.zdnet.co.jp/news/0106/08/e_gibson.html PACK zd3-992421294-7436 1293839999 .zdnet.co.jp / 13 0
280
+ http://example.org/ key value 0 .example.org / 13 0
281
+ http://example.org/ key value .example.org / 13 0
282
+ EOF
283
+ }
284
+
285
+ @cm.cookies_file = 'tmp_test.tmp'
286
+ @cm.load_cookies()
287
+ c0, c1, c2, c3 = @cm.cookies
288
+ assert_equal('http://www.zdnet.co.jp/news/0106/08/e_gibson.html', c0.url.to_s)
289
+ assert_equal('NGUserID', c0.name)
290
+ assert_equal('d29b8f49-10875-992421294-1', c0.value)
291
+ assert_equal(Time.at(2145801600), c0.expires)
292
+ assert_equal('www.zdnet.co.jp', c0.domain)
293
+ assert_equal('/', c0.path)
294
+ assert_equal(9, c0.flag)
295
+ #
296
+ assert_equal('http://www.zdnet.co.jp/news/0106/08/e_gibson.html', c1.url.to_s)
297
+ assert_equal('PACK', c1.name)
298
+ assert_equal('zd3-992421294-7436', c1.value)
299
+ assert_equal(Time.at(1293839999), c1.expires)
300
+ assert_equal('.zdnet.co.jp', c1.domain)
301
+ assert_equal('/', c1.path)
302
+ assert_equal(13, c1.flag)
303
+ #
304
+ assert_equal(nil, c2.expires)
305
+ assert_equal(nil, c3.expires) # allow empty 'expires' (should not happen)
306
+ ensure
307
+ File.unlink("tmp_test.tmp")
308
+ end
309
+ end
310
+
311
+ def test_save_cookie()
312
+ str = <<EOF
313
+ http://www.zdnet.co.jp/news/0106/08/e_gibson.html NGUserID d29b8f49-10875-992421294-1 2145801600 www.zdnet.co.jp / 9
314
+ http://www.zdnet.co.jp/news/0106/08/e_gibson.html PACK zd3-992421294-7436 2145801600 .zdnet.co.jp / 13
315
+ EOF
316
+ begin
317
+ File.open("tmp_test.tmp","w") {|f|
318
+ f.write str
319
+ }
320
+ @cm.cookies_file = 'tmp_test.tmp'
321
+ @cm.load_cookies()
322
+ @cm.instance_eval{@is_saved = false}
323
+ @cm.cookies_file = 'tmp_test2.tmp'
324
+ @cm.save_cookies()
325
+ str2 = ''
326
+ File.open("tmp_test2.tmp","r") {|f|
327
+ str2 = f.read()
328
+ }
329
+ assert_equal(str, str2)
330
+ #
331
+ assert(File.exist?('tmp_test2.tmp'))
332
+ File.unlink("tmp_test2.tmp")
333
+ @cm.save_cookies()
334
+ assert(!File.exist?('tmp_test2.tmp'))
335
+ @cm.save_cookies(true)
336
+ assert(File.exist?('tmp_test2.tmp'))
337
+ ensure
338
+ File.unlink("tmp_test.tmp")
339
+ if FileTest.exist?("tmp_test2.tmp")
340
+ File.unlink("tmp_test2.tmp")
341
+ end
342
+ end
343
+ end
344
+
345
+ def test_not_saved_expired_cookies
346
+ begin
347
+ @cm.cookies_file = 'tmp_test.tmp'
348
+ uri = urify('http://www.example.org')
349
+ @cm.parse("foo=1; path=/", uri)
350
+ @cm.parse("bar=2; path=/; expires=", uri)
351
+ @cm.parse("baz=3; path=/; expires=\"\"", uri)
352
+ @cm.parse("qux=4; path=/; expires=#{(Time.now + 10).asctime}", uri)
353
+ @cm.parse("quxx=5; path=/; expires=#{(Time.now - 10).asctime}", uri)
354
+ @cm.save_cookies()
355
+ @cm.load_cookies
356
+ assert_equal(1, @cm.cookies.size) # +10 cookies only
357
+ ensure
358
+ File.unlink("tmp_test.tmp") if File.exist?("tmp_test.tmp")
359
+ end
360
+ end
361
+
362
+ def test_add()
363
+ c = WebAgent::Cookie.new()
364
+ c.name = "hoge"
365
+ c.value = "funi"
366
+ c.url = urify("http://www.inac.co.jp/hoge")
367
+ @cm.add(c)
368
+ c = @cm.cookies[0]
369
+ assert_equal('hoge', c.name)
370
+ assert_equal('funi', c.value)
371
+ assert_equal(nil, c.expires)
372
+ end
373
+
374
+ def test_add2()
375
+ c = WebAgent::Cookie.new()
376
+ c.name = "hoge"
377
+ c.value = "funi"
378
+ c.path = ''
379
+ c.url = urify("http://www.inac.co.jp/hoge/hoge2/hoge3")
380
+ @cm.add(c)
381
+ #
382
+ c = WebAgent::Cookie.new()
383
+ c.name = "hoge"
384
+ c.value = "funi"
385
+ #c.path = '' NO path given -> same as URL
386
+ c.url = urify("http://www.inac.co.jp/hoge/hoge2/hoge3")
387
+ @cm.add(c)
388
+ #
389
+ c1, c2 = @cm.cookies
390
+ assert_equal('', c1.path)
391
+ assert_equal('/hoge/hoge2', c2.path)
392
+ end
393
+
394
+ def test_check_cookie_accept_domain()
395
+ @cm.accept_domains = [".example1.co.jp", "www1.example.jp"]
396
+ @cm.reject_domains = [".example2.co.jp", "www2.example.jp"]
397
+ check1 = @cm.check_cookie_accept_domain("www.example1.co.jp")
398
+ assert_equal(true, check1)
399
+ check2 = @cm.check_cookie_accept_domain("www.example2.co.jp")
400
+ assert_equal(false, check2)
401
+ check3 = @cm.check_cookie_accept_domain("www1.example.jp")
402
+ assert_equal(true, check3)
403
+ check4 = @cm.check_cookie_accept_domain("www2.example.jp")
404
+ assert_equal(false, check4)
405
+ check5 = @cm.check_cookie_accept_domain("aa.www2.example.jp")
406
+ assert_equal(true, check5)
407
+ check6 = @cm.check_cookie_accept_domain("aa.www2.example.jp")
408
+ assert_equal(true, check6)
409
+ assert_equal(false, @cm.check_cookie_accept_domain(nil))
410
+ end
411
+
412
+ end
@@ -0,0 +1,14 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('helper', File.dirname(__FILE__))
3
+ require 'hexdump'
4
+
5
+
6
+ class TestHexDump < Test::Unit::TestCase
7
+ def test_encode
8
+ str = "\032l\277\370\2429\216\236\351[{\{\262\350\274\376"
9
+ str.force_encoding('BINARY') if str.respond_to?(:force_encoding)
10
+ assert_equal(["00000000 1a6cbff8 a2398e9e e95b7b7b b2e8bcfe .l...9...[{{...."], HexDump.encode(str))
11
+ end
12
+ end if defined?(RUBY_ENGINE) && RUBY_ENGINE != "rbx" && RUBY_VERSION >= "1.9.0"
13
+ # Rubinius 1.8 mode does not support Regexp.quote(raw, 'n') I don't want put
14
+ # a pressure on supporting it because 1.9 mode works fine.