File: helper.rb

package info (click to toggle)
ruby-curb 1.2.2-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 860 kB
  • sloc: ansic: 5,798; ruby: 4,466; makefile: 4
file content (362 lines) | stat: -rw-r--r-- 9,957 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
# DO NOT REMOVE THIS COMMENT - PART OF TESTMODEL.
# Copyright (c)2006 Ross Bamford. See LICENSE.
$CURB_TESTING = true
require 'uri'
require 'stringio'
require 'digest/md5'

$TOPDIR = File.expand_path(File.join(File.dirname(__FILE__), '..'))
#$EXTDIR = File.join($TOPDIR, 'ext')
$LIBDIR = File.join($TOPDIR, 'lib')
$:.unshift($LIBDIR)
#$:.unshift($EXTDIR)

# Setup SimpleCov for Ruby code coverage if COVERAGE env var is set
if ENV['COVERAGE']
  begin
    require 'simplecov'
    require 'simplecov-lcov'
    
    SimpleCov::Formatter::LcovFormatter.config.report_with_single_file = true
    SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter.new([
      SimpleCov::Formatter::HTMLFormatter,
      SimpleCov::Formatter::LcovFormatter
    ])
    
    SimpleCov.start do
      add_filter '/tests/'
      add_filter '/spec/'
      add_filter '/vendor/'
      add_filter '/.bundle/'
      add_group 'Library', 'lib'
      add_group 'Extensions', 'ext'
      
      # Track branch coverage if available
      enable_coverage :branch if respond_to?(:enable_coverage)
    end
  rescue LoadError
    puts "SimpleCov not available. Install it with: gem install simplecov simplecov-lcov"
  end
end

require 'curb'
begin
  require 'test/unit'
rescue LoadError
  gem 'test/unit'
  require 'test/unit'
end
require 'fileutils'
require 'rbconfig'

# Platform helpers
WINDOWS = /mswin|msys|mingw|cygwin|bccwin|wince|emc|windows/i.match?(RbConfig::CONFIG['host_os'])
NO_FORK = !Process.respond_to?(:fork)

$TEST_URL = "file://#{'/' if RUBY_DESCRIPTION =~ /mswin|msys|mingw|cygwin|bccwin|wince|emc/}#{File.expand_path(__FILE__).tr('\\','/')}"

require 'thread'
require 'webrick'

# set this to true to avoid testing with multiple threads
# or to test with multiple threads set it to false
# this is important since, some code paths will change depending
# on the presence of multiple threads
TEST_SINGLE_THREADED=false

# keep webrick quiet
::WEBrick::HTTPServer.send(:remove_method,:access_log) if ::WEBrick::HTTPServer.instance_methods.include?(:access_log)
::WEBrick::BasicLog.send(:remove_method,:log) if ::WEBrick::BasicLog.instance_methods.include?(:log)

::WEBrick::HTTPServer.class_eval do
  def access_log(config, req, res)
    # nop
  end
end
::WEBrick::BasicLog.class_eval do
  def log(level, data)
    # nop
  end
end

#
# Simple test server to record number of times a request is sent/recieved of a specific
# request type, e.g. GET,POST,PUT,DELETE
#
class TestServlet < WEBrick::HTTPServlet::AbstractServlet

  def self.port=(p)
    @port = p
  end

  def self.port
    @port ||= 9129
  end

  def self.path
    '/methods'
  end
  def self.url
    "http://127.0.0.1:#{port}#{path}"
  end

  def respond_with(method,req,res)
    res.body = method.to_s
    $auth_header = req['Authorization']
    res['Content-Type'] = "text/plain"
  end

  def do_GET(req,res)
    if req.path.match(/redirect$/)
      res.status = 302
      res['Location'] = '/foo'
    elsif req.path.match(/not_here$/)
      res.status = 404
    elsif req.path.match(/error$/)
      res.status = 500
    elsif req.path.match(/get_cookies$/)
      res['Content-Type'] = "text/plain"
      res.body = req['Cookie']
      return
    end
    respond_with("GET#{req.query_string}",req,res)
  end

  def do_HEAD(req,res)
    res['Location'] = "/nonexistent"
    respond_with("HEAD#{req.query_string}",req,res)
  end

  def do_POST(req,res)
    if req.path.match(/set_cookies$/)
      JSON.parse(req.body || '[]', symbolize_names: true).each do |hash|
        cookie = WEBrick::Cookie.new(hash.fetch(:name), hash.fetch(:value))
        cookie.domain = hash[:domain] if hash.key?(:domain)
        cookie.expires = hash[:expires] if hash.key?(:expires)
        cookie.path = hash[:path] if hash.key?(:path)
        cookie.secure = hash[:secure] if hash.key?(:secure)
        cookie.max_age = hash[:max_age] if hash.key?(:max_age)
        res.cookies.push(cookie)
      end
      respond_with('OK', req, res)
    elsif req.query['filename'].nil?
      if req.body
        params = {}
        req.body.split('&').map{|s| k,v=s.split('='); params[k] = v }
      end
      if params and params['s'] == '500'
        res.status = 500
      elsif params and params['c']
        cookie = URI.decode_www_form_component(params['c']).split('=')
        res.cookies << WEBrick::Cookie.new(*cookie)
      else
        respond_with("POST\n#{req.body}",req,res)
      end
    else
      respond_with(req.query['filename'],req,res)
    end
  end

  def do_PUT(req,res)
    res['X-Requested-Content-Type'] = req.content_type
    respond_with("PUT\n#{req.body}",req,res)
  end

  def do_DELETE(req,res)
    respond_with("DELETE#{req.query_string}",req,res)
  end

  def do_PURGE(req,res)
    respond_with("PURGE#{req.query_string}",req,res)
  end

  def do_COPY(req,res)
    respond_with("COPY#{req.query_string}",req,res)
  end

  def do_PATCH(req,res)
    respond_with("PATCH\n#{req.body}",req,res)
  end

  def do_OPTIONS(req,res)
    respond_with("OPTIONS#{req.query_string}",req,res)
  end

end

module BugTestServerSetupTeardown
  def setup
    @port ||= 9992
    @server = WEBrick::HTTPServer.new( :Port => @port )
    @server.mount_proc("/test") do|req,res|
      if @response_proc
        @response_proc.call(res)
      else
        res.body = "hi"
        res['Content-Type'] = "text/html"
      end
    end

    @thread = Thread.new(@server) do|srv|
      srv.start
    end
  end

  def teardown
    while @server.status != :Shutdown
      @server.shutdown
    end
    @thread.join
  end
end

module TestServerMethods
  def locked_file
    File.join(File.dirname(__FILE__),"server_lock-#{@__port}")
  end

  def server_setup(port=9129,servlet=TestServlet)
    @__port = port
    if (@server ||= nil).nil? and !File.exist?(locked_file)
      File.open(locked_file,'w') {|f| f << 'locked' }
      if TEST_SINGLE_THREADED
        rd, wr = IO.pipe
        @__pid = fork do
          rd.close
          rd = nil

          # start up a webrick server for testing delete
          server = WEBrick::HTTPServer.new :Port => port, :DocumentRoot => File.expand_path(File.dirname(__FILE__))

          server.mount(servlet.path, servlet)
          server.mount("/tests", WEBrick::HTTPServlet::FileHandler, File.join(File.dirname(__FILE__),'..','tests'))

          trap("INT") { server.shutdown }
          GC.start
          wr.flush
          wr.close
          server.start
        end
        wr.close
        rd.read
        rd.close
      else
        # start up a webrick server for testing delete
        @server = WEBrick::HTTPServer.new :Port => port, :DocumentRoot => File.expand_path(File.dirname(__FILE__))

        @server.mount(servlet.path, servlet)
        @server.mount("/tests", WEBrick::HTTPServlet::FileHandler, File.join(File.dirname(__FILE__),'..','tests'))
        queue = Queue.new # synchronize the thread startup to the main thread

        @test_thread = Thread.new { queue << 1; @server.start }

        # wait for the queue
        value = queue.pop
        if !value
          STDERR.puts "Failed to startup test server!"
          exit(1)
        end

      end

      exit_code = lambda do
        begin
          if File.exist?(locked_file)
            File.unlink locked_file
            if TEST_SINGLE_THREADED
              Process.kill 'INT', @__pid
            else
              @server.shutdown unless @server.nil?
            end
          end
          #@server.shutdown unless @server.nil?
        rescue Object => e
          puts "Error #{__FILE__}:#{__LINE__}\n#{e.message}"
        end
      end

      trap("INT"){exit_code.call}
      at_exit{exit_code.call}

    end
  rescue Errno::EADDRINUSE
  end
end



# Backport for Ruby 1.8
module Backports
  module Ruby18
    module URIFormEncoding
      TBLENCWWWCOMP_ = {}
      TBLDECWWWCOMP_ = {}

      def encode_www_form_component(str)
        if TBLENCWWWCOMP_.empty?
          256.times do |i|
            TBLENCWWWCOMP_[i.chr] = '%%%02X' % i
          end
          TBLENCWWWCOMP_[' '] = '+'
          TBLENCWWWCOMP_.freeze
        end
        str.to_s.gsub( /([^*\-.0-9A-Z_a-z])/ ) {|*| TBLENCWWWCOMP_[$1] }
      end

      def decode_www_form_component(str)
        if TBLDECWWWCOMP_.empty?
          256.times do |i|
            h, l = i>>4, i&15
            TBLDECWWWCOMP_['%%%X%X' % [h, l]] = i.chr
            TBLDECWWWCOMP_['%%%x%X' % [h, l]] = i.chr
            TBLDECWWWCOMP_['%%%X%x' % [h, l]] = i.chr
            TBLDECWWWCOMP_['%%%x%x' % [h, l]] = i.chr
          end
          TBLDECWWWCOMP_['+'] = ' '
          TBLDECWWWCOMP_.freeze
        end

        raise ArgumentError, "invalid %-encoding (#{str.dump})" unless /\A(?:%[[:xdigit:]]{2}|[^%]+)*\z/ =~ str
        str.gsub( /(\+|%[[:xdigit:]]{2})/ ) {|*| TBLDECWWWCOMP_[$1] }
      end

      def encode_www_form( enum )
        enum.map do |k,v|
          if v.nil?
            encode_www_form_component(k)
          elsif v.respond_to?(:to_ary)
            v.to_ary.map do |w|
              str = encode_www_form_component(k)
              unless w.nil?
                str << '='
                str << encode_www_form_component(w)
              end
            end.join('&')
          else
            str = encode_www_form_component(k)
            str << '='
            str << encode_www_form_component(v)
          end
        end.join('&')
      end

      WFKV_ = '(?:%\h\h|[^%#=;&])'
      def decode_www_form(str, _)
        return [] if str.to_s == ''

        unless /\A#{WFKV_}=#{WFKV_}(?:[;&]#{WFKV_}=#{WFKV_})*\z/ =~ str
          raise ArgumentError, "invalid data of application/x-www-form-urlencoded (#{str})"
        end
        ary = []
        $&.scan(/([^=;&]+)=([^;&]*)/) do
          ary << [decode_www_form_component($1, enc), decode_www_form_component($2, enc)]
        end
        ary
      end
    end
  end
end

unless URI.methods.include?(:encode_www_form)
  URI.extend(Backports::Ruby18::URIFormEncoding)
end