super-test 1.0.9

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 (108) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGE.txt +9 -0
  3. data/README.txt +13 -0
  4. data/bin/idb +19 -0
  5. data/bin/ii +113 -0
  6. data/bin/istart_mock +36 -0
  7. data/bin/istop_mock +16 -0
  8. data/bin/kk +181 -0
  9. data/bin/rubyatp +42 -0
  10. data/bin/start_mock +36 -0
  11. data/bin/stop_mock +16 -0
  12. data/bin/xgo +45 -0
  13. data/conf/conf.rb +11 -0
  14. data/conf/db03.yml +31 -0
  15. data/conf/db13.yml +37 -0
  16. data/conf/db19.yml +33 -0
  17. data/conf/online.yml +32 -0
  18. data/conf/super_test.yml +40 -0
  19. data/conf/system.yml +26 -0
  20. data/conf/sz00.yml +31 -0
  21. data/conf/sz06.yml +34 -0
  22. data/conf/wise00.yml +11 -0
  23. data/data/case.house +0 -0
  24. data/data/char.house +0 -0
  25. data/data/images/Bluehills.jpg +0 -0
  26. data/data/images/Sunset.jpg +0 -0
  27. data/data/images/Waterlilies.jpg +0 -0
  28. data/data/images/Winter.jpg +0 -0
  29. data/data/query.house +18595 -0
  30. data/data/user.house +8 -0
  31. data/lib/action/module/check_action.rb +58 -0
  32. data/lib/action/module/cnnt_action.rb +161 -0
  33. data/lib/action/module/datacenter_action.rb +48 -0
  34. data/lib/action/module/http_pack_helper.rb +163 -0
  35. data/lib/action/module/httpserver_action.rb +297 -0
  36. data/lib/action/module/inc.rb +21 -0
  37. data/lib/action/module/mcpack_action.rb +57 -0
  38. data/lib/action/module/sql_action.rb +84 -0
  39. data/lib/action/module/ssh_action.rb +37 -0
  40. data/lib/action/system/user_action.rb +180 -0
  41. data/lib/common/appium_helper.rb +217 -0
  42. data/lib/common/atp_helper.rb +74 -0
  43. data/lib/common/atp_report.rb +344 -0
  44. data/lib/common/data_house.rb +405 -0
  45. data/lib/common/data_model.rb +87 -0
  46. data/lib/common/http/assert_helper.rb +343 -0
  47. data/lib/common/http/fix_hpricot.rb +118 -0
  48. data/lib/common/http/html_helper.rb +362 -0
  49. data/lib/common/http/http_helper.rb +469 -0
  50. data/lib/common/http/multipart.rb +81 -0
  51. data/lib/common/isandbox_helper.rb +195 -0
  52. data/lib/common/json_helper.rb +43 -0
  53. data/lib/common/mock_helper.rb +168 -0
  54. data/lib/common/mtop_helper.rb +141 -0
  55. data/lib/common/myconf_helper.rb +49 -0
  56. data/lib/common/mylog_helper.rb +77 -0
  57. data/lib/common/pairwise.rb +121 -0
  58. data/lib/common/query_house.rb +89 -0
  59. data/lib/common/report_helper.rb +97 -0
  60. data/lib/common/robot_helper.rb +85 -0
  61. data/lib/common/socket/check.rb +325 -0
  62. data/lib/common/socket/conf_modifier.rb +149 -0
  63. data/lib/common/socket/context.rb +55 -0
  64. data/lib/common/socket/data.rb +392 -0
  65. data/lib/common/socket/data_helper.rb +41 -0
  66. data/lib/common/socket/env.rb +317 -0
  67. data/lib/common/socket/inc.rb +24 -0
  68. data/lib/common/socket/log.rb +213 -0
  69. data/lib/common/socket/log4s.rb +58 -0
  70. data/lib/common/socket/log_helper.rb +332 -0
  71. data/lib/common/socket/my_sql.rb +77 -0
  72. data/lib/common/socket/net.rb +74 -0
  73. data/lib/common/socket/network.rb +115 -0
  74. data/lib/common/socket/rlib/conf_modifier.rb +130 -0
  75. data/lib/common/socket/rlib/data_helper.rb +33 -0
  76. data/lib/common/socket/rlib/log_helper.rb +303 -0
  77. data/lib/common/socket/rlib/process_helper.rb +91 -0
  78. data/lib/common/socket/stub.rb +276 -0
  79. data/lib/common/socket/util.rb +266 -0
  80. data/lib/patterns/inc.rb +10 -0
  81. data/lib/patterns/mc_base_pattern.rb +474 -0
  82. data/lib/patterns/some_pattern.rb +145 -0
  83. data/lib/super_test.rb +114 -0
  84. data/log/super_test.log +0 -0
  85. data/log/super_test.log.wf +0 -0
  86. data/test/cover_me.rb +6 -0
  87. data/tool/jenny +0 -0
  88. data/tool/mcsend/mcsend2 +0 -0
  89. data/tool/mcsend/mcsend2_shead +0 -0
  90. data/tool/mcserver/conf/mcserver.conf +77 -0
  91. data/tool/mcserver/conf/mcserverauthip +17 -0
  92. data/tool/mcserver/mcserver +0 -0
  93. data/tool/mcserver/mcserver_trans +0 -0
  94. data/tool/mysql +0 -0
  95. data/tool/net/mcsend/mcsend +0 -0
  96. data/tool/net/mcsend/mcsend_trans +0 -0
  97. data/tool/net/mcsend/nshead.data +7 -0
  98. data/tool/net/mcsend/res_nshead.data +7 -0
  99. data/tool/net/my_client/my_client +0 -0
  100. data/tool/net/tsclient/client.tcl +205 -0
  101. data/tool/others/kk +190 -0
  102. data/tool/others/rubyatp +42 -0
  103. data/tool/others/supertest_install.sh +34 -0
  104. data/tool/trip/idb +0 -0
  105. data/tool/ts-agent/nshead.bft +12 -0
  106. data/tool/ts-agent/server.conf +10 -0
  107. data/tool/ts-agent/server.tcl +376 -0
  108. metadata +275 -0
@@ -0,0 +1,362 @@
1
+ #!/usr/bin/env ruby
2
+ # coding: utf-8
3
+ #
4
+ # Author:: hanyu
5
+ # Date:: 2009.5.7
6
+
7
+
8
+ require 'hpricot'
9
+ require 'common/http/fix_hpricot'
10
+
11
+ # 解析纯文本、HTML、JSON
12
+ #
13
+ # - 打印可读日志
14
+ module HtmlHelper
15
+
16
+ # === 功能:
17
+ # 正则表达式提取
18
+ #
19
+ # === 参数解释:
20
+ # - regexp 提取的正则表达式
21
+ # - group 正则表达式匹配组号,默认为1
22
+ #
23
+ # === Example:
24
+ # Example #1:
25
+ #
26
+ # get "http://www.baidu.com/"
27
+ # puts find_grep %r"<title>(.*?)</title>"
28
+ # # => 百度一下,你就知道
29
+ #
30
+ # Example #2:
31
+ #
32
+ # get "http://www.baidu.com/"
33
+ # puts find_grep /<title>(.*?),(.*?)<\/title>/, 2
34
+ # # => 你就知道
35
+ def find_grep(regexp, group=1)
36
+ raise "no any http request before!" if @response == nil
37
+ m = regexp.match @response.body
38
+ raise HtmlError,"find_grep regexp[#{regexp}] not exist!" if m.nil?
39
+ return m[group]
40
+ end
41
+
42
+ # === 功能:
43
+ # 验证是否包含某字符串,不带正则表达式的功能
44
+ #
45
+ # === 参数解释:
46
+ # - str 给定的字符串
47
+ #
48
+ # === Example:
49
+ # Example :
50
+ # get "http://hi.baidu.com/"
51
+ # p find_has? "百度空间" #=> true
52
+ def find_has?(str)
53
+ raise "no any http request before!" if @response == nil
54
+ @response.body.include? str
55
+ end
56
+
57
+
58
+
59
+ # === 功能:
60
+ # 使用正则表达式的扫描,取出满足的集合
61
+ #
62
+ # === 参数解释:
63
+ # - regexp 扫描的正则表达式
64
+ # - return 一个二维数组,第一维是匹配上的串,第二维是正则表达式里面的group情况
65
+ #
66
+ # === Example:
67
+ # Example #1: 非block
68
+ #
69
+ # get "http://hi.baidu.com/腚腚熊/album"
70
+ # p find_scan /^imgarr\[len\]=\{purl:"(.*)",psrc:"(.*)",pname:"(.*)",pnum:"(.*)"/
71
+ # # => [["/%EB%EB%EB%EB%D0%DC/album/%C4%AC%C8%CF%CF%E0%B2%E1", "http://hiphotos.baidu.com/%EB%EB%EB%EB%D0%DC/abpic/item/8ddde41f55e355daa78669b4.jpg", "默认相册", "32"], ["/%EB%EB%EB%EB%D0%DC/album/%CE%D2%B5%C4%D1%D0%BE%BF%C9%FA%CA%B1%B4%FA", "http://hiphotos.baidu.com/%EB%EB%EB%EB%D0%DC/abpic/item/b7c672197f61435542a9ad2f.jpg", "我的研究生时代", "14"], ["/%EB%EB%EB%EB%D0%DC/album/3", "http://hiphotos.baidu.com/%EB%EB%EB%EB%D0%DC/abpic/item/0ded0b80781ddbcb9123d9b2.jpg", "3", "1"], ["/%EB%EB%EB%EB%D0%DC/album/4", "http://hiphotos.baidu.com/%EB%EB%EB%EB%D0%DC/abpic/item/e62608ea188ae1cfd539c991.jpg", "4", "1"], ["/%EB%EB%EB%EB%D0%DC/album/Kongde", "http://hiphotos.baidu.com/%EB%EB%EB%EB%D0%DC/abpic/item/8c3e0aef76094b36acafd5f0.jpg", "Kongde", "0"]]
72
+ #
73
+ # Example #2: block方式
74
+ #
75
+ # get "http://hi.baidu.com/腚腚熊/album"
76
+ # find_scan /^imgarr\[len\]=\{purl:"(.*)",psrc:"(.*)",pname:"(.*)",pnum:"(.*)"/ do |url,src,name,num|
77
+ # p "url:#{url} src:#{src} name:#{name} num:#{num}"
78
+ # end
79
+ # # => url:/%EB%EB%EB%EB%D0%DC/album/%C4%AC%C8%CF%CF%E0%B2%E1 src:http://hiphotos.baidu.com/%EB%EB%EB%EB%D0%DC/abpic/item/8ddde41f55e355daa78669b4.jpg name:默认相册 num:32
80
+ # # => ...
81
+ def find_scan(regexp,&blk)
82
+ raise "no any http request before!" if @response == nil
83
+ return @response.body.scan regexp,&blk
84
+ end
85
+
86
+ # === 功能:
87
+ # 判断元素是否存在
88
+ #
89
+ # === 参数解释:
90
+ # - xpath 定位,可以使xpath or selector
91
+ # - return 返回boolean
92
+ #
93
+ # === Example:
94
+ # get "http://www.baidu.com/"
95
+ # p find_exist? "title" # => true
96
+ def find_exist?(xpath)
97
+ raise "no any http request before!" if @response == nil
98
+ @hpricot ||= Hpricot(@response.body)
99
+ elems = @hpricot.search(xpath)
100
+ if block_given?
101
+ index = -1
102
+ elems = elems.select do |elem|
103
+ index = index + 1
104
+ yield elem,index
105
+ end
106
+ end
107
+ return !elems.empty?
108
+ end
109
+
110
+ # === 功能:
111
+ # 使用XPath或CSS Selector来提取html片段
112
+ #
113
+ # === 参数解释:
114
+ # - xpath 定位,可以使xpath or selector
115
+ # - return 返回String
116
+ #
117
+ # === Example:
118
+ # Example #1:
119
+ #
120
+ # get "http://www.baidu.com/"
121
+ # # HTML片段如下
122
+ # # <p id=km><a href=http://hi.baidu.com>空间</a>&nbsp;&nbsp;<a href=http://www.hao123.com>hao123</a>
123
+ # # &nbsp;|&nbsp;<a href=/more/>更多<span style="font-family:宋体">>></span></a></p>
124
+ #
125
+ # puts find_html "p#km"
126
+ # # <a href=http://hi.baidu.com>空间</a>&nbsp;&nbsp;<a href=http://www.hao123.com>hao123</a>
127
+ # # &nbsp;|&nbsp;<a href=/more/>更多<span style="font-family:宋体">>></span></a>
128
+ #
129
+ # puts find_html "//p[@id='km']"
130
+ # # 与上同
131
+ def find_html(xpath)
132
+ raise "no any http request before!" if @response == nil
133
+ @hpricot ||= Hpricot(@response.body)
134
+ elems = @hpricot.search(xpath)
135
+ if block_given?
136
+ index = -1
137
+ elems = elems.select do |elem|
138
+ index = index + 1
139
+ yield elem,index
140
+ end
141
+ end
142
+ raise HtmlError, "find_html xpath[#{xpath}] is not exist!" if elems.empty?
143
+ return elems.first.html.force_encoding "gbk"
144
+ end
145
+
146
+ # === 功能:
147
+ # 使用XPath或CSS Selector来提取text内容,不会包含HTML标签
148
+ #
149
+ # === 参数解释:
150
+ # - xpath 定位,可以使xpath or selector
151
+ # - return 返回String
152
+ #
153
+ # === Example:
154
+ # Example #1:
155
+ #
156
+ # get "http://www.baidu.com/"
157
+ # # HTML片段如下
158
+ # # <p id=km><a href=http://hi.baidu.com>空间</a>&nbsp;&nbsp;
159
+ # # <a href=http://www.hao123.com>hao123</a>&nbsp;|&nbsp;<a href=/more/>更多<span style="font-family:宋体">
160
+ # # >></span></a></p>
161
+ #
162
+ # puts find_text "p#km"
163
+ # # => 空间&nbsp;&nbsp;hao123&nbsp;|&nbsp;更多>>
164
+ #
165
+ # puts find_text "//p[@id='km']"
166
+ # # 与上同
167
+ def find_text(xpath)
168
+ raise "no any http request before!" if @response == nil
169
+ @hpricot ||= Hpricot(@response.body)
170
+ elems = @hpricot.search(xpath)
171
+ if block_given?
172
+ index = -1
173
+ elems = elems.select do |elem|
174
+ index = index + 1
175
+ yield elem,index
176
+ end
177
+ end
178
+ raise HtmlError, "find_html xpath[#{xpath}] is not exist!" if elems.empty?
179
+ return elems.first.inner_text
180
+ end
181
+
182
+ # === 功能:
183
+ # 使用XPath或CSS Selector来提取HTML元素的属性值
184
+ #
185
+ # === 参数解释:
186
+ # - xpath 定位,可以使xpath or selector
187
+ # - attr 属性名
188
+ # - return 返回String
189
+ #
190
+ # === Example:
191
+ # Example #1:
192
+ #
193
+ # get "http://www.baidu.com/"
194
+ # # HTML片段如下
195
+ # # <p id=km><a href=http://hi.baidu.com>空间</a>&nbsp;&nbsp;<a href=http://www.hao123.com>hao123</a>&nbsp;|&nbsp;<a href=/more/>更多<span style="font-family:宋体">>></span></a></p>
196
+ #
197
+ # puts find_attr "p#km a:first", "href"
198
+ # # => http://hi.baidu.com
199
+ def find_attr(xpath, attr)
200
+ raise "no any http request before!" if @response == nil
201
+ @hpricot ||= Hpricot(@response.body)
202
+ elems = @hpricot.search(xpath)
203
+ if block_given?
204
+ index = -1
205
+ elems = elems.select do |elem|
206
+ index = index + 1
207
+ yield elem,index
208
+ end
209
+ end
210
+ raise HtmlError, "find_attr xpath[#{xpath}] is not exist!" if elems.empty?
211
+ elem = elems.first
212
+ raise HtmlError, "find_attr xpath[#{xpath}] ok, but elem[#{elem}] has no attr[#{attr}]!" unless elem.has_attribute? attr
213
+ return elem.get_attribute(attr)
214
+ end
215
+
216
+ # === 功能:
217
+ # 此方法不推荐使用,请使用 find_attr
218
+ def find_raw_attr(xpath, attr)
219
+ raise "no any http request before!" if @response == nil
220
+ @hpricot ||= Hpricot(@response.body)
221
+ elems = @hpricot.search(xpath.downcase)
222
+ if block_given?
223
+ index = -1
224
+ elems = elems.select do |elem|
225
+ index = index + 1
226
+ yield elem,index
227
+ end
228
+ end
229
+ raise HtmlError, "find_attr xpath[#{xpath}] is not exist!" if elems.empty?
230
+ elem = elems.first
231
+ raise HtmlError, "find_attr xpath[#{xpath}] ok, but elem[#{elem}] has no attr[#{attr}]!" unless elem.has_attribute? attr
232
+ return elem.raw_attributes[attr]
233
+ end
234
+
235
+
236
+ # === 功能:
237
+ # 使用XPath或CSS Selector来提取HTML元素集合的个数
238
+ #
239
+ # === 参数解释:
240
+ # - xpath 定位,可以使xpath or selector
241
+ # - return 返回Fixnum
242
+ #
243
+ # === Example:
244
+ # Example #1:
245
+ #
246
+ # get "http://www.baidu.com/"
247
+ # # HTML片段如下
248
+ # # <p id=km><a href=http://hi.baidu.com>空间</a>&nbsp;&nbsp;<a href=http://www.hao123.com>hao123</a>&nbsp;|&nbsp;<a href=/more/>更多<span style="font-family:宋体">>></span></a></p>
249
+ #
250
+ # puts find_size "p#km a"
251
+ # # => 3
252
+ # # 上层的意义可能是“输入框下面这一行显示3个超链接
253
+ def find_size(xpath)
254
+ raise "no any http request before!" if @response == nil
255
+ @hpricot ||= Hpricot(@response.body)
256
+ elems = @hpricot.search(xpath)
257
+ if block_given?
258
+ index = -1
259
+ elems = elems.select do |elem|
260
+ index = index + 1
261
+ yield elem,index
262
+ end
263
+ end
264
+ return elems.size
265
+ end
266
+
267
+ # 使用XPath或CSS Selector来提取HTML元素集合的个数
268
+ #
269
+ # === 参数解释:
270
+ # - xpath 父亲节点,可以使xpath or selector
271
+ # - excludes 排除的子节点名,长度可变参数
272
+ # - RETURN 返回非elems内的儿子节点集合
273
+ #
274
+ # === Example:
275
+ # get "http://hi.baidu.com/sys/search?word=我&from=wise"
276
+ # p find_children("entry > list > blog:first")
277
+ # #=> ["title", "content", "spsspaceurlorilist", "url", "time", "spsspacenamelist"]
278
+ # p find_children("entry > list > blog:first",%w{title content url time spsSpaceURLOriList})
279
+ # #=> ["spsspacenamelist"]
280
+ def find_children(xpath,excludes=[])
281
+ raise "no any http request before!" if @response == nil
282
+ @hpricot ||= Hpricot(@response.body)
283
+ elems = @hpricot.search(xpath)
284
+ if block_given?
285
+ index = -1
286
+ elems = elems.select do |elem|
287
+ index = index + 1
288
+ yield elem,index
289
+ end
290
+ end
291
+ raise HtmlError, "find_attr xpath[#{xpath}] is not exist!" if elems.empty?
292
+ elem = elems.first
293
+
294
+ rs = []
295
+ elem.children.each do |el|
296
+ if el.class == Hpricot::Elem and !excludes.include?(el.name)
297
+ rs << el.name
298
+ end
299
+ end
300
+ return rs
301
+ end
302
+
303
+
304
+ # === 功能:
305
+ # 高级接口,将 Hpricot 暴露出来,请参看 Hpricot 的使用手册
306
+ # 返回数组
307
+ #
308
+ # === 参数解释:
309
+ # - xpath 定位,可以使xpath or selector
310
+ # - return 返回Hpricot::Elems
311
+ #
312
+ # === Example:
313
+ # get "http://www.baidu.com"
314
+ # hpricot_search("div").each |elem|
315
+ # p elem
316
+ # end
317
+ def hpricot_search(xpath, &blk)
318
+ raise "no any http request before!" if @response == nil
319
+ @hpricot ||= Hpricot(@response.body)
320
+ @hpricot.search(xpath, &blk)
321
+ end
322
+
323
+
324
+ end
325
+
326
+
327
+ #
328
+ class HtmlError < StandardError
329
+ # TODO
330
+ end
331
+
332
+
333
+ if __FILE__ == $0
334
+ p __FILE__
335
+ p $0
336
+ class MyTest
337
+ include HtmlHelper
338
+
339
+ # 高级接口,将 Hpricot 暴露出来
340
+ def hpricot_search(xpath, &blk)
341
+ @hpricot ||= Hpricot("<tr><td>111</td><td id='q'>222</td><br/><td>333</td></tr>")
342
+ @hpricot.search(xpath, &blk)
343
+ end
344
+ def test
345
+ #post("http://passport.baidu.com/?login","username=hannyu5122&password=aaaa")
346
+ h = Hpricot("<tr><td>111</td><td id='q'>222</td><br/><td>333</td></tr>")
347
+ p h.search("tr td").text
348
+ p h.search("tr td#q").html
349
+ p h.search("tr td#q")[0]
350
+ p h.search("tr td#q")[0].next.html
351
+ p h.search("tr td")[0].get_attribute("id")
352
+ p h.search("tr td")[0].inner_text
353
+ p h.search("tr td#q")[0].html
354
+ p h.search("tt td")
355
+ p h.search("td").size
356
+ p h.search("tt td")[0].html
357
+ end
358
+
359
+ end
360
+ MyTest.new.test2
361
+ end
362
+
@@ -0,0 +1,469 @@
1
+ #!/usr/bin/env ruby
2
+ # coding: utf-8
3
+ #
4
+ # Author:: hanyu
5
+ # Date:: 2009.5.7
6
+
7
+ require 'net/http'
8
+ require 'net/https'
9
+ require 'cgi'
10
+ require 'uri'
11
+ require 'webrick'
12
+ require "common/http/multipart"
13
+
14
+ # 实现HTTP协议的支持,可以在action或case中调用
15
+ #
16
+ # - 封装 Net:HTTP 和 Net:HTTPS
17
+ # - 模拟浏览器的Cookie策略,不完全实现,不支持Expire(没必要)
18
+ # - 上下文环境的保持,request & response
19
+ # - 编码转换(统一使用gbk)
20
+ # - Referer、User-Agent等的自动填入
21
+ # - 打印可读日志
22
+ module HttpHelper
23
+
24
+ # === 功能:
25
+ # 发送POST请求
26
+ #
27
+ # === 参数解释:
28
+ # - url http请求的url,比如: http://hi.baidu.com/,前面的http和后面的/都不能省略
29
+ # - data post的数据,Hash格式,键可以是字符串或符号,值可以是字符串或其他
30
+ # - header http请求携带的header,比如referer、p3p等,形式与data类似
31
+ # - file 支持上传文件,可以传多个,Hash格式,键为参数名,值为文件的本地路径
32
+ #
33
+ # === Example:
34
+ # Example #1:
35
+ # # 模拟登录
36
+ # post "http://passport.baidu.com/?login", {
37
+ # :username => 'xxx',
38
+ # :password => 'yyy'
39
+ # }
40
+ #
41
+ # Example #2:
42
+ # # 自定义header
43
+ # login user
44
+ # post "http://hi.baidu.com/xxx/commit", {
45
+ # :ct => 1,
46
+ # :cm => 2,
47
+ # ........
48
+ # }, {
49
+ # "Myhead" => "okoko"
50
+ # }
51
+ #
52
+ # Example #3:
53
+ # post "http://hi.baidu.com/upload",{
54
+ # :xxx => 'yyy'
55
+ # }
56
+ # # 环境变量的注入
57
+ # puts @request.method
58
+ # puts @response.body
59
+ # puts @response.header["Content-Length"]
60
+ # puts @cookies
61
+ #
62
+ # Example #4:
63
+ # # 上传文件
64
+ # post "http://hi.baidu.com/upload",{
65
+ # :xxx => 'yyy'
66
+ # },{},{
67
+ # "param_name" => "file_path"
68
+ # }
69
+ #
70
+ def post(url,data={},header={},file={})
71
+ #解析成URI
72
+ $myparse = $myparse || URI::Parser.new(:RESERVED=>URI::REGEXP::PATTERN::RESERVED+"%")
73
+ uri = $myparse.parse $myparse.escape(url)
74
+ raise HttpError, "url[#{url}] parse fail! e.g. http://hi.baidu.com/" if uri.scheme.nil? or uri.host.nil? or uri.path.empty?
75
+
76
+ # CGI:URI.path 需要加上query部分才能构成一个正常的请求
77
+ path = (uri.query==nil) ? uri.path : uri.path+"?"+uri.query
78
+
79
+ # 把header符号变成字符串
80
+ header.each do |k,v|
81
+ if k.class == Symbol
82
+ header[k.to_s] = v.to_s
83
+ header.delete k
84
+ end
85
+ end
86
+
87
+ # 初始化Post请求
88
+ req = Net::HTTP::Post.new(path, header)
89
+ req.set_content_type "application/x-www-form-urlencoded" unless req.content_type
90
+
91
+ # 发送请求
92
+ send_http req,uri,data,file
93
+
94
+ end
95
+
96
+ # === 功能:
97
+ # 发送GET请求
98
+ #
99
+ # === 参数解释:
100
+ # - url http请求的url,比如: http://hi.baidu.com/,前面的http和后面的/都不能省略
101
+ # - data 数据将被编码并附在url的后面,Hash格式,键可以是字符串或符号,值可以是字符串或其他
102
+ # - header http请求携带的header,比如referer、p3p等,形式与data类似
103
+ #
104
+ # === Example:
105
+ # Example #1:
106
+ # # 注意url要写全,带上协议头"http",以及路径,若是根路径末尾要加"/"
107
+ # get "http://www.baidu.com/"
108
+ #
109
+ # Example #2:
110
+ # # 支持https
111
+ # get "https://passport.baidu.com/"
112
+ #
113
+ # Example #3:
114
+ # get "http://www.baidu.com/"
115
+ # # 环境变量的注入
116
+ # puts @request.method
117
+ # puts @response.body
118
+ # puts @response.header["Content-Length"]
119
+ # puts @cookies
120
+ #
121
+ # Example #4:
122
+ # # 可自定义 HTTP Header
123
+ # get "http://hi.baidu.com/",{
124
+ # :q => "空间",
125
+ # :t => "haha"
126
+ # },{
127
+ # "Cookie" => "BDUSS=xxx;",
128
+ # "Referer" => "google.com"
129
+ # }
130
+ #
131
+ # Example #5:
132
+ # # 带参数
133
+ # get "https://passport.baidu.com/",{
134
+ # :name => "walle",
135
+ # :password => "1111"
136
+ # }
137
+ #
138
+ def get(url,data={},header={})
139
+ #解析成URI
140
+ $myparse = $myparse || URI::Parser.new(:RESERVED=>URI::REGEXP::PATTERN::RESERVED+"%")
141
+ uri = $myparse.parse $myparse.escape(url)
142
+ raise HttpError, "url[#{url}] parse fail! e.g. http://hi.baidu.com/" if uri.scheme.nil? or uri.host.nil? or uri.path.empty?
143
+
144
+ # CGI:URI.path 需要加上query部分才能构成一个正常的请求
145
+ path = (uri.query==nil) ? uri.path : uri.path+"?"+uri.query
146
+
147
+ # 将data转成url中的参数
148
+ path << "?" if data.size>0 && !path.include?("?")
149
+ data.each do |k,v|
150
+ path << "&" if !path.end_with?("&") && !path.end_with?("?")
151
+ path << k.to_s + "=" + CGI::escape(v.to_s)
152
+ end
153
+
154
+ # 把header符号变成字符串
155
+ header.each do |k,v|
156
+ if k.class == Symbol
157
+ header[k.to_s] = v.to_s
158
+ header.delete k
159
+ end
160
+ end
161
+
162
+ # 初始化Get请求
163
+ req = Net::HTTP::Get.new(path, header)
164
+
165
+ # 发送请求
166
+ send_http req,uri
167
+
168
+ end
169
+
170
+ def download(uri, path=nil)
171
+ begin
172
+ if path
173
+ file_name = path + uri.split('/').last
174
+ file_name.sub(/\/\//, '/')
175
+ else
176
+ file_name = uri.split('/').last
177
+ end
178
+
179
+ file_content = get uri
180
+ #puts file_name
181
+ File.open(file_name, "w+") do |file|
182
+ file.binmode # must be in binary mode
183
+ file.write file_content
184
+ file.rewind
185
+ end
186
+ rescue => err
187
+ puts err
188
+ return ''
189
+ end
190
+ end
191
+
192
+ # === 功能:
193
+ # 发送PUT请求
194
+ # 未实现,有需求吗?
195
+ #
196
+ # === 参数解释:
197
+ #
198
+ # === Example:
199
+ #
200
+ def put(url,data="",header=nil,file=nil)
201
+ #TODO
202
+ end
203
+
204
+ # === 功能:
205
+ # 发送DELETE请求
206
+ # 未实现,有需求吗?
207
+ #
208
+ # === 参数解释:
209
+ #
210
+ # === Example:
211
+ #
212
+ def delete(url,data=nil,header=nil)
213
+ #TODO
214
+ end
215
+
216
+
217
+ # === 功能:
218
+ # 清空当前cookie
219
+ #
220
+ # === 参数解释:
221
+ #
222
+ # === Example:
223
+ # get "http://www.baidu.com/"
224
+ # clear_cookie # => 清空cookie
225
+ # get "http://hi.baidu.com/"
226
+ def clear_cookie
227
+ @cookies = {}
228
+ end
229
+
230
+ # === 功能:
231
+ # 指定不要进行转码
232
+ #
233
+ # === 参数解释:
234
+ #
235
+ # === Example:
236
+ # Example #1: block方式
237
+ #
238
+ # dont_encode do
239
+ # get "..."
240
+ # post "..."
241
+ # end
242
+ # # 凡是块里面的请求都不会有转码,但是块外面的代码仍然可以
243
+ #
244
+ # Example #2: 非block方式
245
+ #
246
+ # get "http://www.baidu.com/"
247
+ # # 返回页面经过转码,转成GBK
248
+ # dont_encode
249
+ # get "http://www.baidu.com/"
250
+ # # 返回页面在任何情况下都不会做任何转码
251
+ # # ...
252
+ # do_encode
253
+ # # 恢复转码方式
254
+ # get "http://www.baidu.com/"
255
+ # # 返回页面经过转码,转成GBK
256
+ def dont_encode
257
+ if block_given?
258
+ @dont_encode = true
259
+ yield
260
+ @dont_encode = false
261
+ else
262
+ @dont_encode = true
263
+ end
264
+ end
265
+
266
+ # === 功能:
267
+ # 参见dont_encode
268
+ def do_encode
269
+ if block_given?
270
+ @dont_encode = false
271
+ yield
272
+ @dont_encode = true
273
+ else
274
+ @dont_encode = false
275
+ end
276
+ end
277
+
278
+ # === 功能:
279
+ # 打印当前HTTP请求返回的content,可用于调试
280
+ #
281
+ # === 参数解释:
282
+ # 无
283
+ #
284
+ # === Example:
285
+ # get "http://www.baidu.com/"
286
+ # print_body
287
+ # #=> <html><head><meta http-equiv=Content-Type content="text/html;charset=gb2312"><title>百度一下,你就知道 </title>.....(省略)
288
+ #
289
+ def print_body
290
+ puts @response.body unless @response.nil?
291
+ end
292
+
293
+ # === 功能:
294
+ # 打印当前HTTP请求返回的所有Header,可用于调试
295
+ #
296
+ # === 参数解释:
297
+ # 无
298
+ #
299
+ # === Example:
300
+ # get "http://www.baidu.com/"
301
+ # print_head
302
+ # #=> {"date"=>["Sun, 27 Dec 2009 12:04:29 GMT"], "server"=>["BWS/1.0"], "content-length"=>["3657"], "content-type"=>["text/html;charset=gb2312"], "cache-control"=>["private"], "expires"=>["Sun, 27 Dec 2009 12:04:29 GMT"], "set-cookie"=>["BAIDUID=95C50755A927A287A68E2014CEF4CF1E:FG=1; expires=Sun, 27-Dec-39 12:04:29 GMT; path=/; domain=.baidu.com"], "p3p"=>["CP=\" OTI DSP COR IVA OUR IND COM \""]}
303
+ #
304
+ def print_head
305
+ puts @response.to_hash unless @response.nil?
306
+ end
307
+ alias print_header print_head
308
+
309
+ # 以下方法为私有
310
+ private
311
+
312
+ # 封装发送HTTP细节
313
+ def send_http(req,uri,data=nil,file={})
314
+ #注入上下文环境中的cookie
315
+ @cookies = {} if @cookies.nil?
316
+ @cookies.each do |key,coos|
317
+ if uri.host.end_with? key
318
+ coos.each do |coo|
319
+ if req.key? "cookie"
320
+ req["cookie"] += "#{coo.name}=#{coo.value};"
321
+ else
322
+ req["cookie"] = "#{coo.name}=#{coo.value};"
323
+ end
324
+ end
325
+ end
326
+ end
327
+
328
+ # 填入默认header
329
+ # req["User-Agent"] = "#{ConfigHelper::CONF['user_agent']}" if req["User-Agent"] == "Ruby"
330
+ # req["Referer"] = "#{@referer}" unless req.key? "referer"
331
+
332
+ # 如果上传文件,需要Multipart的支持
333
+ if file.size > 0
334
+ file.each do |k,v|
335
+ file[k] = File.new v
336
+ end
337
+ data_str, headers = Multipart::Post.prepare_query data.merge(file)
338
+ req["Content-Type"] = headers["Content-Type"]
339
+ else
340
+ #转义data
341
+ if data.nil?
342
+ data_str = nil
343
+ elsif data.kind_of? Hash
344
+ data_str = data.inject("") do |mem, (key, value)|
345
+ mem << "&" if mem.size > 0
346
+ mem << key.to_s + "=" + CGI::escape(value.to_s)
347
+ end
348
+ else
349
+ raise "data must be Hash"
350
+ end
351
+
352
+ end
353
+
354
+ #如果是HTTPS 安全连接
355
+ conn = Net::HTTP.new(uri.host, uri.port)
356
+ if uri.scheme == "https"
357
+ conn.use_ssl = true
358
+ conn.verify_mode = OpenSSL::SSL::VERIFY_NONE
359
+ end
360
+
361
+ take = 0
362
+ #加入异常捕获机器
363
+ begin
364
+ ts1 = Time.now
365
+ #发送HTTP请求
366
+ res = conn.start do |http|
367
+ #puts "data_str.size: #{data_str.size}" unless data_str.nil?
368
+ http.request(req,data_str)
369
+ end
370
+ ts2 = Time.now
371
+ take = ts2 - ts1
372
+ rescue SocketError => err
373
+ #域名不能解析,机器下线?
374
+ $log.error "#{req.method} url[#{uri}] data[#{data}] file[#{file}] time[#{take}s] FAIL! Host[#{uri.host}] is unknown! Maybe it is out of the DNS."
375
+ raise HttpError, "host[#{uri.host}] is unknown! Maybe it is out of the DNS."
376
+ rescue EOFError => err
377
+ #连接被中断,被transmit拒?
378
+ $log.error "#{req.method} url[#{uri}] data[#{data}] file[#{file}] time[#{take}s] FAIL! Connection with uri[#{uri}] is interrupted! Maybe transmit did this."
379
+ raise HttpError, "Connection with uri[#{uri}] is interrupted! Maybe transmit did this."
380
+ rescue SystemCallError => err
381
+ #服务被拒绝,端口未开放?
382
+ $log.error "#{req.method} url[#{uri}] data[#{data}] file[#{file}] time[#{take}s] FAIL! Connection with uri[#{uri}] is refused! Maybe the port[#{uri.port}] is not open."
383
+ raise HttpError, "Connection with uri[#{uri}] is refused! Maybe the port[#{uri.port}] is not open."
384
+ end
385
+ #将返回的cookie存入上下文环境中
386
+ if res.key?('set-cookie')
387
+ res.get_fields('set-cookie').each do |str|
388
+ cookie = WEBrick::Cookie.parse_set_cookie(str)
389
+ cookie.domain = uri.host if cookie.domain == nil
390
+ if @cookies.key?(cookie.domain)
391
+ @cookies[cookie.domain].delete_if do |coo|
392
+ coo.name == cookie.name
393
+ end
394
+ @cookies[cookie.domain] << cookie if cookie.value != "deleted"
395
+ else
396
+ @cookies[cookie.domain] = [cookie]
397
+ end
398
+ end
399
+ end
400
+
401
+ #置上下文变量
402
+ @referer = uri.to_s
403
+ @request = req
404
+ @response = res
405
+ @hpricot = nil
406
+
407
+ # #编码转换
408
+ # unless res.body.nil? or
409
+ # @dont_encode or
410
+ # res["Content-Type"].nil? or # 如果没有 content-type 字段,那么不做转换
411
+ # res["Content-Type"].include? "image" or # 图片不转
412
+ # res["Content-Type"].include? "video" or # 视频不转
413
+ # res["Content-Type"].include? "audio" # 声音不转
414
+ # ct = res["Content-Type"].scan(/charset=(.*?);?$/)[0]
415
+ # encod = ct[0].downcase unless ct.nil?
416
+ # if ! encod.nil?
417
+ # if encod=="gbk" or encod=="gb2312"
418
+ # res.body = res.body.force_encoding("gbk")
419
+ # else
420
+ # res.body = res.body.force_encoding(encod).encode "gbk"
421
+ # end
422
+ # else
423
+ # if ConfigHelper::CONF["default_encoding"]=="gbk"
424
+ # res.body = res.body.force_encoding("gbk")
425
+ # else
426
+ # res.body = res.body.force_encoding(ConfigHelper::CONF["default_encoding"]).encode "gbk"
427
+ # end
428
+ # end
429
+ # end
430
+ res.body
431
+ end
432
+
433
+ end
434
+
435
+ class HttpError < StandardError
436
+ # do nothing
437
+ end
438
+
439
+
440
+
441
+ if __FILE__ == $0
442
+ $LIB_ROOT = "#{File.dirname(__FILE__)}/.."
443
+ $TEST_ROOT = "#{$LIB_ROOT}/.."
444
+ $: << "#{$LIB_ROOT}"
445
+ require 'common/log_helper'
446
+ require 'common/config_helper'
447
+
448
+ class MyTest
449
+ include HttpHelper
450
+
451
+ def test1
452
+ @cookies = {}
453
+ #post("http://passport.baidu.com/?login","username=hannyu5122&password=aaaa")
454
+ get "http://www.baidu.com/"
455
+ puts @response.body
456
+ get "http://sz-testing-space07.sz01.baidu.com:5120/haoba?oko"
457
+ end
458
+ def test2
459
+ @cookies = {}
460
+ assert_raise HttpError do
461
+ get "http://db-testing-space13.db01.baidu.com:4444/developers"
462
+ #get "http://db-testing-space13.db01.baidu.com:8080/developers"
463
+ get "http://db-testing-sp.db01.baidu.com:8080/developers"
464
+ end
465
+ end
466
+ end
467
+ MyTest.new.test2
468
+ end
469
+