ghazel-curb 0.5.9.0

Sign up to get free protection for your applications and to get access to all the features.
data/ext/extconf.rb ADDED
@@ -0,0 +1,162 @@
1
+ require 'mkmf'
2
+
3
+ dir_config('curl')
4
+
5
+ if find_executable('curl-config')
6
+ $CFLAGS << " #{`curl-config --cflags`.strip}"
7
+ if ENV['STATIC_BUILD']
8
+ $LIBS << " #{`curl-config --static-libs`.strip}"
9
+ else
10
+ $LIBS << " #{`curl-config --libs`.strip}"
11
+ end
12
+ ca_bundle_path=`curl-config --ca`.strip
13
+ if !ca_bundle_path.nil? and ca_bundle_path != ''
14
+ $defs.push( %{-D HAVE_CURL_CONFIG_CA} )
15
+ $defs.push( %{-D CURL_CONFIG_CA='#{ca_bundle_path.inspect}'} )
16
+ end
17
+ elsif !have_library('curl') or !have_header('curl/curl.h')
18
+ fail <<-EOM
19
+ Can't find libcurl or curl/curl.h
20
+
21
+ Try passing --with-curl-dir or --with-curl-lib and --with-curl-include
22
+ options to extconf.
23
+ EOM
24
+ end
25
+
26
+ # Check arch flags
27
+ archs = $CFLAGS.scan(/-arch\s(.*?)\s/).first # get the first arch flag
28
+ if archs and archs.size >= 1
29
+ # need to reduce the number of archs...
30
+ # guess the first one is correct... at least the first one is probably the ruby installed arch...
31
+ # this could lead to compiled binaries that crash at runtime...
32
+ $CFLAGS.gsub!(/-arch\s(.*?)\s/,' ')
33
+ $CFLAGS << " -arch #{archs.first}"
34
+ puts "Selected arch: #{archs.first}"
35
+ end
36
+
37
+ def define(s)
38
+ $defs.push( format("-D HAVE_%s", s.to_s.upcase) )
39
+ end
40
+
41
+ def have_constant(name)
42
+ checking_for name do
43
+ src = %{
44
+ #include <curl/curl.h>
45
+ int main() {
46
+ int test = (int)#{name.upcase};
47
+ return 0;
48
+ }
49
+ }
50
+ if try_compile(src,"#{$CFLAGS} #{$LIBS}")
51
+ define name
52
+ true
53
+ else
54
+ false
55
+ end
56
+ end
57
+ end
58
+
59
+ have_constant "curlinfo_redirect_time"
60
+ have_constant "curlinfo_response_code"
61
+ have_constant "curlinfo_filetime"
62
+ have_constant "curlinfo_redirect_count"
63
+ have_constant "curlinfo_os_errno"
64
+ have_constant "curlinfo_num_connects"
65
+ have_constant "curlinfo_ftp_entry_path"
66
+ have_constant "curl_version_ssl"
67
+ have_constant "curl_version_libz"
68
+ have_constant "curl_version_ntlm"
69
+ have_constant "curl_version_gssnegotiate"
70
+ have_constant "curl_version_debug"
71
+ have_constant "curl_version_asynchdns"
72
+ have_constant "curl_version_spnego"
73
+ have_constant "curl_version_largefile"
74
+ have_constant "curl_version_idn"
75
+ have_constant "curl_version_sspi"
76
+ have_constant "curl_version_conv"
77
+ have_constant "curlproxy_http"
78
+ have_constant "curlproxy_socks4"
79
+ have_constant "curlproxy_socks5"
80
+ have_constant "curlauth_basic"
81
+ have_constant "curlauth_digest"
82
+ have_constant "curlauth_gssnegotiate"
83
+ have_constant "curlauth_ntlm"
84
+ have_constant "curlauth_anysafe"
85
+ have_constant "curlauth_any"
86
+ have_constant "curle_tftp_notfound"
87
+ have_constant "curle_tftp_perm"
88
+ have_constant "curle_tftp_diskfull"
89
+ have_constant "curle_tftp_illegal"
90
+ have_constant "curle_tftp_unknownid"
91
+ have_constant "curle_tftp_exists"
92
+ have_constant "curle_tftp_nosuchuser"
93
+ # older versions of libcurl 7.12
94
+ have_constant "curle_send_fail_rewind"
95
+ have_constant "curle_ssl_engine_initfailed"
96
+ have_constant "curle_login_denied"
97
+
98
+ # older than 7.16.3
99
+ have_constant "curlmopt_maxconnects"
100
+
101
+ # additional consts
102
+ have_constant "curle_conv_failed"
103
+ have_constant "curle_conv_reqd"
104
+ have_constant "curle_ssl_cacert_badfile"
105
+ have_constant "curle_remote_file_not_found"
106
+ have_constant "curle_ssh"
107
+ have_constant "curle_ssl_shutdown_failed"
108
+ have_constant "curle_again"
109
+ have_constant "curle_ssl_crl_badfile"
110
+ have_constant "curle_ssl_issuer_error"
111
+
112
+ # centos 4.5 build of libcurl
113
+ have_constant "curlm_bad_socket"
114
+ have_constant "curlm_unknown_option"
115
+ have_func("curl_multi_timeout")
116
+ have_func("curl_multi_fdset")
117
+ have_func("curl_multi_perform")
118
+
119
+ if try_compile('int main() { return 0; }','-Wall')
120
+ $CFLAGS << ' -Wall'
121
+ end
122
+
123
+ # do some checking to detect ruby 1.8 hash.c vs ruby 1.9 hash.c
124
+ def test_for(name, const, src)
125
+ checking_for name do
126
+ if try_compile(src,"#{$CFLAGS} #{$LIBS}")
127
+ define const
128
+ true
129
+ else
130
+ false
131
+ end
132
+ end
133
+ end
134
+ test_for("Ruby 1.9 Hash", "RUBY19_HASH", %{
135
+ #include <ruby.h>
136
+ int main() {
137
+ VALUE hash = rb_hash_new();
138
+ if( RHASH(hash)->ntbl->num_entries ) {
139
+ return 0;
140
+ }
141
+ return 1;
142
+ }
143
+ })
144
+ test_for("Ruby 1.9 st.h", "RUBY19_ST_H", %{
145
+ #include <ruby.h>
146
+ #include <ruby/st.h>
147
+ int main() {
148
+ return 0;
149
+ }
150
+ })
151
+
152
+ test_for("curl_easy_escape", "CURL_EASY_ESCAPE", %{
153
+ #include <curl/curl.h>
154
+ int main() {
155
+ CURL *easy = curl_easy_init();
156
+ curl_easy_escape(easy,"hello",5);
157
+ return 0;
158
+ }
159
+ })
160
+
161
+ create_header('curb_config.h')
162
+ create_makefile('curb_core')
data/lib/curb.rb ADDED
@@ -0,0 +1,184 @@
1
+ require 'curb_core'
2
+
3
+ module Curl
4
+ class Easy
5
+ class << self
6
+
7
+ # call-seq:
8
+ # Curl::Easy.download(url, filename = url.split(/\?/).first.split(/\//).last) { |curl| ... }
9
+ #
10
+ # Stream the specified url (via perform) and save the data directly to the
11
+ # supplied filename (defaults to the last component of the URL path, which will
12
+ # usually be the filename most simple urls).
13
+ #
14
+ # If a block is supplied, it will be passed the curl instance prior to the
15
+ # perform call.
16
+ #
17
+ # *Note* that the semantics of the on_body handler are subtly changed when using
18
+ # download, to account for the automatic routing of data to the specified file: The
19
+ # data string is passed to the handler *before* it is written
20
+ # to the file, allowing the handler to perform mutative operations where
21
+ # necessary. As usual, the transfer will be aborted if the on_body handler
22
+ # returns a size that differs from the data chunk size - in this case, the
23
+ # offending chunk will *not* be written to the file, the file will be closed,
24
+ # and a Curl::Err::AbortedByCallbackError will be raised.
25
+ def download(url, filename = url.split(/\?/).first.split(/\//).last, &blk)
26
+ curl = Curl::Easy.new(url, &blk)
27
+
28
+ File.open(filename, "wb") do |output|
29
+ old_on_body = curl.on_body do |data|
30
+ result = old_on_body ? old_on_body.call(data) : data.length
31
+ output << data if result == data.length
32
+ result
33
+ end
34
+
35
+ curl.perform
36
+ end
37
+
38
+ return curl
39
+ end
40
+ end
41
+
42
+ # Allow the incoming cert string to be file:password
43
+ # but be careful to not use a colon from a windows file path
44
+ # as the split point. Mimic what curl's main does
45
+ alias_method :native_cert=, :cert=
46
+ def cert=(cert_file)
47
+ pos = cert_file.rindex(':')
48
+ if pos && pos > 1
49
+ self.native_cert= cert_file[0..pos-1]
50
+ self.certpassword= cert_file[pos+1..-1]
51
+ else
52
+ self.native_cert= cert_file
53
+ end
54
+ self.cert
55
+ end
56
+ end
57
+ class Multi
58
+ class << self
59
+ # call-seq:
60
+ # Curl::Multi.get('url1','url2','url3','url4','url5', :follow_location => true) do|easy|
61
+ # easy
62
+ # end
63
+ #
64
+ # Blocking call to fetch multiple url's in parallel.
65
+ def get(urls, easy_options={}, multi_options={}, &blk)
66
+ url_confs = []
67
+ urls.each do|url|
68
+ url_confs << {:url => url, :method => :get}.merge(easy_options)
69
+ end
70
+ self.http(url_confs, multi_options) {|c,code,method| blk.call(c) }
71
+ end
72
+
73
+ # call-seq:
74
+ #
75
+ # Curl::Multi.post([{:url => 'url1', :post_fields => {'field1' => 'value1', 'field2' => 'value2'}},
76
+ # {:url => 'url2', :post_fields => {'field1' => 'value1', 'field2' => 'value2'}},
77
+ # {:url => 'url3', :post_fields => {'field1' => 'value1', 'field2' => 'value2'}}],
78
+ # { :follow_location => true, :multipart_form_post => true },
79
+ # {:pipeline => true }) do|easy|
80
+ # easy_handle_on_request_complete
81
+ # end
82
+ #
83
+ # Blocking call to POST multiple form's in parallel.
84
+ #
85
+ # urls_with_config: is a hash of url's pointing to the postfields to send
86
+ # easy_options: are a set of common options to set on all easy handles
87
+ # multi_options: options to set on the Curl::Multi handle
88
+ #
89
+ def post(urls_with_config, easy_options={}, multi_options={}, &blk)
90
+ url_confs = []
91
+ urls_with_config.each do|uconf|
92
+ url_confs << uconf.merge(:method => :post).merge(easy_options)
93
+ end
94
+ self.http(url_confs, multi_options) {|c,code,method| blk.call(c) }
95
+ end
96
+
97
+ # call-seq:
98
+ #
99
+ # Curl::Multi.put([{:url => 'url1', :put_data => "some message"},
100
+ # {:url => 'url2', :put_data => IO.read('filepath')},
101
+ # {:url => 'url3', :put_data => "maybe another string or socket?"],
102
+ # {:follow_location => true},
103
+ # {:pipeline => true }) do|easy|
104
+ # easy_handle_on_request_complete
105
+ # end
106
+ #
107
+ # Blocking call to POST multiple form's in parallel.
108
+ #
109
+ # urls_with_config: is a hash of url's pointing to the postfields to send
110
+ # easy_options: are a set of common options to set on all easy handles
111
+ # multi_options: options to set on the Curl::Multi handle
112
+ #
113
+ def put(urls_with_config, easy_options={}, multi_options={}, &blk)
114
+ url_confs = []
115
+ urls_with_config.each do|uconf|
116
+ url_confs << uconf.merge(:method => :put).merge(easy_options)
117
+ end
118
+ self.http(url_confs, multi_options) {|c,code,method| blk.call(c) }
119
+ end
120
+
121
+
122
+ # call-seq:
123
+ #
124
+ # Curl::Multi.http( [
125
+ # { :url => 'url1', :method => :post,
126
+ # :post_fields => {'field1' => 'value1', 'field2' => 'value2'} },
127
+ # { :url => 'url2', :method => :get,
128
+ # :follow_location => true, :max_redirects => 3 },
129
+ # { :url => 'url3', :method => :put, :put_data => File.open('file.txt','rb') },
130
+ # { :url => 'url4', :method => :head }
131
+ # ], {:pipeline => true})
132
+ #
133
+ # Blocking call to issue multiple HTTP requests with varying verb's.
134
+ #
135
+ # urls_with_config: is a hash of url's pointing to the easy handle options as well as the special option :method, that can by one of [:get, :post, :put, :delete, :head], when no verb is provided e.g. :method => nil -> GET is used
136
+ # multi_options: options for the multi handle
137
+ # blk: a callback, that yeilds when a handle is completed
138
+ #
139
+ def http(urls_with_config, multi_options={}, &blk)
140
+ m = Curl::Multi.new
141
+ # configure the multi handle
142
+ multi_options.each { |k,v| m.send("#{k}=", v) }
143
+
144
+ urls_with_config.each do|conf|
145
+ c = conf.dup # avoid being destructive to input
146
+ url = c.delete(:url)
147
+ method = c.delete(:method)
148
+ headers = c.delete(:headers)
149
+
150
+ easy = Curl::Easy.new(url)
151
+
152
+ case method
153
+ when :post
154
+ fields = c.delete(:post_fields)
155
+ # set the post post using the url fields
156
+ easy.post_body = fields.map{|f,k| "#{easy.escape(f)}=#{easy.escape(k)}"}.join('&')
157
+ when :put
158
+ easy.put_data = c.delete(:put_data)
159
+ when :head
160
+ easy.head = true
161
+ when :delete
162
+ easy.delete = true
163
+ when :get
164
+ else
165
+ # XXX: nil is treated like a GET
166
+ end
167
+
168
+ # headers is a special key
169
+ headers.each {|k,v| easy.headers[k] = v } if headers
170
+
171
+ #
172
+ # use the remaining options as specific configuration to the easy handle
173
+ # bad options should raise an undefined method error
174
+ #
175
+ c.each { |k,v| easy.send("#{k}=",v) }
176
+
177
+ easy.on_complete {|curl,code| blk.call(curl,code,method) } if blk
178
+ m.add(easy)
179
+ end
180
+ m.perform
181
+ end
182
+ end
183
+ end
184
+ end
data/lib/curl.rb ADDED
@@ -0,0 +1,2 @@
1
+ require 'curb'
2
+
data/tests/alltests.rb ADDED
@@ -0,0 +1,3 @@
1
+ $: << $TESTDIR = File.expand_path(File.dirname(__FILE__))
2
+ require 'unittests'
3
+ Dir[File.join($TESTDIR, 'bug_*.rb')].each { |lib| require lib }
@@ -0,0 +1,52 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), 'helper'))
2
+ require 'webrick'
3
+ class ::WEBrick::HTTPServer ; def access_log(config, req, res) ; end ; end
4
+ class ::WEBrick::BasicLog ; def log(level, data) ; end ; end
5
+
6
+ class BugTestInstancePostDiffersFromClassPost < Test::Unit::TestCase
7
+ def test_bug
8
+ server = WEBrick::HTTPServer.new( :Port => 9999 )
9
+ server.mount_proc("/test") do|req,res|
10
+ sleep 0.5
11
+ res.body = "hi"
12
+ res['Content-Type'] = "text/html"
13
+ end
14
+
15
+ thread = Thread.new(server) do|srv|
16
+ srv.start
17
+ end
18
+
19
+ threads = []
20
+ timer = Time.now
21
+
22
+ 5.times do |i|
23
+ t = Thread.new do
24
+ c = Curl::Easy.perform('http://localhost:9999/test')
25
+ c.header_str
26
+ end
27
+ threads << t
28
+ end
29
+
30
+ multi_responses = threads.collect do|t|
31
+ t.value
32
+ end
33
+
34
+ multi_time = (Time.now - timer)
35
+ puts "requested in #{multi_time}"
36
+
37
+ timer = Time.now
38
+ single_responses = []
39
+ 5.times do |i|
40
+ c = Curl::Easy.perform('http://localhost:9999/test')
41
+ single_responses << c.header_str
42
+ end
43
+
44
+ single_time = (Time.now - timer)
45
+ puts "requested in #{single_time}"
46
+
47
+ assert single_time > multi_time
48
+
49
+ server.shutdown
50
+ thread.join
51
+ end
52
+ end
@@ -0,0 +1,53 @@
1
+ # From Vlad Jebelev:
2
+ #
3
+ # - Second thing - I think you just probably didn't have the time to update
4
+ # instance methods yet but when I POST with a reusal of a previous curl
5
+ # instance, it doesnt' work for me, e.g. when I create a curl previously and
6
+ # then issue:
7
+ #
8
+ # c.http_post(login_url, *fields)
9
+ #
10
+ # instead of:
11
+ #
12
+ # c = Curl::Easy.http_post(login_url, *fields) do |curl|
13
+ # ...
14
+ # end
15
+ #
16
+ # then the result I am getting is quite different.
17
+ #
18
+ # ================
19
+ #
20
+ # Update:
21
+ #
22
+ # It seems that class httpost is incorrectly passing arguments down to
23
+ # instance httppost. This bug is intermittent, but results in an
24
+ # exception from the first post when it occurs.
25
+ #
26
+ require File.expand_path(File.join(File.dirname(__FILE__), 'helper'))
27
+
28
+ class BugTestInstancePostDiffersFromClassPost < Test::Unit::TestCase
29
+ def test_bug
30
+ 5.times do |i|
31
+ puts "Test ##{i}"
32
+ do_test
33
+ sleep 2
34
+ end
35
+ end
36
+
37
+ def do_test
38
+ c = Curl::Easy.http_post('https://www.google.com/accounts/ServiceLoginAuth',
39
+ Curl::PostField.content('ltmpl','m_blanco'))
40
+ body_c, header_c = c.body_str, c.header_str
41
+
42
+ sleep 2
43
+
44
+ c.http_post('https://www.google.com/accounts/ServiceLoginAuth',
45
+ Curl::PostField.content('ltmpl','m_blanco'))
46
+ body_i, header_i = c.body_str, c.header_str
47
+
48
+ # timestamps will differ, just check first bit. We wont get here if
49
+ # the bug bites anyway...
50
+ assert_equal header_c[0..50], header_i[0..50]
51
+ end
52
+ end
53
+
@@ -0,0 +1,10 @@
1
+ # From safis http://github.com/taf2/curb/issues#issue/5
2
+ # irb: require 'curb'
3
+ # irb: multi = Curl::Multi.new
4
+ # irb: exit
5
+ # <main>:47140: [BUG] Bus Error
6
+ $:.unshift File.expand_path(File.join(File.dirname(__FILE__),'..','ext'))
7
+ $:.unshift File.expand_path(File.join(File.dirname(__FILE__),'..','lib'))
8
+ require 'curb'
9
+ multi = Curl::Multi.new
10
+ exit
@@ -0,0 +1,40 @@
1
+ # From Vlad Jebelev:
2
+ #
3
+ # - if I have a require statement after "require 'curb'" and there is a
4
+ # POST with at least 1 field, the script will fail with a segmentation
5
+ # fault, e.g. the following sequence fails every time for me (Ruby 1.8.5):
6
+ # -----------------------------------------------------------------
7
+ # require 'curb'
8
+ # require 'uri'
9
+ #
10
+ # url = 'https://www.google.com/accounts/ServiceLoginAuth'
11
+ #
12
+ # c = Curl::Easy.http_post(
13
+ # 'https://www.google.com/accounts/ServiceLoginAuth',
14
+ # [Curl:: PostField.content('ltmpl','m_blanco')] ) do |curl|
15
+ # end
16
+ # ------------------------------------------------------------------
17
+ # :..dev/util$ ruby seg.rb
18
+ # seg.rb:6: [BUG] Segmentation fault
19
+ # ruby 1.8.5 (2006-08-25) [i686-linux]
20
+ #
21
+ # Aborted
22
+ # ------------------------------------------------------------------
23
+ #
24
+ require 'test/unit'
25
+ require 'rbconfig'
26
+
27
+ $rubycmd = Config::CONFIG['RUBY_INSTALL_NAME'] || 'ruby'
28
+
29
+ class BugTestRequireLastOrSegfault < Test::Unit::TestCase
30
+ def test_bug
31
+ 5.times do |i|
32
+ puts "Test ##{i}"
33
+
34
+ # will be empty string if it segfaults...
35
+ assert_equal 'success', `#$rubycmd #{File.dirname(__FILE__)}/require_last_or_segfault_script.rb`.chomp
36
+ sleep 5
37
+ end
38
+ end
39
+ end
40
+
data/tests/helper.rb ADDED
@@ -0,0 +1,168 @@
1
+ # DO NOT REMOVE THIS COMMENT - PART OF TESTMODEL.
2
+ # Copyright (c)2006 Ross Bamford. See LICENSE.
3
+ $CURB_TESTING = true
4
+ require 'uri'
5
+
6
+ $TOPDIR = File.expand_path(File.join(File.dirname(__FILE__), '..'))
7
+ $EXTDIR = File.join($TOPDIR, 'ext')
8
+ $LIBDIR = File.join($TOPDIR, 'lib')
9
+ $:.unshift($LIBDIR)
10
+ $:.unshift($EXTDIR)
11
+
12
+ require 'curb'
13
+ require 'test/unit'
14
+
15
+ $TEST_URL = "file://#{URI.escape(File.expand_path(__FILE__).tr('\\','/').tr(':','|'))}"
16
+
17
+ require 'thread'
18
+ require 'webrick'
19
+
20
+ # set this to true to avoid testing with multiple threads
21
+ # or to test with multiple threads set it to false
22
+ # this is important since, some code paths will change depending
23
+ # on the presence of multiple threads
24
+ TEST_SINGLE_THREADED=false
25
+
26
+ # keep webrick quiet
27
+ class ::WEBrick::HTTPServer
28
+ def access_log(config, req, res)
29
+ # nop
30
+ end
31
+ end
32
+ class ::WEBrick::BasicLog
33
+ def log(level, data)
34
+ # nop
35
+ end
36
+ end
37
+
38
+ #
39
+ # Simple test server to record number of times a request is sent/recieved of a specific
40
+ # request type, e.g. GET,POST,PUT,DELETE
41
+ #
42
+ class TestServlet < WEBrick::HTTPServlet::AbstractServlet
43
+
44
+ def self.port=(p)
45
+ @port = p
46
+ end
47
+
48
+ def self.port
49
+ (@port or 9129)
50
+ end
51
+
52
+ def self.path
53
+ '/methods'
54
+ end
55
+
56
+ def self.url
57
+ "http://127.0.0.1:#{port}#{path}"
58
+ end
59
+
60
+ def respond_with(method,req,res)
61
+ res.body = method.to_s
62
+ res['Content-Type'] = "text/plain"
63
+ end
64
+
65
+ def do_GET(req,res)
66
+ respond_with(:GET,req,res)
67
+ end
68
+
69
+ def do_HEAD(req,res)
70
+ res['Location'] = "/nonexistent"
71
+ respond_with(:HEAD, req, res)
72
+ end
73
+
74
+ def do_POST(req,res)
75
+ if req.body
76
+ params = {}
77
+ req.body.split('&').map{|s| k,v=s.split('='); params[k] = v }
78
+ end
79
+ if params and params['s'] == '500'
80
+ res.status = 500
81
+ else
82
+ respond_with("POST\n#{req.body}",req,res)
83
+ end
84
+ end
85
+
86
+ def do_PUT(req,res)
87
+ res['X-Requested-Content-Type'] = req.content_type
88
+ respond_with("PUT\n#{req.body}",req,res)
89
+ end
90
+
91
+ def do_DELETE(req,res)
92
+ respond_with(:DELETE,req,res)
93
+ end
94
+
95
+ end
96
+
97
+ module TestServerMethods
98
+ def locked_file
99
+ File.join(File.dirname(__FILE__),"server_lock-#{@__port}")
100
+ end
101
+
102
+ def server_setup(port=9129,servlet=TestServlet)
103
+ @__port = port
104
+ if @server.nil? and !File.exist?(locked_file)
105
+
106
+ File.open(locked_file,'w') {|f| f << 'locked' }
107
+ if TEST_SINGLE_THREADED
108
+ rd, wr = IO.pipe
109
+ @__pid = fork do
110
+ rd.close
111
+ rd = nil
112
+
113
+ # start up a webrick server for testing delete
114
+ server = WEBrick::HTTPServer.new :Port => port, :DocumentRoot => File.expand_path(File.dirname(__FILE__))
115
+
116
+ server.mount(servlet.path, servlet)
117
+ server.mount("/ext", WEBrick::HTTPServlet::FileHandler, File.join(File.dirname(__FILE__),'..','ext'))
118
+
119
+ trap("INT") { server.shutdown }
120
+ GC.start
121
+ wr.flush
122
+ wr.close
123
+ server.start
124
+ end
125
+ wr.close
126
+ rd.read
127
+ rd.close
128
+ else
129
+ # start up a webrick server for testing delete
130
+ @server = WEBrick::HTTPServer.new :Port => port, :DocumentRoot => File.expand_path(File.dirname(__FILE__))
131
+
132
+ @server.mount(servlet.path, servlet)
133
+ @server.mount("/ext", WEBrick::HTTPServlet::FileHandler, File.join(File.dirname(__FILE__),'..','ext'))
134
+ queue = Queue.new # synchronize the thread startup to the main thread
135
+
136
+ @test_thread = Thread.new { queue << 1; @server.start }
137
+
138
+ # wait for the queue
139
+ value = queue.pop
140
+ if !value
141
+ STDERR.puts "Failed to startup test server!"
142
+ exit(1)
143
+ end
144
+
145
+ end
146
+
147
+ exit_code = lambda do
148
+ begin
149
+ if File.exist?(locked_file)
150
+ File.unlink locked_file
151
+ if TEST_SINGLE_THREADED
152
+ Process.kill 'INT', @__pid
153
+ else
154
+ @server.shutdown unless @server.nil?
155
+ end
156
+ end
157
+ #@server.shutdown unless @server.nil?
158
+ rescue Object => e
159
+ puts "Error #{__FILE__}:#{__LINE__}\n#{e.message}"
160
+ end
161
+ end
162
+
163
+ trap("INT"){exit_code.call}
164
+ at_exit{exit_code.call}
165
+
166
+ end
167
+ end
168
+ end