rest_connection 0.1.1 → 0.1.2

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 (49) hide show
  1. data/README.rdoc +1 -1
  2. data/Rakefile +2 -3
  3. data/VERSION +1 -1
  4. data/git_hooks/post-commit +43 -0
  5. data/git_hooks/pre-commit +98 -14
  6. data/lib/rest_connection.rb +150 -22
  7. data/lib/rest_connection/rightscale/account.rb +2 -0
  8. data/lib/rest_connection/rightscale/alert_spec.rb +1 -5
  9. data/lib/rest_connection/rightscale/alert_spec_subject.rb +21 -0
  10. data/lib/rest_connection/rightscale/audit_entry.rb +2 -0
  11. data/lib/rest_connection/rightscale/child_account.rb +2 -0
  12. data/lib/rest_connection/rightscale/cloud.rb +2 -0
  13. data/lib/rest_connection/rightscale/cloud_account.rb +2 -0
  14. data/lib/rest_connection/rightscale/ec2_ebs_volume.rb +5 -1
  15. data/lib/rest_connection/rightscale/ec2_elastic_ip.rb +2 -0
  16. data/lib/rest_connection/rightscale/ec2_security_group.rb +24 -0
  17. data/lib/rest_connection/rightscale/ec2_ssh_key.rb +2 -0
  18. data/lib/rest_connection/rightscale/executable.rb +2 -0
  19. data/lib/rest_connection/rightscale/instance_type.rb +6 -0
  20. data/lib/rest_connection/rightscale/mc_datacenter.rb +2 -0
  21. data/lib/rest_connection/rightscale/mc_image.rb +2 -0
  22. data/lib/rest_connection/rightscale/mc_instance.rb +2 -0
  23. data/lib/rest_connection/rightscale/mc_instance_type.rb +2 -0
  24. data/lib/rest_connection/rightscale/mc_multi_cloud_image.rb +2 -0
  25. data/lib/rest_connection/rightscale/mc_multi_cloud_image_setting.rb +2 -0
  26. data/lib/rest_connection/rightscale/mc_security_group.rb +62 -0
  27. data/lib/rest_connection/rightscale/mc_server_template_multi_cloud_image.rb +2 -0
  28. data/lib/rest_connection/rightscale/mc_ssh_key.rb +2 -0
  29. data/lib/rest_connection/rightscale/mc_tag.rb +2 -0
  30. data/lib/rest_connection/rightscale/mc_volume.rb +2 -0
  31. data/lib/rest_connection/rightscale/mc_volume_attachment.rb +2 -0
  32. data/lib/rest_connection/rightscale/mc_volume_snapshot.rb +2 -0
  33. data/lib/rest_connection/rightscale/mc_volume_type.rb +2 -0
  34. data/lib/rest_connection/rightscale/monitoring_metric.rb +2 -0
  35. data/lib/rest_connection/rightscale/multi_cloud_image.rb +2 -0
  36. data/lib/rest_connection/rightscale/permission.rb +2 -0
  37. data/lib/rest_connection/rightscale/right_script.rb +3 -0
  38. data/lib/rest_connection/rightscale/rightscale_api_base.rb +51 -4
  39. data/lib/rest_connection/rightscale/rightscale_api_gateway.rb +60 -33
  40. data/lib/rest_connection/rightscale/rightscale_api_resources.rb +5 -0
  41. data/lib/rest_connection/rightscale/s3_bucket.rb +2 -1
  42. data/lib/rest_connection/rightscale/security_group_rule.rb +31 -0
  43. data/lib/rest_connection/rightscale/server_ec2_ebs_volume.rb +40 -0
  44. data/lib/rest_connection/rightscale/session.rb +61 -0
  45. data/lib/rest_connection/rightscale/sqs_queue.rb +22 -0
  46. data/lib/rest_connection/rightscale/tag.rb +2 -0
  47. data/lib/rest_connection/rightscale/task.rb +4 -2
  48. data/lib/rest_connection/rightscale/user.rb +2 -0
  49. metadata +12 -6
@@ -19,7 +19,7 @@ Copy the example from GEMHOME/rest_connection/examples/rest_api_config.yaml.samp
19
19
  "gem install gemedit"
20
20
  "gem edit rest_connection"
21
21
 
22
- == Usage: some IRB samples
22
+ == Usage: some IRB samples for the RightScale API module
23
23
 
24
24
  $ irb
25
25
  ruby> require 'rubygems'; require 'rest_connection'
data/Rakefile CHANGED
@@ -2,8 +2,8 @@ require 'rubygems'
2
2
  require 'jeweler'
3
3
  Jeweler::Tasks.new do |gemspec|
4
4
  gemspec.name = "rest_connection"
5
- gemspec.summary = "lib for restful connections to the rightscale api"
6
- gemspec.description = "provides rest_connection"
5
+ gemspec.summary = "Modular RESTful API library"
6
+ gemspec.description = "Current implemented modules: RightScale API"
7
7
  gemspec.email = ["jeremy@rubyonlinux.org", "tw.rodriguez@gmail.com"]
8
8
  gemspec.homepage = "http://github.com/twrodriguez/rest_connection"
9
9
  gemspec.authors = ["Jeremy Deininger", "Timothy Rodriguez"]
@@ -13,4 +13,3 @@ Jeweler::Tasks.new do |gemspec|
13
13
  gemspec.add_dependency('highline')
14
14
  end
15
15
  Jeweler::GemcutterTasks.new
16
-
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.1
1
+ 0.1.2
@@ -0,0 +1,43 @@
1
+ #!/usr/bin/env ruby
2
+ puts <<EOS
3
+ ..,ONMMMMMO.
4
+ NM8~:~:.,+NMM=
5
+ MO .MM:
6
+ NM. ,MN
7
+ .. .7MN . . 8M,
8
+ ==. ?N: .MMN .,,.. 8$ZZ.~MN
9
+ .$. N8 ,DD. ,MMN ...+:. .MMM
10
+ D 8D.Z= .$. NMMM..,~8I ,88+. MMMM:.
11
+ ,~... ,MM .N . MMMM7. .... MMMMM,
12
+ DZ.. .:OZ.:M. ..8= .MMMM. .OMMMMM
13
+ :7 . 8+$M:.D+ +MMMM, .:N+,MMD: 7MMMMM.
14
+ .MM7:.... 8 .M. 7MMMMM. MMMMZMMMMO.7MMMMM.
15
+ ,?. .. ..8 ,M =MMMMM MMN8$7O8DMM.OMMM~ +.
16
+ N.. . .+ M, .MMMMMOM M8. .OM.MIMMMZ =,.
17
+ =NZI+~, + I8 .MMMMMMM= .=DD, MMMMMI ~~
18
+ O. .N + M. IMMMMMMMMMD ~MN 7MMMMMMM .Z
19
+ .MNZZNMZ. . MM 7MMMMMMMMMMMMMMMMMMMMMMMM, .~M,.
20
+ ID=. . . MMI MMMMMMMMMMMMMMMMMMMMMMMMMD. .+N
21
+ .DMO,ZND+. MMM. :MMMMMMMMN =MMMMMMMMN:ZMMM,. +M~,$OD$
22
+ .MMO... MMM OMMMMMMMM~ . ,I++O7. OMMM= .IM7 . .=..+MNI.
23
+ .8MO :MMM .MMMMMMMMMM. MMMMM= ~D ?MO:7MN...
24
+ +$ON. $NMM .NMMMMMMMMM7. .MMMMM. .8Z. :7N...MM:
25
+ O7?N M+MMNMMMMMMMMMMMMMMMMMN MMMMMM8D. . $, .$8 M ..,$MN~,,.
26
+ N$:=M. .NM.MM. ?MMMMMMO. .. D IO$IM:D.,$O, ,. O.I,Z :M: .+MI
27
+ MO, MMI ..NM8.MM. =. MM..IMN7,. .,IDN7~MMMMMM, N .Z N.M. ,M. =N.
28
+ .MO. MMMMMMMM::MM .: . .M :+I?=D.~.MMMMMMM?,,~INMMNNM+ ~ ~. D8. ,8.
29
+ .M8. MMMMMMMM ZM$. 8 7. ~ M,MM+MMMMMMMMMMMMMMM.. , : ,M. .O+
30
+ .MO. MMMMMMMI.MM, N = .....,IDI. MMMMMMMM8MMMMMM.. = M+ .M.
31
+ .MZ~.MMMMMMM..MM . N .=. ?M,NMMMMMM?~MM$IMMM7MMMMM7 :O M
32
+ M7I.NMMMMM8.$MZ.~ 8 .~, : MMMMMMMMMMMMM.~OOIMMM+MMMMM, .N M
33
+ N=D OMMMMM, MM O .I .7. MMMMMMMMMMMMMMMMMMMMMD7NMM:MMMMN D .M
34
+ O:M,~MMMMD NM? D.=, 8 OMMMMMMMMMMMMMMMMMMMMMZZMM?MMMM: ... Z .M
35
+ +=M$ MMMZ :MN ~, D. I. ~MMMMMMM+,,~I, .NMMMMMZ.MDNMM7 I. . .M.
36
+ .$NM .,.. MM .M :N. :~ .MMMMMM. MMMMMMZ=M,MM. .M. 7M
37
+ .N.MM~ $MZ. O. N? N. ,MMMMMMM. MMMMMMMM+8Z: NZ. . .MI.
38
+ .M.=MMMMN.. .+=..M. M. NMMMMMMMD 8MMMMMMM.MMM. $M. . ?, ~M.
39
+ +. ~MM .. $, M: N: . 7MMMMMMN .~MMMMMM8,MMMMMMMMMMM ..M. :MM
40
+ D N . ,M N NN. I8. $MMMMMMM?.. .?MMMMMMM?OMMMMMMMMMMMMMMMMMMMMI . ...MM$
41
+ 7? .?N.7O DM ,M ZMMMMMMMMMM7.IMMMMMMMMD$MMMMMMMMMMMMMMMMMMMMMMMMZ: IMMN.
42
+ .~MM?.=NM~DM8.. M 8MMMMMMMMMMMMMMMMM7=MMMMMMMMMMMMMMMMMD.IMMMNZZNMMN~
43
+ EOS
@@ -1,39 +1,119 @@
1
1
  #!/bin/bash
2
2
 
3
+ lod_message() {
4
+ cat <<EOS
5
+
6
+ OMM MM$
7
+ MMMM MMMM
8
+ MMM MMO
9
+ =MM MMM
10
+ MMM MMD
11
+ MMMMMMMMMMMMMMMMMMMMM NMMMMMMMMMMMMMMMMMMMMM
12
+ MMMMMMMMMMMMMMMMMMMM NMMMMMMMMMMMMMMMMMMM,
13
+ MMMM? ?MMMM =MMMM MMMMD
14
+ =MMM ?MMM MMMM MMMN
15
+ :MMM MMM NMM= =MMD
16
+ MMM ,MMO MMM DMM
17
+ MMM MMMD MMM DMM? ,MMM, MMD
18
+ MMM MMM$ MMM NMM? MMM MMN
19
+ MMM MMM OMMM =MMO
20
+ MMMN NMM$ MMM MMM
21
+ MMM? MMMM DMMM MMM$
22
+ MMMM: :MMMM DMMMM MMMM$
23
+ =MMMMMMMMMMMMMM? MMMMMMMMMMMMMMM
24
+ MMMMMMMMMMM MMMMMMMMMMM
25
+
26
+
27
+
28
+
29
+ DMMMMMMMMMMMMMMMMMMMMMMM
30
+
31
+ EOS
32
+ }
33
+
3
34
  whitespace=""
35
+ echo "Checking for syntax errors..."
4
36
  for FILE in `git diff-index --name-only HEAD --` ; do
5
- if test -e $FILE; then
6
- if [[ -n `grep "\\s\\s*$" $FILE` ]]; then whitespace="$whitespace $FILE"; fi
7
- # Remove trailing whitespace
8
- sed -i "s/\\s\\s*$//g" $FILE
9
- # Remove tabs
10
- sed -i "s/\t/ /g" $FILE
11
- # If a file is ruby, check for syntax errors
12
- if [[ -n `find $FILE -regex ".*\.rb$"` ]]; then
37
+ if test -f $FILE; then
38
+ filetype=`file -b $FILE`
39
+ if [[ "$filetype" =~ "text" ]]; then
40
+ if [[ -n `grep "\\s\\s*$" $FILE` ]]; then whitespace="$whitespace $FILE"; fi
41
+ # Remove trailing whitespace
42
+ sed -i "s/\\s\\s*$//g" $FILE
43
+ # Remove tabs
44
+ sed -i "s/\t/ /g" $FILE
45
+ fi
46
+
47
+ # If a file is ruby, check for syntax errors using ruby
48
+ if [[ "$FILE" =~ .*\.rb$ ]]; then
13
49
  if [[ "$fail" -eq 0 || -z "$fail" ]]; then
14
- `ruby -c $FILE 1> /dev/null`; fail=$?
50
+ ruby -c "$FILE" 1> /dev/null; fail=$?
51
+ if [[ "$fail" -ne 0 ]]; then echo "Syntax Error found in '$FILE'"; fi
15
52
  else
16
- `ruby -c $FILE 1> /dev/null`
53
+ ruby -c "$FILE" 1> /dev/null
54
+ if [[ "$?" -ne 0 ]]; then echo "Syntax Error found in '$FILE'"; fi
55
+ fi
56
+ fi
57
+
58
+ # If a file is json, check for syntax errors
59
+ if [[ "$FILE" =~ .*\.json$ ]]; then
60
+ if [[ "$fail" -eq 0 || -z "$fail" ]]; then
61
+ ruby -e "require 'rubygems'; require 'json'; JSON::parse(IO.read('$FILE'))" 1> /dev/null; fail=$?
62
+ if [[ "$fail" -ne 0 ]]; then echo "Syntax Error found in '$FILE'"; fi
63
+ else
64
+ ruby -e "require 'rubygems'; require 'json'; JSON::parse(IO.read('$FILE'))" 1> /dev/null
65
+ if [[ "$?" -ne 0 ]]; then echo "Syntax Error found in '$FILE'"; fi
66
+ fi
67
+ fi
68
+
69
+ # If a file is yaml, check for syntax errors
70
+ if [[ "$FILE" =~ .*\.yaml$ ]]; then
71
+ if [[ "$fail" -eq 0 || -z "$fail" ]]; then
72
+ ruby -e "require 'rubygems'; require 'yaml'; YAML::load(IO.read('$FILE'))" 1> /dev/null; fail=$?
73
+ if [[ "$fail" -ne 0 ]]; then echo "Syntax Error found in '$FILE'"; fi
74
+ else
75
+ ruby -e "require 'rubygems'; require 'yaml'; YAML::load(IO.read('$FILE'))" 1> /dev/null
76
+ if [[ "$?" -ne 0 ]]; then echo "Syntax Error found in '$FILE'"; fi
17
77
  fi
18
78
  fi
19
79
  fi
20
80
  done
81
+ echo "Syntax check complete."
21
82
 
22
83
  # Built-in git checks
23
84
  git diff-index --check HEAD --
24
85
 
25
86
  if [[ "$fail" -ne 0 && -n "$fail" ]]; then
26
87
  echo "Syntax Errors Found. Aborting commit"
88
+ lod_message
89
+ exit 1
90
+ fi
91
+
92
+ # Check for warnings
93
+ fail=0
94
+ for FILE in `git diff-index --name-only HEAD --` ; do
95
+ if test -e $FILE; then
96
+ # If a file is ruby, check for syntax errors
97
+ if [[ -n `find $FILE -regex ".*\.rb$"` ]]; then
98
+ warnings=`ruby -c "$FILE" 2>&1 | grep -i warn`
99
+ if [[ -n "$warnings" ]]; then fail=1; fi
100
+ fi
101
+ fi
102
+ done
103
+
104
+ if [[ "$fail" -ne 0 && -n "$fail" ]]; then
105
+ echo "Syntax Warnings Found. Aborting commit"
106
+ lod_message
27
107
  exit 1
28
108
  fi
29
109
 
30
110
  for FILE in $whitespace; do
31
111
  echo "Whitespace problem fixed. Please re-add '$FILE' to your commit"
32
112
  done
33
- if [[ -n "$whitespace" ]]; then exit 1; fi
113
+ if [[ -n "$whitespace" ]]; then lod_message; exit 1; fi
34
114
 
35
115
  # Check that project metadata files exist
36
- for FILE in "Rakefile" "README.rdoc" "VERSION" ".gitignore" "rest_connection.gemspec"; do
116
+ for FILE in "README.rdoc" "VERSION" ".gitignore" "Rakefile"; do
37
117
  if test ! -e $FILE; then
38
118
  echo "$FILE not present. Aborting commit"
39
119
  exit 1
@@ -44,10 +124,14 @@ done
44
124
  username=`git config --get user.name`
45
125
  useremail=`git config --get user.email`
46
126
  emaildomain=`echo $useremail | grep -o "[^@]*$"`
47
- if [[ "$username" == "" ]]; then
127
+ if [[ "$username" == "Put Your Name Here" || "$username" == "" ]]; then
48
128
  echo "Please set your git user.name by running 'git config user.name <your github username>'"
129
+ lod_message
49
130
  exit 1
50
- elif [[ "$useremail" == "" ]] || ! host "$emaildomain" &> /dev/null; then
131
+ elif [[ "$useremail" == "setyouremail@rightscale.com" || "$useremail" == "" ]] || ! host "$emaildomain" &> /dev/null; then
51
132
  echo "Please set your git user.email by running 'git config user.email <your github email>'"
133
+ lod_message
52
134
  exit 1
53
135
  fi
136
+
137
+ exit 0
@@ -132,17 +132,48 @@ module RestConnection
132
132
  http.verify_mode = OpenSSL::SSL::VERIFY_NONE
133
133
  end
134
134
  headers = @settings[:common_headers]
135
- headers.merge!("Cookie" => @cookie) if @cookie
136
135
  http.start do |http|
137
- req = yield(uri, headers)
138
- unless @cookie
139
- req.basic_auth(@settings[:user], @settings[:pass]) if @settings[:user]
136
+ @max_retries = 3
137
+ ret = nil
138
+ begin
139
+ headers.delete("Cookie")
140
+ headers.merge!("Cookie" => @cookie) if @cookie
141
+ req = yield(uri, headers)
142
+ logger("#{req.method}: #{req.path}")
143
+ logger("\trequest body: #{req.body}") if req.body and req.body !~ /password/
144
+ req.basic_auth(@settings[:user], @settings[:pass]) if @settings[:user] unless @cookie
145
+
146
+ response, body = http.request(req)
147
+ ret = handle_response(response)
148
+ rescue Exception => e
149
+ raise unless error_handler(e)
150
+ retry
151
+ end
152
+ ret
153
+ end
154
+ end
155
+
156
+ def error_handler(e)
157
+ case e
158
+ when EOFError, Timeout::Error
159
+ if @max_retries >= 0
160
+ logger("Caught #{e}. Retrying...")
161
+ @max_retries -= 1
162
+ return true
163
+ end
164
+ when RestConnection::Errors::Forbidden
165
+ if @max_retries >= 0
166
+ if e.response.body =~ /(session|cookie).*(invalid|expired)/i
167
+ logger("Caught '#{e.response.body}'. Refreshing cookie...")
168
+ refresh_cookie if respond_to?(:refresh_cookie)
169
+ else
170
+ return false
171
+ end
172
+ @max_retries -= 1
173
+ return true
140
174
  end
141
- logger("#{req.method}: #{req.path}")
142
- logger("\trequest body: #{req.body}") if req.body and req.body !~ /password/
143
- response, body = http.request(req)
144
- handle_response(response)
145
175
  end
176
+ return false
146
177
  end
147
178
 
148
179
  # connection.get("/root/login", :test_header => "x", :test_header2 => "y")
@@ -151,9 +182,9 @@ module RestConnection
151
182
  # additional_parameters = Hash or String of parameters to pass to HTTP::Get
152
183
  def get(href, additional_parameters = "")
153
184
  rest_connect do |base_uri,headers|
154
- href = "#{base_uri}/#{href}" unless begins_with_slash(href)
185
+ new_href = (href =~ /^\// ? href : "#{base_uri}/#{href}")
155
186
  params = requestify(additional_parameters) || ""
156
- new_path = URI.escape(href + @settings[:extension] + "?") + params
187
+ new_path = URI.escape(new_href + @settings[:extension] + "?") + params
157
188
  Net::HTTP::Get.new(new_path, headers)
158
189
  end
159
190
  end
@@ -165,8 +196,8 @@ module RestConnection
165
196
  # additional_parameters = Hash or String of parameters to pass to HTTP::Post
166
197
  def post(href, additional_parameters = {})
167
198
  rest_connect do |base_uri, headers|
168
- href = "#{base_uri}/#{href}" unless begins_with_slash(href)
169
- res = Net::HTTP::Post.new(href , headers)
199
+ new_href = (href =~ /^\// ? href : "#{base_uri}/#{href}")
200
+ res = Net::HTTP::Post.new(new_href , headers)
170
201
  unless additional_parameters.empty?
171
202
  res.set_content_type('application/json')
172
203
  res.body = additional_parameters.to_json
@@ -183,8 +214,8 @@ module RestConnection
183
214
  # additional_parameters = Hash or String of parameters to pass to HTTP::Put
184
215
  def put(href, additional_parameters = {})
185
216
  rest_connect do |base_uri, headers|
186
- href = "#{base_uri}/#{href}" unless begins_with_slash(href)
187
- new_path = URI.escape(href)
217
+ new_href = (href =~ /^\// ? href : "#{base_uri}/#{href}")
218
+ new_path = URI.escape(new_href)
188
219
  req = Net::HTTP::Put.new(new_path, headers)
189
220
  req.set_content_type('application/json')
190
221
  req.body = additional_parameters.to_json
@@ -199,8 +230,8 @@ module RestConnection
199
230
  # additional_parameters = Hash or String of parameters to pass to HTTP::Delete
200
231
  def delete(href, additional_parameters = {})
201
232
  rest_connect do |base_uri, headers|
202
- href = "#{base_uri}/#{href}" unless begins_with_slash(href)
203
- new_path = URI.escape(href)
233
+ new_href = (href =~ /^\// ? href : "#{base_uri}/#{href}")
234
+ new_path = URI.escape(new_href)
204
235
  req = Net::HTTP::Delete.new(href, headers)
205
236
  req.set_content_type('application/json')
206
237
  req.body = additional_parameters.to_json
@@ -226,14 +257,10 @@ module RestConnection
226
257
  return res
227
258
  end
228
259
  else
229
- raise "invalid response HTTP code: #{res.code.to_i}, #{res.code}, #{res.body}"
260
+ raise RestConnection::Errors.status_error(res)
230
261
  end
231
262
  end
232
263
 
233
- def begins_with_slash(href)
234
- href =~ /^\//
235
- end
236
-
237
264
  def logger(message)
238
265
  init_message = "Initializing Logging using "
239
266
  if @@logger.nil?
@@ -250,7 +277,7 @@ module RestConnection
250
277
  if @settings.nil?
251
278
  @@logger.info(message)
252
279
  else
253
- @@logger.info("[API v#{@settings[:common_headers]['X_API_VERSION']} ]" + message)
280
+ @@logger.info("[API v#{@settings[:common_headers]['X_API_VERSION']}] " + message)
254
281
  end
255
282
  end
256
283
 
@@ -272,6 +299,107 @@ module RestConnection
272
299
  "#{prefix}=#{CGI.escape(parameters.to_s)}"
273
300
  end
274
301
  end
302
+ end
303
+
304
+ module Errors
305
+ # HTTPStatusErrors, borrowed lovingly from the excon gem <3
306
+ class HTTPStatusError < StandardError
307
+ attr_reader :request, :response
308
+
309
+ def initialize(msg, response = nil, request = nil)
310
+ super(msg)
311
+ @request = request
312
+ @response = response
313
+ end
314
+ end
275
315
 
316
+ class Continue < HTTPStatusError; end # 100
317
+ class SwitchingProtocols < HTTPStatusError; end # 101
318
+ class OK < HTTPStatusError; end # 200
319
+ class Created < HTTPStatusError; end # 201
320
+ class Accepted < HTTPStatusError; end # 202
321
+ class NonAuthoritativeInformation < HTTPStatusError; end # 203
322
+ class NoContent < HTTPStatusError; end # 204
323
+ class ResetContent < HTTPStatusError; end # 205
324
+ class PartialContent < HTTPStatusError; end # 206
325
+ class MultipleChoices < HTTPStatusError; end # 300
326
+ class MovedPermanently < HTTPStatusError; end # 301
327
+ class Found < HTTPStatusError; end # 302
328
+ class SeeOther < HTTPStatusError; end # 303
329
+ class NotModified < HTTPStatusError; end # 304
330
+ class UseProxy < HTTPStatusError; end # 305
331
+ class TemporaryRedirect < HTTPStatusError; end # 307
332
+ class BadRequest < HTTPStatusError; end # 400
333
+ class Unauthorized < HTTPStatusError; end # 401
334
+ class PaymentRequired < HTTPStatusError; end # 402
335
+ class Forbidden < HTTPStatusError; end # 403
336
+ class NotFound < HTTPStatusError; end # 404
337
+ class MethodNotAllowed < HTTPStatusError; end # 405
338
+ class NotAcceptable < HTTPStatusError; end # 406
339
+ class ProxyAuthenticationRequired < HTTPStatusError; end # 407
340
+ class RequestTimeout < HTTPStatusError; end # 408
341
+ class Conflict < HTTPStatusError; end # 409
342
+ class Gone < HTTPStatusError; end # 410
343
+ class LengthRequired < HTTPStatusError; end # 411
344
+ class PreconditionFailed < HTTPStatusError; end # 412
345
+ class RequestEntityTooLarge < HTTPStatusError; end # 413
346
+ class RequestURITooLong < HTTPStatusError; end # 414
347
+ class UnsupportedMediaType < HTTPStatusError; end # 415
348
+ class RequestedRangeNotSatisfiable < HTTPStatusError; end # 416
349
+ class ExpectationFailed < HTTPStatusError; end # 417
350
+ class UnprocessableEntity < HTTPStatusError; end # 422
351
+ class InternalServerError < HTTPStatusError; end # 500
352
+ class NotImplemented < HTTPStatusError; end # 501
353
+ class BadGateway < HTTPStatusError; end # 502
354
+ class ServiceUnavailable < HTTPStatusError; end # 503
355
+ class GatewayTimeout < HTTPStatusError; end # 504
356
+
357
+ # Messages for nicer exceptions, from rfc2616
358
+ def self.status_error(response)
359
+ @errors ||= {
360
+ 100 => [RestConnection::Errors::Continue, 'Continue'],
361
+ 101 => [RestConnection::Errors::SwitchingProtocols, 'Switching Protocols'],
362
+ 200 => [RestConnection::Errors::OK, 'OK'],
363
+ 201 => [RestConnection::Errors::Created, 'Created'],
364
+ 202 => [RestConnection::Errors::Accepted, 'Accepted'],
365
+ 203 => [RestConnection::Errors::NonAuthoritativeInformation, 'Non-Authoritative Information'],
366
+ 204 => [RestConnection::Errors::NoContent, 'No Content'],
367
+ 205 => [RestConnection::Errors::ResetContent, 'Reset Content'],
368
+ 206 => [RestConnection::Errors::PartialContent, 'Partial Content'],
369
+ 300 => [RestConnection::Errors::MultipleChoices, 'Multiple Choices'],
370
+ 301 => [RestConnection::Errors::MovedPermanently, 'Moved Permanently'],
371
+ 302 => [RestConnection::Errors::Found, 'Found'],
372
+ 303 => [RestConnection::Errors::SeeOther, 'See Other'],
373
+ 304 => [RestConnection::Errors::NotModified, 'Not Modified'],
374
+ 305 => [RestConnection::Errors::UseProxy, 'Use Proxy'],
375
+ 307 => [RestConnection::Errors::TemporaryRedirect, 'Temporary Redirect'],
376
+ 400 => [RestConnection::Errors::BadRequest, 'Bad Request'],
377
+ 401 => [RestConnection::Errors::Unauthorized, 'Unauthorized'],
378
+ 402 => [RestConnection::Errors::PaymentRequired, 'Payment Required'],
379
+ 403 => [RestConnection::Errors::Forbidden, 'Forbidden'],
380
+ 404 => [RestConnection::Errors::NotFound, 'Not Found'],
381
+ 405 => [RestConnection::Errors::MethodNotAllowed, 'Method Not Allowed'],
382
+ 406 => [RestConnection::Errors::NotAcceptable, 'Not Acceptable'],
383
+ 407 => [RestConnection::Errors::ProxyAuthenticationRequired, 'Proxy Authentication Required'],
384
+ 408 => [RestConnection::Errors::RequestTimeout, 'Request Timeout'],
385
+ 409 => [RestConnection::Errors::Conflict, 'Conflict'],
386
+ 410 => [RestConnection::Errors::Gone, 'Gone'],
387
+ 411 => [RestConnection::Errors::LengthRequired, 'Length Required'],
388
+ 412 => [RestConnection::Errors::PreconditionFailed, 'Precondition Failed'],
389
+ 413 => [RestConnection::Errors::RequestEntityTooLarge, 'Request Entity Too Large'],
390
+ 414 => [RestConnection::Errors::RequestURITooLong, 'Request-URI Too Long'],
391
+ 415 => [RestConnection::Errors::UnsupportedMediaType, 'Unsupported Media Type'],
392
+ 416 => [RestConnection::Errors::RequestedRangeNotSatisfiable, 'Request Range Not Satisfiable'],
393
+ 417 => [RestConnection::Errors::ExpectationFailed, 'Expectation Failed'],
394
+ 422 => [RestConnection::Errors::UnprocessableEntity, 'Unprocessable Entity'],
395
+ 500 => [RestConnection::Errors::InternalServerError, 'InternalServerError'],
396
+ 501 => [RestConnection::Errors::NotImplemented, 'Not Implemented'],
397
+ 502 => [RestConnection::Errors::BadGateway, 'Bad Gateway'],
398
+ 503 => [RestConnection::Errors::ServiceUnavailable, 'Service Unavailable'],
399
+ 504 => [RestConnection::Errors::GatewayTimeout, 'Gateway Timeout']
400
+ }
401
+ error, message = @errors[response.code.to_i] || [RestConnection::Errors::HTTPStatusError, 'Unknown']
402
+ error.new("Invalid response HTTP code: #{response.code.to_i}: #{response.body}", response)
403
+ end
276
404
  end
277
405
  end