simplehttp 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/AUTHORS ADDED
@@ -0,0 +1 @@
1
+ Tim Becker (tim@kuriositaet.de)
File without changes
data/LICENSE ADDED
@@ -0,0 +1,58 @@
1
+ This package is copyrighted free software by Tim Becker <tim@kuriositaet.de>.
2
+ You can redistribute it and/or modify it under either the terms of the GPL
3
+ (see COPYING.txt file), or the conditions below:
4
+
5
+ 1. You may make and give away verbatim copies of the source form of the
6
+ software without restriction, provided that you duplicate all of the
7
+ original copyright notices and associated disclaimers.
8
+
9
+ 2. You may modify your copy of the software in any way, provided that
10
+ you do at least ONE of the following:
11
+
12
+ a) place your modifications in the Public Domain or otherwise
13
+ make them Freely Available, such as by posting said
14
+ modifications to Usenet or an equivalent medium, or by allowing
15
+ the author to include your modifications in the software.
16
+
17
+ b) use the modified software only within your corporation or
18
+ organization.
19
+
20
+ c) rename any non-standard executables so the names do not conflict
21
+ with standard executables, which must also be provided.
22
+
23
+ d) make other distribution arrangements with the author.
24
+
25
+ 3. You may distribute the software in object code or executable
26
+ form, provided that you do at least ONE of the following:
27
+
28
+ a) distribute the executables and library files of the software,
29
+ together with instructions (in the manual page or equivalent)
30
+ on where to get the original distribution.
31
+
32
+ b) accompany the distribution with the machine-readable source of
33
+ the software.
34
+
35
+ c) give non-standard executables non-standard names, with
36
+ instructions on where to get the original software distribution.
37
+
38
+ d) make other distribution arrangements with the author.
39
+
40
+ 4. You may modify and include the part of the software into any other
41
+ software (possibly commercial). But some files in the distribution
42
+ are not written by the author, so that they are not under this terms.
43
+
44
+ They are gc.c(partly), utils.c(partly), regex.[ch], st.[ch] and some
45
+ files under the ./missing directory. See each file for the copying
46
+ condition.
47
+
48
+ 5. The scripts and library files supplied as input to or produced as
49
+ output from the software do not automatically fall under the
50
+ copyright of the software, but belong to whomever generated them,
51
+ and may be sold commercially, and may be aggregated with this
52
+ software.
53
+
54
+ 6. THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
55
+ IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
56
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
57
+ PURPOSE.
58
+
data/README ADDED
@@ -0,0 +1,74 @@
1
+ SimpleHttp - a simplified wrapper around Net::Http
2
+
3
+ SimpleHttp aims to reduce the complexity of Net::Http while providing
4
+ the most commonly used (by me) http functionality.
5
+
6
+ FEATURES / USAGE
7
+
8
+ * No fuss one line GET and POST requests:
9
+
10
+ str = SimpleHttp.get "http://www.example.com"
11
+ str = SimpleHttp.get "www.example.com"
12
+
13
+ * Can use URI or String url interchangibly
14
+
15
+ str = SimpleHttp.get URI.parse "http://www.example.com/"
16
+
17
+ * Transparent Proxy Handling. Uses the 'http_proxy' environment
18
+ variable if set, also provides a +set_proxy+ method.
19
+
20
+ http = SimpleHttp.new "http://www.example.com"
21
+ http.set_proxy "http://proxy.example.com:8000"
22
+ http.post "query" => "example_query"
23
+
24
+ * POST sends ruby Hashes as 'application/x-www-form/urlencoded' per
25
+ default, but can send any data.
26
+
27
+ http = SimpleHttp.new "http://www.example.com/image_upload"
28
+ http.post imageData, "img/png"
29
+
30
+ * Automatically handles SSL
31
+
32
+ str = SimpleHttp.get "https://secure.example.com"
33
+
34
+ * Easy HTTP Basic Authentication
35
+ str = SimpleHttp.get URI.parse("http://usr:pwd@www.example.com")
36
+ #or
37
+ http = SimpleHttp.new "http://www.example.com"
38
+ http.basic_authentication "user", "password"
39
+ http.post "query" => "example_query"
40
+
41
+ * Access headers of the request or response
42
+ http = SimpleHttp.new "www.example.com"
43
+ http.request_header["X-Custom-Header"]="useful header"
44
+
45
+ * Automatically follows Http Redirects.
46
+
47
+
48
+ The +get+ and +post+ methods return a +String+ containing the
49
+ body of the request if the request was successful (HTTP 200). In case of
50
+ a redirect, the redirect is followed and the ultimate response is
51
+ returned. Per Default, up to three redirects are followed, this
52
+ behaviour can be modified by setting +follow_num_redirects+.
53
+
54
+ In case of any other type of response, an exception is raised.
55
+
56
+ The default behaviour can be modified by registering handlers
57
+ using the +register_response_handler+ method. E.g. if you'd like to
58
+ retrieve the +Date+ header instead of the body for successful
59
+ transactions:
60
+
61
+ http = SimpleHttp.new ...
62
+ http.register_response_handler(Net::HTTPSuccess) {|req,res,http|
63
+ res['date']
64
+ }
65
+
66
+ Or you'd like to print the +Location+ and then raise an exception in
67
+ case of a redirect:
68
+
69
+
70
+ http = SimpleHttp.new ...
71
+ http.register_response_handler(Net::HTTPRedirect) {|req,res,http|
72
+ puts res['location']
73
+ raise "REDIRECT not allowed!"
74
+ }
@@ -0,0 +1,120 @@
1
+ require "rake/rdoctask"
2
+ require "rake/gempackagetask"
3
+ require "rake/testtask"
4
+ require "rake/clean"
5
+ require "rubygems"
6
+
7
+ require "lib/simple_http"
8
+
9
+ # Specifies the default task to execute. This is often the "test" task
10
+ # and we'll change things around as soon as we have some tests.
11
+
12
+ task :default => [:rdoc]
13
+
14
+ # The directory to generate +rdoc+ in.
15
+ RDOC_DIR="doc/html"
16
+
17
+ # This global variable contains files that will be erased by the `clean` task.
18
+ # The `clean` task itself is automatically generated by requiring `rake/clean`.
19
+
20
+ CLEAN << RDOC_DIR
21
+
22
+
23
+ # This is the task that generates the +rdoc+ documentation from the
24
+ # source files. Instantiating Rake::RDocTask automatically generates a
25
+ # task called `rdoc`.
26
+
27
+ Rake::RDocTask.new do |rd|
28
+ # Options for documenation generation are specified inside of
29
+ # this block. For example the following line specifies that the
30
+ # content of the README file should be the main page of the
31
+ # documenation.
32
+ rd.main = "README"
33
+
34
+ # The following line specifies all the files to extract
35
+ # documenation from.
36
+ rd.rdoc_files.include( "README", "AUTHORS", "LICENSE", "TODO",
37
+ "CHANGELOG", "bin/**/*", "lib/**/*.rb",
38
+ "examples/**/*rb","test/**/*.rb", "doc/*.rdoc")
39
+ # This one specifies the output directory ...
40
+ rd.rdoc_dir = "doc/html"
41
+
42
+ # Or the HTML title of the generated documentation set.
43
+ rd.title = "simple_http: Simple Http client lib."
44
+
45
+ # These are options specifiying how source code inlined in the
46
+ # documentation should be formatted.
47
+
48
+ rd.options = ["--line-numbers", "--inline-source"]
49
+
50
+ # Check:
51
+ # `rdoc --help` for more rdoc options
52
+ # the {rdoc documenation home}[http://www.ruby-doc.org/stdlib/libdoc/rdoc/rdoc/index.html]
53
+ # or the documentation for the +Rake::RDocTask+ task[http://rake.rubyforge.org/classes/Rake/RDocTask.html]
54
+ end
55
+
56
+ # The GemPackageTask facilitates getting all your files collected
57
+ # together into gem archives. You can also use it to generate tarball
58
+ # and zip archives.
59
+
60
+ # First you'll need to assemble a gemspec
61
+
62
+ PROJECT_NAME = "simplehttp"
63
+ PKG_VERSION = SimpleHttp::VERSION
64
+ PKG_FILES = FileList['lib/**/*.rb', 'bin/**/*', 'examples/**/*', '[A-Z]*', 'test/**/*'].to_a
65
+
66
+ spec = Gem::Specification.new do |s|
67
+ s.platform = Gem::Platform::RUBY
68
+ s.summary = "simple_http: Simple Http client lib."
69
+ s.name = PROJECT_NAME
70
+ s.version = PKG_VERSION
71
+ s.files = PKG_FILES
72
+ s.requirements << "none"
73
+ s.require_path = 'lib'
74
+ s.description = <<END_DESC
75
+ Wrapper around net/http to provide quick and dirty http access.
76
+ END_DESC
77
+ end
78
+
79
+ # Adding a new GemPackageTask adds a task named `package`, which generates
80
+ # packages as gems, tarball and zip archives.
81
+ Rake::GemPackageTask.new(spec) do |pkg|
82
+ pkg.need_zip = true
83
+ pkg.need_tar_gz = true
84
+ end
85
+
86
+
87
+ # This task is used to demonstrate how to upload files to Rubyforge.
88
+ # Calling `upload_page` creates a current version of the +rdoc+
89
+ # documentation and uploads it to the Rubyforge homepage of the project,
90
+ # assuming it's hosted there and naming conventions haven't changed.
91
+ #
92
+ # This task uses `sh` to call the `scp` binary, which is plattform
93
+ # dependant and may not be installed on your computer if you're using
94
+ # Windows. I'm currently not aware of any pure ruby way to do scp
95
+ # transfers.
96
+
97
+ RubyForgeUser="a2800276"
98
+ RubyForgeProject=PROJECT_NAME
99
+
100
+ desc "Upload the web pages to the web."
101
+ task :upload_pages => ["rdoc", "clean"] do
102
+ if RubyForgeProject then
103
+ path = "/var/www/gforge-projects/#{RubyForgeProject}"
104
+ sh "scp -r doc/html/* #{RubyForgeUser}@rubyforge.org:#{path}"
105
+ sh "scp doc/images/*.png #{RubyForgeUser}@rubyforge.org:#{path}/images"
106
+ end
107
+ end
108
+
109
+
110
+ # This task will run the unit tests provided in files called
111
+ # `test/test*.rb`. The task itself can be run with a call to `rake test`
112
+
113
+ Rake::TestTask.new do |t|
114
+ t.libs << "test"
115
+ t.libs << "lib"
116
+ t.test_files = FileList['test/*.rb']
117
+ t.verbose = true
118
+ end
119
+
120
+
data/TODO ADDED
@@ -0,0 +1,26 @@
1
+ * There seems to be a bug in webrick that it doesn't recognize the
2
+ Content-Length header if using basic authentication. The POST test
3
+ cases lead to a:
4
+ ERROR HTTPRequest#fixup: WEBrick::HTTPStatus::LengthRequired occured.
5
+ even though the Content-Length header is set correctly in the http
6
+ packet...
7
+
8
+ * I've not figured out how to set_up and teardown webbrick properly.
9
+ Since webbrick blocks after calling `start`, it needs to started in a
10
+ seperate thread. I didn't handle communication with it properly
11
+ though. Test::Unit calls set_up and teardown before
12
+ and after executing each test... method, and not as I expected, before
13
+ and after each test file. This leads to a new TestServer being
14
+ instantiated which complains "bind-adress already in use", because the
15
+ other instance wasn't properly shut down. I tried to dix this by setting
16
+ up the server in the constructor, but that has the same effect.
17
+ It seems like a new instance of TestCase is instantiated to run every
18
+ single test... method.
19
+
20
+ * There also seems to be something screwy about how rake calls the
21
+ tests. Some ruby files seem to be included twice. This leads to
22
+ "already initialized constant" error in the output of the unit tests.
23
+
24
+ * The two previous bugs aren't really problematic, because they only
25
+ make the output of the tests ugly. They should be easy to fix... (But
26
+ they're not high on my list of priorities.)
@@ -0,0 +1,361 @@
1
+ require 'net/http'
2
+ require 'net/https'
3
+ require 'uri'
4
+ require 'cgi'
5
+ require 'base64'
6
+
7
+
8
+ # Wrapper around ruby's standard net/http classes. Currently, only GET
9
+ # and POST https methods are supported. `SimpleHttp` provides class
10
+ # methods `get` and `post` to handle basic functionality. In case more
11
+ # complicated requests need to be made or default settings need to be
12
+ # overriden, it's possible to instantiate `SimpleHttp` and use instance
13
+ # methods `get` and `put`.
14
+ #
15
+ #
16
+ # Features:
17
+ #
18
+ # * Handles Redirects automatically
19
+ # * Proxy used transparently if http_proxy environment variable is
20
+ # set.
21
+ # * SSL handled automatically
22
+ # * fault tolerant uri, e.g. all of these would work:
23
+ # "www.example.com", "www.example.com/", "http://www.example.com"
24
+ #
25
+ # Some usage examples:
26
+ # # plain GET (using class methods)
27
+ # SimpleHttp.get "www.example.com"
28
+ #
29
+ # # POST using the instance methods
30
+ # uri = URI.parse "https://www.example.com/index.html"
31
+ # sh = SimpleHttp uri
32
+ # sh.set_proxy "my.proxy", "8080"
33
+ # sh.post {"query" => "query_data"}
34
+ #
35
+ # # POST using class methods.
36
+ # binaryData = getImage
37
+ # SimpleData.post binaryData, "image/png"
38
+ #
39
+ # # GET requst with a custom request_header
40
+ # sh = SimpleHttp.new "http://www.example.com"
41
+ # sh.request_headers= {'X-Special-Http-Header'=>'my-value'}
42
+ # sh.get
43
+ class SimpleHttp
44
+
45
+ VERSION='0.1.0'
46
+
47
+ attr_accessor :proxy_host, :proxy_port, :proxy_user, :proxy_pwd, :uri, :request_headers, :response_handlers, :follow_num_redirects
48
+
49
+ RESPONSE_HANDLERS = {
50
+ Net::HTTPResponse => lambda { |request, response, http|
51
+ raise response.to_s
52
+ },
53
+ Net::HTTPSuccess => lambda { |request, response, http|
54
+ return response.body
55
+ },
56
+ Net::HTTPRedirection => lambda { |request, response, http|
57
+ raise "too many redirects!" unless http.follow_num_redirects > 0
58
+
59
+ # create a new SimpleHttp for the location
60
+ # refered to decreasing the remaining redirects
61
+ # by one.
62
+ sh = SimpleHttp.new response['location']
63
+ sh.follow_num_redirects = http.follow_num_redirects-1
64
+
65
+ # copy the response handlers used in the current
66
+ # request in case they were non standard.
67
+ sh.response_handlers = http.response_handlers
68
+
69
+ # http doesn't permit redirects for methods
70
+ # other than GET of HEAD, so we complain in case
71
+ # we get them in response to a POST request. (Or
72
+ # anything other than GET, for that matter.)
73
+
74
+ if request.class == Net::HTTP::Get
75
+ return sh.get
76
+ else
77
+ raise "Not a valid HTTP method for redirection: #{request.class}"
78
+
79
+ end
80
+ }
81
+
82
+ }
83
+
84
+ # SimpleHttp can either be used directly through the +get+ and
85
+ # +post+ class methods or be instantiated, in case you need to
86
+ # to add custom behaviour to the requests.
87
+ #
88
+ # @param may be a URI or a String.
89
+ #
90
+ # Example:
91
+ # http = SimpleHttp.new(URI.parse("http://www.example.com"))
92
+ # http = SimpleHttp.new "www.example.com"
93
+ # http = SimpleHttp.new "http://usr:pwd@www.example.com:1234"
94
+ def initialize uri
95
+ set_proxy ENV['http_proxy'] if ENV['http_proxy']
96
+
97
+ if uri.class == String
98
+
99
+ unless uri =~ /^https?:\/\//
100
+ uri = "http://#{uri}"
101
+ end
102
+
103
+ uri = URI.parse uri
104
+
105
+ end
106
+ @uri = uri
107
+ if !@uri.path || "" == @uri.path.strip
108
+ @uri.path="/"
109
+ end
110
+
111
+
112
+ @request_headers={}
113
+ @response_handlers=RESPONSE_HANDLERS.clone
114
+ @follow_num_redirects=3
115
+
116
+ if @uri.user
117
+ basic_authentication @uri.user, @uri.password
118
+ end
119
+
120
+ end
121
+
122
+ #
123
+ # Provides facilities to perform http basic authentication. You
124
+ # don't need to provide +usr+ and +pwd+ if they are already included
125
+ # in the uri, i.e. http://user:password@www.example.com/
126
+ #
127
+
128
+ def basic_authentication usr, pwd
129
+ str = Base64.encode64("#{usr}:#{pwd}")
130
+ str = "Basic #{str}"
131
+ @request_headers["Authorization"]=str
132
+ end
133
+
134
+ #
135
+ # this method can be used to register response handlers for specific
136
+ # http responses in case you need to override the default behaviour.
137
+ # Defaults are:
138
+ #
139
+ # HTTPSuccess : return the body of the response
140
+ # HTTPRedirection : follow the redirection until success
141
+ # Others : raise an exception
142
+ #
143
+ # `clazz` is the subclass of HTTPResponse (or HTTPResponse in case you
144
+ # want to define "default" behaviour) that you are registering the
145
+ # handler for.
146
+ #
147
+ # `block` is the handler itself, if a response of the appropriate class
148
+ # is received, `block` is called with three parameters: the the
149
+ # Net::HTTPRequest, the actual HTTPResponse object that was received
150
+ # and a reference to the instance of `SimpleHttp` that is executing the
151
+ # call.
152
+ #
153
+ # example:
154
+ #
155
+ # # to override the default action of following a HTTP
156
+ # # redirect, you could register the folllowing handler:
157
+ #
158
+ # sh = SimpleHttp "www.example.com"
159
+ # sh.register_response_handler Net::HTTPRedirection {|request, response, shttp|
160
+ # response['location']
161
+ # }
162
+ #
163
+
164
+ def register_response_handler clazz, &block
165
+ c = clazz
166
+ while c != Object
167
+ # completely unnecessary sanity check to make sure parameter
168
+ # `clazz` is in fact a HTTPResponse ...
169
+ if c == Net::HTTPResponse
170
+ @response_handlers[clazz]=block
171
+ return
172
+ end
173
+ c = c.superclass
174
+ end
175
+
176
+ raise "Trying to register a response handler for non-response class: #{clazz}"
177
+ end
178
+
179
+ #
180
+ # Set the proxy to use for the http request.
181
+ # Note that you don't need to set the proxy in case the
182
+ # `http_proxy` environment variable is set. To override
183
+ # previous proxy settings and connect directly, call
184
+ # `set_proxy nil`
185
+ #
186
+ # usage:
187
+ # http = SimpleHttp.new "www.example.com"
188
+ #
189
+ # http.set_proxy "http://proxy:8000"
190
+ # or:
191
+ # http.set_proxy(URI.parse("http://proxy:8000"))
192
+ # or:
193
+ # http.set_proxy 'proxy', '8000', 'my_user', 'secret'
194
+ # or:
195
+ # http.set_proxy nil # to override previous proxy
196
+ # settings and make the request directly.
197
+ #
198
+
199
+
200
+ def set_proxy proxy, port=nil, user=nil, pwd=nil
201
+
202
+
203
+ if !proxy
204
+ @proxy_host=@proxy_port=@proxy_user=@proxy_pwd=nil
205
+ return
206
+ end
207
+
208
+ if proxy.class == String
209
+ if !port && !user && !pwd
210
+ proxy = URI.parse(proxy)
211
+ else
212
+ @proxy_host= host
213
+ @proxy_port= port
214
+ @proxy_user= user
215
+ @proxy_pwd = pwd
216
+ end
217
+ end
218
+
219
+ if proxy.class == URI::HTTP
220
+ @proxy_host= proxy.host
221
+ @proxy_port= proxy.port
222
+ @proxy_user= proxy.user
223
+ @proxy_pwd = proxy.password
224
+ end
225
+ end
226
+
227
+ # interal
228
+ # Takes a HTTPResponse (or subclass) and determines how to
229
+ # handle the response. Default behaviour is:
230
+ #
231
+ # HTTPSuccess : return the body of the response
232
+ # HTTPRedirection : follow the redirect until success.
233
+ # default : raise the HTTPResponse.
234
+ #
235
+ # the default behaviour can be overidden by registering a
236
+ # response handler using the `register_response_handler` method.
237
+ #
238
+
239
+ def handle_response http_request, http_response
240
+ raise "Not a Net::HTTPResponse" unless http_response.is_a? Net::HTTPResponse
241
+
242
+ c = http_response.class
243
+ while c!=Object
244
+ # the response_handlers hash contains a handler
245
+ # for the specific response class.
246
+ if @response_handlers[c]
247
+ return @response_handlers[c].call(http_request, http_response, self)
248
+ end
249
+
250
+ c=c.superclass
251
+ end
252
+
253
+ # if we reached this place, no handler was registered
254
+ # for this response. default is to return the response.
255
+
256
+ return http_response
257
+ end
258
+
259
+ # internal
260
+ def do_http request
261
+ response = nil
262
+
263
+ http = Net::HTTP.new(@uri.host, @uri.port, @proxy_host,
264
+ @proxy_port, @proxy_user, @proxy_pwd)
265
+ http.use_ssl = @uri.scheme == 'https'
266
+
267
+ # add custom request headers.
268
+
269
+ @request_headers.each {|key,value|
270
+ request[key]=value;
271
+ }
272
+
273
+ handle_response(request, http.request(request));
274
+ end
275
+
276
+ # internal
277
+ def make_query query
278
+ return query unless query && query.class == Hash
279
+ str = ""
280
+ query.collect { |key, value|
281
+ str += CGI::escape(key) + "=" + CGI::escape(value)
282
+ }
283
+ str
284
+ end
285
+
286
+ # Make a simple GET request to the provided URI.
287
+ #
288
+ # Example:
289
+ # puts(SimpleHttp.get("www.example.com"))
290
+ def self.get uri, query=nil
291
+ http = SimpleHttp.new uri
292
+ http.get query
293
+ end
294
+
295
+ # Make a POST request to the provided URI.
296
+ #
297
+ # Example:
298
+ # puts(SimpleHttp.post("www.example.com", "query"=>"my_query"))
299
+ #
300
+ # Alternatively, you can post any sort of data, but will have to
301
+ # set the appriate content_type:
302
+ #
303
+ # SimpleHttp.post("http://www.example.com/", binary_data, "img/png")
304
+
305
+ def self.post uri, query=nil, content_type='application/x-www-form-urlencoded'
306
+ http = SimpleHttp.new uri
307
+ http.post query, content_type
308
+ end
309
+
310
+ # Call the +get+ method as an instance method if you need to
311
+ # modify the default behaviour of the library, or set special
312
+ # headers:
313
+ #
314
+ # http = SimpleHttp.new "www.example.com"
315
+ # http.request_headers["X-Special"]="whatever"
316
+ # str = http.get
317
+ def get query = nil
318
+ if (query = make_query query)
319
+ @uri.query = @uri.query ? @uri.query+"&"+query : query
320
+ end
321
+ full_path = @uri.path + (@uri.query ? "?#{@uri.query}" : "")
322
+
323
+ req = Net::HTTP::Get.new(full_path)
324
+ # puts Net::HTTP::Proxy(@proxy_host, @proxy_port, @proxy_user, @proxy_pwd).get(@uri)
325
+ do_http req
326
+ end
327
+
328
+ #
329
+ # Post the query data to the url.
330
+ # The body of the request remains empty if query=nil.
331
+ # In case `query` is a `Hash`, it's assumed that we are
332
+ # sending a form.
333
+ # In case `query` is a `String`, it's also assumed that a
334
+ # form is being sent, UNLESS the `content_type` parameter
335
+ # is set.
336
+ #
337
+ def post query=nil, content_type='application/x-www-form-urlencoded'
338
+ req = Net::HTTP::Post.new(@uri.path)
339
+
340
+ req.body= make_query query if query
341
+ req.content_type=content_type if query
342
+ req.content_length=query ? req.body.length : 0
343
+
344
+ do_http req
345
+ end
346
+
347
+ end
348
+
349
+ #ht = SimpleHttp.new "http://www.google.com/aldfksjaldskjfalskjfdlk"
350
+ ##ht.register_response_handler(Net::HTTPRedirection) {|req, res, ht| puts res['location']}
351
+ #puts ht.get.class
352
+ ##puts(ht.get("q"=>"bla"))
353
+ #
354
+ ##puts (SimpleHttp.get "http://www.google.com")
355
+ #
356
+ #['http://www.google.com/', 'www.google.com', 'https://www.google.com'].each {|u|
357
+ # SimpleHttp.new u
358
+ #}
359
+ ##puts ht.post
360
+
361
+
@@ -0,0 +1,193 @@
1
+ require 'simple_http.rb'
2
+ require 'http_test_server.rb'
3
+
4
+ require 'test/unit'
5
+ require 'uri'
6
+ require 'base64'
7
+
8
+ # These tests communicate with a corresponding http server (TestServer), which is
9
+ # implemented in `http_test_server.rb`
10
+
11
+ class SimpleHttpTest < Test::Unit::TestCase
12
+ def initialize *args
13
+ super *args
14
+ # create webbrick server in a separate thread
15
+ Thread.new {
16
+ TestServer.new.start
17
+ }
18
+ end
19
+
20
+ def teardown
21
+ #@t.shutdown # webrick blocks in a weird way, can't
22
+ #commnicate with it in a different thread. this, of
23
+ #course, is really ugly.
24
+ end
25
+
26
+ # Tests of SimpleHttp class method behaviour.
27
+
28
+ def test_get_class_method
29
+ # string url
30
+ ret = SimpleHttp.get "http://127.0.0.1:12345/test1"
31
+ assert_equal(ret, TestServer::SUCCESS_TEXT_0, "basic GET 1 test failed.");
32
+
33
+ # string url, with query
34
+ ret = SimpleHttp.get "http://127.0.0.1:12345/test1?query=true"
35
+ assert_equal(ret, TestServer::SUCCESS_TEXT_0, "basic GET 2 test failed.");
36
+
37
+ # uri
38
+ uri = URI.parse "http://127.0.0.1:12345/test1?query=true"
39
+ ret = SimpleHttp.get uri
40
+ assert_equal(ret, TestServer::SUCCESS_TEXT_0, "basic GET 3 test failed.");
41
+
42
+ #string with query as hash
43
+ ret = SimpleHttp.get "http://127.0.0.1:12345/test2", "query" => "query_test"
44
+ assert_equal("query_test", ret, "basic GET (query) 4 test failed.");
45
+
46
+ #uri with existing query + query as hash.
47
+ uri = URI.parse "http://127.0.0.1:12345/test2?query2=true"
48
+ ret = SimpleHttp.get uri, "query" => "query_test"
49
+ assert_equal("query_test", ret, "basic GET (query) 4.1 test failed.");
50
+
51
+ end
52
+
53
+ # Tests for http GET calls implemented using instantiated SimpleHttp objects.
54
+
55
+ def test_get_class_instance_method
56
+ http = SimpleHttp.new "http://127.0.0.1:12345/test1"
57
+ ret = http.get
58
+ assert_equal(ret, TestServer::SUCCESS_TEXT_0, "instance GET 1 test failed.");
59
+
60
+ http = SimpleHttp.new "http://127.0.0.1:12345/test2?query=query_test"
61
+ ret = http.get
62
+ assert_equal("query_test", ret, "instance GET 2 test (query)");
63
+
64
+ http = SimpleHttp.new "http://127.0.0.1:12345/query_test2?query=query_test"
65
+ ret = http.get "query2"=>"query2_test"
66
+ assert_equal("query2_test", ret, "instance GET 2.1 test (add to existing query")
67
+
68
+ http = SimpleHttp.new(URI.parse("http://127.0.0.1:12345/query_test2?bla=true"))
69
+ ret = http.get "query2" => "query_test"
70
+ assert_equal("query_test", ret, "basic GET (query) 3 test failed.")
71
+
72
+ # GET requst with a custom request_header
73
+ http = SimpleHttp.new "http://127.0.0.1:12345/header_test"
74
+ http.request_headers= {'x-special-http-header'=>'my-value'}
75
+ ret = http.get
76
+ assert_equal("my-value", ret, "GET header test 4")
77
+
78
+
79
+ end
80
+
81
+ # http POST calls using class methods.
82
+ #
83
+ def test_post_class_method
84
+
85
+ # string url
86
+ ret = SimpleHttp.post "http://127.0.0.1:12345/test1"
87
+ assert_equal(ret, TestServer::SUCCESS_TEXT_0, "basic POST 1 test failed.");
88
+
89
+
90
+ #string with query as hash
91
+ ret = SimpleHttp.post "http://127.0.0.1:12345/test2", "query" => "query_test"
92
+ assert_equal("query_test", ret, "basic POST (query) 2 test failed.");
93
+
94
+ #uri with existing query + query as hash.
95
+ uri = URI.parse "http://127.0.0.1:12345/test2"
96
+ ret = SimpleHttp.post uri, "query" => "query_test"
97
+ assert_equal("query_test", ret, "basic POST (query) 2.1 test failed.");
98
+
99
+ # post something other than a form.
100
+ ret = SimpleHttp.post "http://127.0.0.1:12345/post_data_test", TestServer::POST_DATA, "misc/test-data"
101
+ assert_equal(TestServer::POST_DATA, ret, "class Post data test")
102
+
103
+
104
+ end
105
+
106
+
107
+ def test_post_instance_method
108
+ http = SimpleHttp.new "http://127.0.0.1:12345/test1"
109
+ ret = http.post
110
+ assert_equal(ret, TestServer::SUCCESS_TEXT_0, "instance POST 1 test failed.");
111
+
112
+ http = SimpleHttp.new "http://127.0.0.1:12345/test2"
113
+ ret = http.post "query" => "query_test"
114
+ assert_equal("query_test", ret, "instance POST 2 test (query)");
115
+
116
+ http = SimpleHttp.new "http://127.0.0.1:12345/query_test2?query=query_test"
117
+ ret = http.post "query2"=>"query2_test"
118
+ assert_equal("query2_test", ret, "instance POST 2.1 test (add to existing query")
119
+
120
+ http = SimpleHttp.new(URI.parse("http://127.0.0.1:12345/query_test2?bla=true"))
121
+ ret = http.post "query2" => "query_test"
122
+ assert_equal("query_test", ret, "basic POST (query) 3 test failed.")
123
+
124
+ # POST requst with a custom request_header
125
+ http = SimpleHttp.new "http://127.0.0.1:12345/header_test"
126
+ http.request_headers= {'x-special-http-header'=>'my-value'}
127
+ ret = http.post
128
+ assert_equal("my-value", ret, "POST header test 4")
129
+
130
+ # POST request with a custom data type (not posting a form.)
131
+ http = SimpleHttp.new "http://127.0.0.1:12345/post_data_test"
132
+ ret = http.post TestServer::POST_DATA, "misc/test-data"
133
+ assert_equal(TestServer::POST_DATA, ret, "Post data test")
134
+
135
+
136
+ end
137
+
138
+ def test_basic_auth
139
+
140
+ # string url
141
+ ret = SimpleHttp.get "http://test:pwd@127.0.0.1:12345/basic_auth"
142
+ assert_equal(TestServer::SUCCESS_TEXT_1, ret, "basic auth get class 1 test failed.");
143
+
144
+ http = SimpleHttp.new "http://127.0.0.1:12345/basic_auth"
145
+ http.basic_authentication "test", "pwd"
146
+ ret = http.get
147
+ assert_equal(ret, TestServer::SUCCESS_TEXT_1, "basic auth get instance 2 test failed.");
148
+ #string with query as hash
149
+ ret = SimpleHttp.post "http://test:pwd@127.0.0.1:12345/basic_auth", "query" => "query_test"
150
+ assert_equal(TestServer::SUCCESS_TEXT_1, ret, "basic auth post class 3 test failed.");
151
+
152
+ http = SimpleHttp.new "http://127.0.0.1:12345/basic_auth"
153
+ http.basic_authentication "test", "pwd"
154
+ ret = http.post TestServer::POST_DATA, "misc/test-data"
155
+ assert_equal(TestServer::SUCCESS_TEXT_1, ret, "Post data test")
156
+ end
157
+
158
+ def test_response_handler
159
+ assert_raise(RuntimeError) {
160
+ ret = SimpleHttp.get "http://test:pwd@127.0.0.1:12345/non_existant"
161
+ }
162
+
163
+ http = SimpleHttp.new "http://test:pwd@127.0.0.1:12345/non_existant"
164
+ http.register_response_handler(Net::HTTPNotFound) { |req, res, http|
165
+ res.code
166
+ }
167
+ ret = http.get
168
+ assert_equal("404", ret, "response handler test 2")
169
+
170
+ http = SimpleHttp.new "http://test:pwd@127.0.0.1:12345/redirect1"
171
+ http.register_response_handler(Net::HTTPRedirection) { |req, res, http|
172
+ res['location']
173
+ }
174
+ ret = http.get
175
+ assert_equal("http://127.0.0.1:12345/redirect2", ret, "response handler test 3")
176
+
177
+ end
178
+
179
+ def test_redirect
180
+ assert_raise(RuntimeError) {
181
+ http = SimpleHttp.new "http://test:pwd@127.0.0.1:12345/redirect1"
182
+ ret = http.get
183
+ }
184
+
185
+ ret = SimpleHttp.get "http://test:pwd@127.0.0.1:12345/redirect"
186
+ assert_equal(ret, TestServer::SUCCESS_TEXT_0, "redirect test 2");
187
+
188
+
189
+ end
190
+
191
+
192
+ end
193
+
@@ -0,0 +1,90 @@
1
+ require 'webrick'
2
+
3
+ include WEBrick
4
+ class TestServer
5
+ SUCCESS_TEXT_0 = "success_0"
6
+ SUCCESS_TEXT_1 = "success_1"
7
+ SUCCESS_TEXT_2 = "success_2"
8
+ SUCCESS_TEXT_3 = "success_3"
9
+ SUCCESS_TEXT_4 = "success_4"
10
+ SUCCESS_TEXT_5 = "success_5"
11
+ SUCCESS_TEXT_6 = "success_6"
12
+ SUCCESS_TEXT_7 = "success_7"
13
+ SUCCESS_TEXT_8 = "success_8"
14
+ SUCCESS_TEXT_9 = "success_9"
15
+
16
+ POST_DATA = [0xbe, 0x00, 0x12, 0x23, 0x45, 0x67, 0x89, 0xAB].join
17
+
18
+ def initialize
19
+ @server = HTTPServer.new(
20
+ :Port => 12345
21
+ )
22
+
23
+ add_tests
24
+ end
25
+
26
+ def start
27
+ @server.start
28
+ end
29
+
30
+ def shutdown
31
+ @server.shutdown
32
+ end
33
+
34
+ def dbg str
35
+ puts "!!!!!!!!! #{str}"
36
+ end
37
+ def add_tests
38
+ # return a text
39
+ @server.mount_proc("/test1"){|req, res|
40
+ res.body=SUCCESS_TEXT_0
41
+ }
42
+ #return value of query param named "query"
43
+ @server.mount_proc("/test2"){|req, res|
44
+ res.body=req.query["query"]
45
+ }
46
+
47
+ # return value of query param named "query2"
48
+ @server.mount_proc("/query_test2"){|req, res|
49
+ res.body=req.query["query2"]
50
+ }
51
+
52
+ # return value of request header named "X-Special-Http-Header"
53
+ @server.mount_proc("/header_test"){|req, res|
54
+ res.body=req.header["x-special-http-header"][0]
55
+ }
56
+
57
+ # return value of request header named "X-Special-Http-Header"
58
+ @server.mount_proc("/post_data_test"){|req, res|
59
+ ctype = req.header['content-type'][0]
60
+ if "misc/test-data" == ctype
61
+ res.body=req.body
62
+ else
63
+ res.body="failed, content-type: #{ctype}"
64
+ end
65
+ }
66
+
67
+ @server.mount_proc("/basic_auth") {|req, res|
68
+
69
+ auth = Base64.decode64(req.header['authorization'][0].split[1])
70
+ usr, pwd = auth.split(':')
71
+ if ('test'==usr && 'pwd'==pwd)
72
+ res.body=SUCCESS_TEXT_1
73
+ else
74
+ res.status=403
75
+ end
76
+ }
77
+
78
+ 1.upto(6) {|i|
79
+ @server.mount_proc("/redirect#{i}") { |req, res|
80
+ res.status=301
81
+ res.header['location']="http://127.0.0.1:12345/redirect#{i+1}"
82
+ }
83
+ }
84
+
85
+ @server.mount_proc("/redirect") { |req, res|
86
+ res.status=301
87
+ res.header['location']="http://127.0.0.1:12345/test1"
88
+ }
89
+ end
90
+ end
metadata ADDED
@@ -0,0 +1,54 @@
1
+ --- !ruby/object:Gem::Specification
2
+ rubygems_version: 0.9.0
3
+ specification_version: 1
4
+ name: simplehttp
5
+ version: !ruby/object:Gem::Version
6
+ version: 0.1.0
7
+ date: 2007-02-08 00:00:00 +01:00
8
+ summary: "simple_http: Simple Http client lib."
9
+ require_paths:
10
+ - lib
11
+ email:
12
+ homepage:
13
+ rubyforge_project:
14
+ description: Wrapper around net/http to provide quick and dirty http access.
15
+ autorequire:
16
+ default_executable:
17
+ bindir: bin
18
+ has_rdoc: false
19
+ required_ruby_version: !ruby/object:Gem::Version::Requirement
20
+ requirements:
21
+ - - ">"
22
+ - !ruby/object:Gem::Version
23
+ version: 0.0.0
24
+ version:
25
+ platform: ruby
26
+ signing_key:
27
+ cert_chain:
28
+ post_install_message:
29
+ authors: []
30
+
31
+ files:
32
+ - lib/simple_http.rb
33
+ - AUTHORS
34
+ - CHANGELOG
35
+ - LICENSE
36
+ - Rakefile
37
+ - README
38
+ - TODO
39
+ - test/http_test.rb
40
+ - test/http_test_server.rb
41
+ test_files: []
42
+
43
+ rdoc_options: []
44
+
45
+ extra_rdoc_files: []
46
+
47
+ executables: []
48
+
49
+ extensions: []
50
+
51
+ requirements:
52
+ - none
53
+ dependencies: []
54
+