http-request 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (4) hide show
  1. data/README +6 -0
  2. data/VERSION +1 -0
  3. data/lib/http_request.rb +197 -0
  4. metadata +69 -0
data/README ADDED
@@ -0,0 +1,6 @@
1
+ HttpRequest
2
+ ===========
3
+
4
+ Simple HTTP client written in Ruby. Intended to be easier to work with then Net/HTTP.
5
+
6
+ Test on Ruby 1.8.7 and 1.9.2.
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 1.0.0
@@ -0,0 +1,197 @@
1
+ # +-------------------------------------------------------------------------------+
2
+ # | HttpRequest |
3
+ # +-------------------------------------------------------------------------------+
4
+ # | Author: NuLayer Inc. / www.nulayer.com |
5
+ # +-------------------------------------------------------------------------------+
6
+ # | BSD LICENSE |
7
+ # | Copyright (c) 2007-2010, NuLayer Inc. |
8
+ # | All rights reserved. |
9
+ # | |
10
+ # | Redistribution and use in source and binary forms, with or without |
11
+ # | modification, are permitted provided that the following conditions are met: |
12
+ # | * Redistributions of source code must retain the above copyright |
13
+ # | notice, this list of conditions and the following disclaimer. |
14
+ # | * Redistributions in binary form must reproduce the above copyright |
15
+ # | notice, this list of conditions and the following disclaimer in the |
16
+ # | documentation and/or other materials provided with the distribution. |
17
+ # | * Neither the name of the <organization> nor the |
18
+ # | names of its contributors may be used to endorse or promote products |
19
+ # | derived from this software without specific prior written permission. |
20
+ # | |
21
+ # | THIS SOFTWARE IS PROVIDED BY NuLayer Inc. "AS IS" AND ANY |
22
+ # | EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
23
+ # | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
24
+ # | DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY |
25
+ # | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
26
+ # | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
27
+ # | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND |
28
+ # | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
29
+ # | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
30
+ # | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
31
+ # +-------------------------------------------------------------------------------+
32
+
33
+ require 'net/http'
34
+
35
+ class HttpRequest
36
+ VERSION = '1.0.0'
37
+
38
+ class HTTPError < StandardError; end
39
+ class UnexpectedError < StandardError; end
40
+
41
+ class UnreachableError < HTTPError; end
42
+ class ConnectionResetError < HTTPError; end
43
+ class TimeoutError < HTTPError; end
44
+ class RedirectError < HTTPError; end
45
+
46
+ attr_accessor :uri
47
+ attr_accessor :header
48
+ attr_accessor :body
49
+ attr_accessor :status
50
+
51
+
52
+ def self.head(url, options={})
53
+ http = HttpRequest.new(url)
54
+ http.head(options)
55
+ end
56
+
57
+ def self.get(url, options={})
58
+ http = HttpRequest.new(url)
59
+ http.get(options)
60
+ end
61
+
62
+ def self.user_agent=(user_agent)
63
+ @user_agent = user_agent
64
+ end
65
+
66
+ def self.user_agent
67
+ @user_agent
68
+ end
69
+
70
+
71
+ def initialize(url)
72
+ self.uri = url
73
+ end
74
+
75
+ def head(options={})
76
+ request(:head, options)
77
+ end
78
+
79
+ def get(options={})
80
+ request(:get, options)
81
+ end
82
+
83
+ def request(type, options={})
84
+ user_agent = options[:user_agent] || HttpRequest.user_agent || 'HttpRequest'
85
+ timeout = (options[:timeout] || 10).to_i
86
+ redirect_limit = options[:redirect_limit] || 5
87
+ output_file = options[:output_file]
88
+ content_max = options[:content_max]
89
+
90
+ # Check if we're in a redirecting loop
91
+ if redirect_limit == 0
92
+ raise RedirectError, "HTTP redirect too deep: #{uri.to_s}"
93
+ end
94
+
95
+ # Prepare the request
96
+ req_path = uri.path
97
+ req_path += "?#{uri.query}" if !uri.query.nil?
98
+
99
+ req_klass = (type == :head ? Net::HTTP::Head : Net::HTTP::Get)
100
+ req = req_klass.new(req_path, { 'User-Agent' => user_agent })
101
+
102
+ # HTTP request block
103
+ @retries = 3
104
+ begin
105
+ http = Net::HTTP.new(uri.host, uri.port)
106
+
107
+ http.open_timeout = timeout
108
+ http.read_timeout = timeout
109
+
110
+ http.start do |http|
111
+ http.request(req) do |response|
112
+ # Save the header
113
+ self.header = response.header
114
+ self.body = nil
115
+
116
+ # Restrict downloading of content
117
+ download_content = true
118
+ if !content_max.nil? && header['content-length'].to_i > content_max
119
+ download_content = false
120
+ end
121
+
122
+ # Get the body
123
+ if download_content
124
+ if output_file
125
+ open(output_file, "w") do |f|
126
+ response.read_body { |data| f.write(data) }
127
+ end
128
+ else
129
+ self.body = response.read_body
130
+ end
131
+ end
132
+
133
+ # Handle URL Redirection
134
+ if response.kind_of?(Net::HTTPRedirection)
135
+ update_uri_location(header['location'])
136
+ request type, options.merge({ :redirect_limit => redirect_limit-1 })
137
+ end
138
+ end
139
+ end
140
+ rescue ::Errno::ENETUNREACH
141
+ raise UnreachableError, "network is unreachable: #{uri.to_s}"
142
+ rescue ::Errno::ECONNRESET, ::Errno::ECONNREFUSED, ::SocketError
143
+ raise ConnectionResetError, "connection reset by peer: #{uri.to_s}"
144
+ rescue ::Timeout::Error
145
+ raise TimeoutError, "connection timed out: #{uri.to_s}"
146
+ rescue ::Errno::EINTR => ex
147
+ # Transmission was interrupted, retry the request just once.
148
+ # This usually occurs because the process received a signal.
149
+ @retries -= 1
150
+ if @retries >= 0
151
+ retry
152
+ else
153
+ raise ex
154
+ end
155
+ rescue HTTPError => ex
156
+ # Catch exceptions that may be raised above -- not sure why we have to do this
157
+ raise ex
158
+ rescue => ex
159
+ raise UnexpectedError, "#{ex.inspect} -- #{uri.to_s}"
160
+ ensure
161
+ http.finish rescue nil
162
+ http = nil
163
+ end
164
+
165
+ return self
166
+ end
167
+
168
+ def header=(header)
169
+ return if header.nil?
170
+ @header = header
171
+ self.status = header.code.to_i
172
+ end
173
+
174
+ def reset!
175
+ self.header = nil
176
+ self.body = nil
177
+ self.status = nil
178
+ end
179
+
180
+ def uri=(url)
181
+ @uri = URI.parse(url)
182
+ @uri.path = '/' if @uri.path.empty?
183
+ reset!
184
+ end
185
+
186
+ def update_uri_location(location)
187
+ if header['location'].to_s[0].to_s.chr == '/'
188
+ url = "#{uri.scheme}://#{uri.host}"
189
+ url += ":#{uri.port}" if uri.port != 80 && uri.port != 443
190
+ url += location
191
+ else
192
+ url = location
193
+ end
194
+
195
+ self.uri = url
196
+ end
197
+ end
metadata ADDED
@@ -0,0 +1,69 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: http-request
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 1
7
+ - 0
8
+ - 0
9
+ version: 1.0.0
10
+ platform: ruby
11
+ authors:
12
+ - Peter Kieltyka
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2010-07-21 00:00:00 -04:00
18
+ default_executable:
19
+ dependencies: []
20
+
21
+ description: Simple HTTP client built with Net/HTTP
22
+ email:
23
+ - peter.kieltyka@nulayer.com
24
+ executables: []
25
+
26
+ extensions: []
27
+
28
+ extra_rdoc_files: []
29
+
30
+ files:
31
+ - README
32
+ - VERSION
33
+ - lib/http_request.rb
34
+ has_rdoc: true
35
+ homepage: http://nulayer.com
36
+ licenses: []
37
+
38
+ post_install_message:
39
+ rdoc_options: []
40
+
41
+ require_paths:
42
+ - lib
43
+ required_ruby_version: !ruby/object:Gem::Requirement
44
+ none: false
45
+ requirements:
46
+ - - ">="
47
+ - !ruby/object:Gem::Version
48
+ segments:
49
+ - 0
50
+ version: "0"
51
+ required_rubygems_version: !ruby/object:Gem::Requirement
52
+ none: false
53
+ requirements:
54
+ - - ">="
55
+ - !ruby/object:Gem::Version
56
+ segments:
57
+ - 1
58
+ - 3
59
+ - 6
60
+ version: 1.3.6
61
+ requirements: []
62
+
63
+ rubyforge_project:
64
+ rubygems_version: 1.3.7
65
+ signing_key:
66
+ specification_version: 3
67
+ summary: Simple HTTP client built with Net/HTTP
68
+ test_files: []
69
+