super-test 1.0.9

Sign up to get free protection for your applications and to get access to all the features.
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
+