stella 0.5.5 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (110) hide show
  1. data/CHANGES.txt +73 -0
  2. data/LICENSE.txt +19 -0
  3. data/README.rdoc +85 -0
  4. data/Rakefile +54 -59
  5. data/bin/example_test.rb +82 -0
  6. data/bin/example_webapp.rb +63 -0
  7. data/lib/{stella/logger.rb → logger.rb} +6 -11
  8. data/lib/stella.rb +76 -58
  9. data/lib/stella/clients.rb +161 -0
  10. data/lib/stella/command/base.rb +4 -24
  11. data/lib/stella/command/form.rb +36 -0
  12. data/lib/stella/command/get.rb +44 -0
  13. data/lib/stella/common.rb +53 -0
  14. data/lib/stella/crypto.rb +88 -0
  15. data/lib/stella/data/domain.rb +2 -2
  16. data/lib/stella/data/http.rb +155 -27
  17. data/lib/stella/environment.rb +66 -0
  18. data/lib/stella/functest.rb +105 -0
  19. data/lib/stella/loadtest.rb +186 -0
  20. data/lib/{utils → stella}/stats.rb +16 -20
  21. data/lib/stella/testplan.rb +237 -0
  22. data/lib/stella/testrunner.rb +64 -0
  23. data/lib/storable.rb +280 -0
  24. data/lib/threadify.rb +171 -0
  25. data/lib/timeunits.rb +65 -0
  26. data/lib/util/httputil.rb +266 -0
  27. data/stella.gemspec +69 -0
  28. data/tryouts/drb/drb_test.rb +65 -0
  29. data/tryouts/drb/open4.rb +19 -0
  30. data/tryouts/drb/slave.rb +27 -0
  31. data/tryouts/oo_tryout.rb +30 -0
  32. metadata +44 -138
  33. data/README.textile +0 -162
  34. data/bin/stella +0 -12
  35. data/bin/stella.bat +0 -12
  36. data/lib/daemonize.rb +0 -56
  37. data/lib/pcaplet.rb +0 -180
  38. data/lib/stella/adapter/ab.rb +0 -337
  39. data/lib/stella/adapter/base.rb +0 -106
  40. data/lib/stella/adapter/httperf.rb +0 -305
  41. data/lib/stella/adapter/pcap_watcher.rb +0 -221
  42. data/lib/stella/adapter/proxy_watcher.rb +0 -76
  43. data/lib/stella/adapter/siege.rb +0 -341
  44. data/lib/stella/cli.rb +0 -258
  45. data/lib/stella/cli/agents.rb +0 -73
  46. data/lib/stella/cli/base.rb +0 -55
  47. data/lib/stella/cli/language.rb +0 -18
  48. data/lib/stella/cli/localtest.rb +0 -78
  49. data/lib/stella/cli/sysinfo.rb +0 -16
  50. data/lib/stella/cli/watch.rb +0 -278
  51. data/lib/stella/command/localtest.rb +0 -358
  52. data/lib/stella/response.rb +0 -85
  53. data/lib/stella/storable.rb +0 -204
  54. data/lib/stella/support.rb +0 -276
  55. data/lib/stella/sysinfo.rb +0 -257
  56. data/lib/stella/test/definition.rb +0 -79
  57. data/lib/stella/test/run/summary.rb +0 -70
  58. data/lib/stella/test/stats.rb +0 -114
  59. data/lib/stella/text.rb +0 -64
  60. data/lib/stella/text/resource.rb +0 -38
  61. data/lib/utils/crypto-key.rb +0 -84
  62. data/lib/utils/domainutil.rb +0 -47
  63. data/lib/utils/escape.rb +0 -302
  64. data/lib/utils/fileutil.rb +0 -78
  65. data/lib/utils/httputil.rb +0 -266
  66. data/lib/utils/mathutil.rb +0 -15
  67. data/lib/utils/textgraph.rb +0 -267
  68. data/lib/utils/timerutil.rb +0 -58
  69. data/lib/win32/Console.rb +0 -970
  70. data/lib/win32/Console/ANSI.rb +0 -305
  71. data/support/kvm.h +0 -91
  72. data/support/ruby-pcap-takuma-notes.txt +0 -19
  73. data/support/ruby-pcap-takuma-patch.txt +0 -30
  74. data/support/text/en.yaml +0 -80
  75. data/support/text/nl.yaml +0 -7
  76. data/support/useragents.txt +0 -75
  77. data/tests/01-util_test.rb +0 -0
  78. data/tests/02-stella-util_test.rb +0 -42
  79. data/tests/10-stella_test.rb +0 -104
  80. data/tests/11-stella-storable_test.rb +0 -68
  81. data/tests/60-stella-command_test.rb +0 -248
  82. data/tests/80-stella-cli_test.rb +0 -45
  83. data/tests/spec-helper.rb +0 -31
  84. data/vendor/drydock/LICENSE.txt +0 -22
  85. data/vendor/drydock/README.textile +0 -57
  86. data/vendor/drydock/bin/example +0 -170
  87. data/vendor/drydock/drydock.gemspec +0 -18
  88. data/vendor/drydock/lib/drydock.rb +0 -232
  89. data/vendor/drydock/lib/drydock/exceptions.rb +0 -24
  90. data/vendor/drydock/test/command_test.rb +0 -33
  91. data/vendor/useragent/MIT-LICENSE +0 -20
  92. data/vendor/useragent/README +0 -21
  93. data/vendor/useragent/init.rb +0 -1
  94. data/vendor/useragent/lib/user_agent.rb +0 -83
  95. data/vendor/useragent/lib/user_agent/browsers.rb +0 -24
  96. data/vendor/useragent/lib/user_agent/browsers/all.rb +0 -69
  97. data/vendor/useragent/lib/user_agent/browsers/gecko.rb +0 -43
  98. data/vendor/useragent/lib/user_agent/browsers/internet_explorer.rb +0 -40
  99. data/vendor/useragent/lib/user_agent/browsers/opera.rb +0 -49
  100. data/vendor/useragent/lib/user_agent/browsers/webkit.rb +0 -94
  101. data/vendor/useragent/lib/user_agent/comparable.rb +0 -25
  102. data/vendor/useragent/lib/user_agent/operating_systems.rb +0 -19
  103. data/vendor/useragent/spec/browsers/gecko_user_agent_spec.rb +0 -209
  104. data/vendor/useragent/spec/browsers/internet_explorer_user_agent_spec.rb +0 -99
  105. data/vendor/useragent/spec/browsers/opera_user_agent_spec.rb +0 -59
  106. data/vendor/useragent/spec/browsers/other_user_agent_spec.rb +0 -19
  107. data/vendor/useragent/spec/browsers/webkit_user_agent_spec.rb +0 -373
  108. data/vendor/useragent/spec/spec_helper.rb +0 -1
  109. data/vendor/useragent/spec/user_agent_spec.rb +0 -331
  110. data/vendor/useragent/useragent.gemspec +0 -12
@@ -1,47 +0,0 @@
1
-
2
- require 'net/dns/packet'
3
-
4
- module DomainUtil
5
-
6
- def DomainUtil.parse_domain_request(data=[])
7
- return unless data && !data.empty?
8
- data = data.split(/\r?\n/) unless data.kind_of? Array
9
- data.shift while (data[0].empty? || data[0].nil?) # Remove leading empties
10
-
11
- dns_data = Net::DNS::Packet.parse( data.join($/) )
12
- return unless dns_data.header.query?
13
- domain_name = dns_data.question[0].qName
14
- return dns_data, domain_name, dns_data.header
15
- end
16
-
17
- def DomainUtil.parse_domain_response(data=[])
18
- return unless data && !data.empty?
19
- data = data.split(/\r?\n/) unless data.kind_of? Array
20
- data.shift while (data[0].empty? || data[0].nil?) # Remove leading empties
21
-
22
- # This is the heavy lifting.
23
- dns_data = Net::DNS::Packet.parse( data.join($/) )
24
-
25
- # We don't want queries or empty answers
26
- return if dns_data.header.query? || dns_data.answer.nil? || dns_data.answer.empty?
27
-
28
- domain_name = dns_data.answer[0].name
29
-
30
- # Empty the lists if they are already populated
31
- addresses = []
32
- cnames = []
33
-
34
- # Store the CNAMEs associated to this domain. Can be empty.
35
- dns_data.each_cname do |cname|
36
- cnames << cname.to_s
37
- end
38
-
39
- # Store the IP address for this domain. If empty, the lookup was unsuccessful.
40
- dns_data.each_address do |ip|
41
- addresses << ip.to_s
42
- end
43
-
44
- return dns_data, domain_name, dns_data.header, addresses, cnames
45
- end
46
-
47
- end
data/lib/utils/escape.rb DELETED
@@ -1,302 +0,0 @@
1
- # escape.rb - escape/unescape library for several formats
2
- #
3
- # Copyright (C) 2006,2007 Tanaka Akira <akr@fsij.org>
4
- #
5
- # Redistribution and use in source and binary forms, with or without
6
- # modification, are permitted provided that the following conditions are met:
7
- #
8
- # 1. Redistributions of source code must retain the above copyright notice, this
9
- # list of conditions and the following disclaimer.
10
- # 2. Redistributions in binary form must reproduce the above copyright notice,
11
- # this list of conditions and the following disclaimer in the documentation
12
- # and/or other materials provided with the distribution.
13
- # 3. The name of the author may not be used to endorse or promote products
14
- # derived from this software without specific prior written permission.
15
- #
16
- # THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
17
- # WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18
- # MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
19
- # EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20
- # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
21
- # OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22
- # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23
- # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
24
- # IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
25
- # OF SUCH DAMAGE.
26
-
27
- # Escape module provides several escape functions.
28
- # * URI
29
- # * HTML
30
- # * shell command
31
- module EscapeUtil
32
- module_function
33
-
34
- class StringWrapper
35
- class << self
36
- alias new_no_dup new
37
- def new(str)
38
- new_no_dup(str.dup)
39
- end
40
- end
41
-
42
- def initialize(str)
43
- @str = str
44
- end
45
-
46
- def to_s
47
- @str.dup
48
- end
49
-
50
- def inspect
51
- "\#<#{self.class}: #{@str}>"
52
- end
53
-
54
- def ==(other)
55
- other.class == self.class && @str == other.instance_variable_get(:@str)
56
- end
57
- alias eql? ==
58
-
59
- def hash
60
- @str.hash
61
- end
62
- end
63
-
64
- class ShellEscaped < StringWrapper
65
- end
66
-
67
- # Escape.shell_command composes
68
- # a sequence of words to
69
- # a single shell command line.
70
- # All shell meta characters are quoted and
71
- # the words are concatenated with interleaving space.
72
- # It returns an instance of ShellEscaped.
73
- #
74
- # Escape.shell_command(["ls", "/"]) #=> #<Escape::ShellEscaped: ls />
75
- # Escape.shell_command(["echo", "*"]) #=> #<Escape::ShellEscaped: echo '*'>
76
- #
77
- # Note that system(*command) and
78
- # system(Escape.shell_command(command)) is roughly same.
79
- # There are two exception as follows.
80
- # * The first is that the later may invokes /bin/sh.
81
- # * The second is an interpretation of an array with only one element:
82
- # the element is parsed by the shell with the former but
83
- # it is recognized as single word with the later.
84
- # For example, system(*["echo foo"]) invokes echo command with an argument "foo".
85
- # But system(Escape.shell_command(["echo foo"])) invokes "echo foo" command without arguments (and it probably fails).
86
- def shell_command(command)
87
- s = command.map {|word| shell_single_word(word) }.join(' ')
88
- ShellEscaped.new_no_dup(s)
89
- end
90
-
91
- # Escape.shell_single_word quotes shell meta characters.
92
- # It returns an instance of ShellEscaped.
93
- #
94
- # The result string is always single shell word, even if
95
- # the argument is "".
96
- # Escape.shell_single_word("") returns #<Escape::ShellEscaped: ''>.
97
- #
98
- # Escape.shell_single_word("") #=> #<Escape::ShellEscaped: ''>
99
- # Escape.shell_single_word("foo") #=> #<Escape::ShellEscaped: foo>
100
- # Escape.shell_single_word("*") #=> #<Escape::ShellEscaped: '*'>
101
- def shell_single_word(str)
102
- if str && str.empty?
103
- ShellEscaped.new_no_dup("''")
104
- elsif %r{\A[0-9A-Za-z+,./:=@_-]+\z} =~ str
105
- ShellEscaped.new(str)
106
- else
107
- result = ''
108
- str.scan(/('+)|[^']+/) {
109
- if $1
110
- result << %q{\'} * $1.length
111
- else
112
- result << "'#{$&}'"
113
- end
114
- }
115
- ShellEscaped.new_no_dup(result)
116
- end
117
- end
118
-
119
- class PercentEncoded < StringWrapper
120
- end
121
-
122
- # Escape.uri_segment escapes URI segment using percent-encoding.
123
- # It returns an instance of PercentEncoded.
124
- #
125
- # Escape.uri_segment("a/b") #=> #<Escape::PercentEncoded: a%2Fb>
126
- #
127
- # The segment is "/"-splitted element after authority before query in URI, as follows.
128
- #
129
- # scheme://authority/segment1/segment2/.../segmentN?query#fragment
130
- #
131
- # See RFC 3986 for details of URI.
132
- def uri_segment(str)
133
- # pchar - pct-encoded = unreserved / sub-delims / ":" / "@"
134
- # unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
135
- # sub-delims = "!" / "$" / "&" / "'" / "(" / ")" / "*" / "+" / "," / ";" / "="
136
- s = str.gsub(%r{[^A-Za-z0-9\-._~!$&'()*+,;=:@]}n) {
137
- '%' + $&.unpack("H2")[0].upcase
138
- }
139
- PercentEncoded.new_no_dup(s)
140
- end
141
-
142
- # Escape.uri_path escapes URI path using percent-encoding.
143
- # The given path should be a sequence of (non-escaped) segments separated by "/".
144
- # The segments cannot contains "/".
145
- # It returns an instance of PercentEncoded.
146
- #
147
- # Escape.uri_path("a/b/c") #=> #<Escape::PercentEncoded: a/b/c>
148
- # Escape.uri_path("a?b/c?d/e?f") #=> #<Escape::PercentEncoded: a%3Fb/c%3Fd/e%3Ff>
149
- #
150
- # The path is the part after authority before query in URI, as follows.
151
- #
152
- # scheme://authority/path#fragment
153
- #
154
- # See RFC 3986 for details of URI.
155
- #
156
- # Note that this function is not appropriate to convert OS path to URI.
157
- def uri_path(str)
158
- s = str.gsub(%r{[^/]+}n) { uri_segment($&) }
159
- PercentEncoded.new_no_dup(s)
160
- end
161
-
162
- # :stopdoc:
163
- def html_form_fast(pairs, sep='&')
164
- s = pairs.map {|k, v|
165
- # query-chars - pct-encoded - x-www-form-urlencoded-delimiters =
166
- # unreserved / "!" / "$" / "'" / "(" / ")" / "*" / "," / ":" / "@" / "/" / "?"
167
- # query-char - pct-encoded = unreserved / sub-delims / ":" / "@" / "/" / "?"
168
- # query-char = pchar / "/" / "?" = unreserved / pct-encoded / sub-delims / ":" / "@" / "/" / "?"
169
- # unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
170
- # sub-delims = "!" / "$" / "&" / "'" / "(" / ")" / "*" / "+" / "," / ";" / "="
171
- # x-www-form-urlencoded-delimiters = "&" / "+" / ";" / "="
172
- k = k.gsub(%r{[^0-9A-Za-z\-\._~:/?@!\$'()*,]}n) {
173
- '%' + $&.unpack("H2")[0].upcase
174
- }
175
- v = v.gsub(%r{[^0-9A-Za-z\-\._~:/?@!\$'()*,]}n) {
176
- '%' + $&.unpack("H2")[0].upcase
177
- }
178
- "#{k}=#{v}"
179
- }.join(sep)
180
- PercentEncoded.new_no_dup(s)
181
- end
182
- # :startdoc:
183
-
184
- # Escape.html_form composes HTML form key-value pairs as a x-www-form-urlencoded encoded string.
185
- # It returns an instance of PercentEncoded.
186
- #
187
- # Escape.html_form takes an array of pair of strings or
188
- # an hash from string to string.
189
- #
190
- # Escape.html_form([["a","b"], ["c","d"]]) #=> #<Escape::PercentEncoded: a=b&c=d>
191
- # Escape.html_form({"a"=>"b", "c"=>"d"}) #=> #<Escape::PercentEncoded: a=b&c=d>
192
- #
193
- # In the array form, it is possible to use same key more than once.
194
- # (It is required for a HTML form which contains
195
- # checkboxes and select element with multiple attribute.)
196
- #
197
- # Escape.html_form([["k","1"], ["k","2"]]) #=> #<Escape::PercentEncoded: k=1&k=2>
198
- #
199
- # If the strings contains characters which must be escaped in x-www-form-urlencoded,
200
- # they are escaped using %-encoding.
201
- #
202
- # Escape.html_form([["k=","&;="]]) #=> #<Escape::PercentEncoded: k%3D=%26%3B%3D>
203
- #
204
- # The separator can be specified by the optional second argument.
205
- #
206
- # Escape.html_form([["a","b"], ["c","d"]], ";") #=> #<Escape::PercentEncoded: a=b;c=d>
207
- #
208
- # See HTML 4.01 for details.
209
- def html_form(pairs, sep='&')
210
- r = ''
211
- first = true
212
- pairs.each {|k, v|
213
- # query-chars - pct-encoded - x-www-form-urlencoded-delimiters =
214
- # unreserved / "!" / "$" / "'" / "(" / ")" / "*" / "," / ":" / "@" / "/" / "?"
215
- # query-char - pct-encoded = unreserved / sub-delims / ":" / "@" / "/" / "?"
216
- # query-char = pchar / "/" / "?" = unreserved / pct-encoded / sub-delims / ":" / "@" / "/" / "?"
217
- # unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
218
- # sub-delims = "!" / "$" / "&" / "'" / "(" / ")" / "*" / "+" / "," / ";" / "="
219
- # x-www-form-urlencoded-delimiters = "&" / "+" / ";" / "="
220
- r << sep if !first
221
- first = false
222
- k.each_byte {|byte|
223
- ch = byte.chr
224
- if %r{[^0-9A-Za-z\-\._~:/?@!\$'()*,]}n =~ ch
225
- r << "%" << ch.unpack("H2")[0].upcase
226
- else
227
- r << ch
228
- end
229
- }
230
- r << '='
231
- v.each_byte {|byte|
232
- ch = byte.chr
233
- if %r{[^0-9A-Za-z\-\._~:/?@!\$'()*,]}n =~ ch
234
- r << "%" << ch.unpack("H2")[0].upcase
235
- else
236
- r << ch
237
- end
238
- }
239
- }
240
- PercentEncoded.new_no_dup(r)
241
- end
242
-
243
- class HTMLEscaped < StringWrapper
244
- end
245
-
246
- # :stopdoc:
247
- HTML_TEXT_ESCAPE_HASH = {
248
- '&' => '&amp;',
249
- '<' => '&lt;',
250
- '>' => '&gt;',
251
- }
252
- # :startdoc:
253
-
254
- # Escape.html_text escapes a string appropriate for HTML text using character references.
255
- # It returns an instance of HTMLEscaped.
256
- #
257
- # It escapes 3 characters:
258
- # * '&' to '&amp;'
259
- # * '<' to '&lt;'
260
- # * '>' to '&gt;'
261
- #
262
- # Escape.html_text("abc") #=> #<Escape::HTMLEscaped: abc>
263
- # Escape.html_text("a & b < c > d") #=> #<Escape::HTMLEscaped: a &amp; b &lt; c &gt; d>
264
- #
265
- # This function is not appropriate for escaping HTML element attribute
266
- # because quotes are not escaped.
267
- def html_text(str)
268
- s = str.gsub(/[&<>]/) {|ch| HTML_TEXT_ESCAPE_HASH[ch] }
269
- HTMLEscaped.new_no_dup(s)
270
- end
271
-
272
- # :stopdoc:
273
- HTML_ATTR_ESCAPE_HASH = {
274
- '&' => '&amp;',
275
- '<' => '&lt;',
276
- '>' => '&gt;',
277
- '"' => '&quot;',
278
- }
279
- # :startdoc:
280
-
281
- class HTMLAttrValue < StringWrapper
282
- end
283
-
284
- # Escape.html_attr_value encodes a string as a double-quoted HTML attribute using character references.
285
- # It returns an instance of HTMLAttrValue.
286
- #
287
- # Escape.html_attr_value("abc") #=> #<Escape::HTMLAttrValue: "abc">
288
- # Escape.html_attr_value("a&b") #=> #<Escape::HTMLAttrValue: "a&amp;b">
289
- # Escape.html_attr_value("ab&<>\"c") #=> #<Escape::HTMLAttrValue: "ab&amp;&lt;&gt;&quot;c">
290
- # Escape.html_attr_value("a'c") #=> #<Escape::HTMLAttrValue: "a'c">
291
- #
292
- # It escapes 4 characters:
293
- # * '&' to '&amp;'
294
- # * '<' to '&lt;'
295
- # * '>' to '&gt;'
296
- # * '"' to '&quot;'
297
- #
298
- def html_attr_value(str)
299
- s = '"' + str.gsub(/[&<>"]/) {|ch| HTML_ATTR_ESCAPE_HASH[ch] } + '"'
300
- HTMLAttrValue.new_no_dup(s)
301
- end
302
- end
@@ -1,78 +0,0 @@
1
- require 'fileutils'
2
-
3
- module FileUtil
4
-
5
- def FileUtil.read_file(path)
6
- FileUtil.read_file_to_array(path).join('')
7
- end
8
-
9
- def FileUtil.read_file_to_array(path)
10
- contents = []
11
- return contents unless File.exists?(path)
12
-
13
- open(path, 'r') do |l|
14
- contents = l.readlines
15
- end
16
-
17
- contents
18
- end
19
- def FileUtil.read_binary_file(path)
20
- contents = ''
21
- return contents unless File.exists?(path)
22
-
23
- open(path, 'rb') do |l|
24
- while (!l.eof?)
25
- contents << l.read(4096)
26
- end
27
- end
28
-
29
- contents
30
- end
31
-
32
-
33
-
34
- def FileUtil.write_file(path, content, flush=true)
35
- FileUtil.write_or_append_file('w', path, content, flush)
36
- end
37
-
38
- def FileUtil.append_file(path, content, flush=true)
39
- FileUtil.write_or_append_file('a', path, content, flush)
40
- end
41
-
42
- def FileUtil.write_or_append_file(write_or_append, path, content = '', flush = true)
43
- #STDERR.puts "Writing to #{ path }..."
44
- FileUtil.create_dir(File.dirname(path))
45
-
46
- open(path, write_or_append) do |f|
47
- f.puts content
48
- f.flush if flush;
49
- end
50
- File.chmod(0600, path)
51
- end
52
-
53
- def FileUtil.create_file(filepath, perm='w', file_perms=nil, force=false)
54
- raise Exception.new("File #{filepath} already exists!") if File.exists?(filepath) && !force
55
-
56
- newfile = File.new(filepath, perm)
57
- begin
58
- if file_perms && File.exists?(file_perms)
59
- File.chown(File.stat(file_perms).uid.to_i, File.stat(file_perms).gid.to_i, filepath)
60
- end
61
- rescue NotImplementedError => ex
62
- end
63
-
64
- newfile
65
- end
66
-
67
- def FileUtil.create_dir(dirpath, dir_perms=nil)
68
- return if File.directory?(dirpath)
69
-
70
- #STDERR.puts "Creating #{ dirpath }"
71
- FileUtils.makedirs(dirpath)
72
-
73
- if dir_perms && File.exists?(dir_perms)
74
- File.chown(File.stat(dir_perms).uid.to_i, File.stat(dir_perms).gid.to_i, dirpath)
75
- end
76
-
77
- end
78
- end
@@ -1,266 +0,0 @@
1
-
2
- require 'uri'
3
- require 'timeout'
4
- require 'net/http'
5
-
6
- module HTTPUtil
7
- VALID_METHODS = %w{GET HEAD POST PUT DELETE}
8
- @@timeout = 20
9
-
10
- # Takes a string. See WEBrick::parse_header(string).
11
- def HTTPUtil.parse_header(raw)
12
- header = Hash.new([].freeze)
13
- raw.each_line do |line|
14
- case line
15
- when /\A(.+?):\s+(.+)\z/om
16
- name, value = $1, $2
17
- name = name.tr('-', '_').to_sym
18
- value.strip!
19
-
20
- header[name] = [] unless header.has_key?(name)
21
- header[name] << value
22
- end
23
- end
24
- header
25
- end
26
-
27
- # Takes a string or array. See parse_header_body for further info.
28
- # Returns +method+, +http_version+, +uri+, +header+, +body+
29
- def HTTPUtil.parse_http_request(data, host=:unknown, port=80)
30
- return unless data && !data.empty?
31
- data = data.split(/\r?\n/) unless data.kind_of? Array
32
- data.shift while (data[0].empty? || data[0].nil?) # Remove leading empties
33
- request_line = data.shift # i.e. GET /path HTTP/1.1
34
- method, path, http_version = nil
35
-
36
- # With WEBrick and other proxies, the entire URI is included in HTTP requests.
37
- # i.e. GET http://stellaaahhhh.com/streetcar.png HTTP/1.1
38
- # The parser is expecting just the absolute path.
39
- if request_line =~ /^(\S+)\s+(http:\/\/.+)\s+(HTTP.+)?/mo
40
- uri = URI.parse($2)
41
- request_line = "#{$1} #{uri.request_uri} #{$3}"
42
- host = uri.host
43
- end
44
-
45
- if request_line =~ /^(\S+)\s+(\S+)(?:\s+HTTP\/(\d+\.\d+))?/mo
46
- method = $1
47
- http_version = $3 # Comes before $2 b/c the split resets the numbered vars
48
- path, query_string = $2.split('?')
49
-
50
- # We only process the header and body data when we know we're
51
- # starting from the beginning of a request string. We don't
52
- # want no partials.
53
- header, body = HTTPUtil.parse_header_body(data)
54
- query = HTTPUtil.parse_query(method, query_string)
55
-
56
-
57
- # TODO: Parse username/password
58
- uri = URI::HTTP.build({
59
- :scheme => 'http',
60
- :host => header[:Host][0] || host.to_s,
61
- :port => port,
62
- :path => path,
63
- :query => query_string
64
- })
65
-
66
- else
67
- rl = request_line.sub(/\x0d?\x0a\z/o, '')
68
- raise "Bad Request-Line `#{rl}'."
69
- end
70
-
71
- return method, http_version, uri, header, body
72
- end
73
-
74
-
75
- # Takes a string or array. See parse_header_body for further info.
76
- # Returns +status+, +http_version+, +message+, +header+, +body+
77
- def HTTPUtil.parse_http_response(data=[])
78
- return unless data && !data.empty?
79
- data = data.split(/\r?\n/) unless data.kind_of? Array
80
- data.shift while (data[0].empty? || data[0].nil?) # Remove leading empties
81
- status_line = data.shift # ie. HTTP/1.1 200 OK
82
- http_version, status, message = nil
83
-
84
- if status_line =~ /^HTTP\/(\d.+?)(\s+(\d\d\d)\s+(.+))?$/mo
85
- http_version = $1
86
- status = $2
87
- message = $4
88
-
89
- header, body, query = HTTPUtil.parse_header_body(data)
90
-
91
- else
92
- raise "Bad Response-Line `#{status_line}'."
93
- end
94
-
95
- return status, http_version, message, header, body
96
- end
97
-
98
- # Process everything after the first line of an HTTP request or response:
99
- # GET / HTTP/1.1
100
- # HTTP/1.1 200 OK
101
- # etc...
102
- # Used by parse_http_request and parse_http_response but can be used separately.
103
- # Takes a string or array of strings. A string should be formatted like an HTTP
104
- # request or response. If a body is present it should be separated by two newlines.
105
- # An array of string should contain an empty or nil element between the header
106
- # and body content. This will happen naturally if the raw lines were split by
107
- # a single line terminator. (i.e. /\n/ rather than /\n\n/)
108
- # Returns header (hash), body (string)
109
- def HTTPUtil.parse_header_body(data=[])
110
- header, body = {}, nil
111
- data = data.split(/\r?\n/) unless data.kind_of? Array
112
- data.shift while (data[0].nil? || data[0].empty?) # Remove leading empties
113
-
114
- return header, body unless data && !data.empty?
115
-
116
- #puts data.to_yaml
117
-
118
- # Skip that first line if it exists
119
- data.shift if data[0].match(/\AHTTP|GET|POST|DELETE|PUT|HEAD/mo)
120
-
121
- header_lines = []
122
- header_lines << data.shift while (!data[0].nil? && !data[0].empty?)
123
- header = HTTPUtil::parse_header(header_lines.join($/))
124
-
125
- # We omit the blank line that delimits the header from the body
126
- body = data[1..-1].join($/) unless data.empty?
127
-
128
- return header, body
129
- end
130
-
131
- def HTTPUtil.parse_query(request_method, query_string, content_type='', body='')
132
- query = Hash.new([].freeze)
133
-
134
- if request_method == "GET" || request_method == "HEAD"
135
- query = HTTPUtil::parse_query_from_string(query_string)
136
- elsif content_type =~ /^application\/x-www-form-urlencoded/
137
- query = HTTPUtil::parse_query_from_string(body)
138
- elsif content_type =~ /^multipart\/form-data; boundary=(.+)/
139
- boundary = $1.tr('"', '')
140
- query = HTTPUtil::parse_form_data(body, boundary)
141
- else
142
- query
143
- end
144
-
145
- query
146
- end
147
-
148
- def HTTPUtil.validate_method(meth='GET')
149
- (VALID_METHODS.member? meth.upcase) ? meth : VALID_METHODS[0]
150
- end
151
-
152
- # Parses a query string by breaking it up at the '&'
153
- # and ';' characters. You can also use this to parse
154
- # cookies by changing the characters used in the second
155
- # parameter (which defaults to '&;'.
156
- # Stolen from Mongrel
157
- def HTTPUtil.parse_query_from_string(qs, d = '&;')
158
- params = {}
159
- (qs||'').split(/[#{d}] */n).inject(params) { |h,p|
160
- k, v=unescape(p).split('=',2)
161
- next unless k
162
- k = k.tr('-', '_').to_sym
163
- if cur = params[k]
164
- if cur.class == Array
165
- params[k] << v
166
- else
167
- params[k] = [cur, v]
168
- end
169
- else
170
- params[k] = v
171
- end
172
- }
173
-
174
- return params
175
- end
176
-
177
-
178
-
179
- # Based on WEBrick::HTTPutils::parse_form_data
180
- def HTTPUtil.parse_form_data(io, boundary)
181
- boundary_regexp = /\A--#{boundary}(--)?#{$/}\z/
182
- form_data = Hash.new
183
- return form_data unless io
184
- data = nil
185
- io.each_line{|line|
186
- if boundary_regexp =~ line
187
- if data
188
- data.chop!
189
- key = data.name.tr('-', '_').to_sym
190
- if form_data.has_key?(key)
191
- form_data[key].append_data(data)
192
- else
193
- form_data[key] = data
194
- end
195
- end
196
- data = FormData.new
197
- next
198
- else
199
- if data
200
- data << line
201
- end
202
- end
203
- }
204
- return form_data
205
- end
206
-
207
-
208
- # Extend the basic query string parser provided by the cgi module.
209
- # converts single valued params (the most common case) to
210
- # objects instead of arrays
211
- #
212
- # Input:
213
- # the query string
214
- #
215
- # Output:
216
- # hash of parameters, contains arrays for multivalued parameters
217
- # (multiselect, checkboxes , etc)
218
- # If no query string is provided (nil or "") returns an empty hash.
219
- def HTTPUtil.query_to_hash(query_string)
220
- return {} unless query_string
221
-
222
- query_parameters = HTTPUtil.parse_query(query_string)
223
-
224
- query_parameters.each { |key, val|
225
- # replace the array with an object
226
- query_parameters[key] = val[0] if 1 == val.length
227
- }
228
-
229
- # set default value to nil! cgi sets this to []
230
- query_parameters.default = nil
231
-
232
- return query_parameters
233
- end
234
-
235
- def HTTPUtil.hash_to_query(parameters)
236
- return '' unless parameters
237
- pairs = []
238
- parameters.each do |param, value|
239
- pairs << "#{param}=#{URI.escape(value.to_s)}"
240
- end
241
- return pairs.join('&')
242
- #return pairs.join(";")
243
- end
244
-
245
-
246
-
247
- # Performs URI escaping so that you can construct proper
248
- # query strings faster. Use this rather than the cgi.rb
249
- # version since it's faster. (Stolen from Mongrel/Camping).
250
- def HTTPUtil.escape(s)
251
- s.to_s.gsub(/([^ a-zA-Z0-9_.-]+)/n) {
252
- '%'+$1.unpack('H2'*$1.size).join('%').upcase
253
- }.tr(' ', '+')
254
- end
255
-
256
-
257
- # Unescapes a URI escaped string. (Stolen from Mongrel/Camping).
258
- def HTTPUtil.unescape(s)
259
- s.tr('+', ' ').gsub(/((?:%[0-9a-fA-F]{2})+)/n){
260
- [$1.delete('%')].pack('H*')
261
- }
262
- end
263
-
264
-
265
- end
266
-