Module: Puppet::Network::HTTP::Handler
- Includes:
- Authentication, Authorization, API::V1
- Included in:
- RackREST, WEBrickREST
- Defined in:
- lib/puppet/network/http/handler.rb
Defined Under Namespace
Classes: HTTPError, HTTPNotAcceptableError, HTTPNotFoundError
Constant Summary collapse
- DISALLOWED_KEYS =
These shouldn’t be allowed to be set by clients in the query string, for security reasons.
["node", "ip"]
Constants included from API::V1
Instance Attribute Summary collapse
- #handler ⇒ Object readonly
- #server ⇒ Object readonly
Instance Method Summary collapse
-
#accept_header(request) ⇒ Object
Retrieve the accept header from the http request.
-
#content_type_header(request) ⇒ Object
Retrieve the Content-Type header from the http request.
-
#do_destroy(indirection, key, params, request, response) ⇒ Object
Execute our destroy.
- #do_exception(response, exception, status = 400) ⇒ Object
-
#do_find(indirection, key, params, request, response) ⇒ Object
Execute our find.
-
#do_head(indirection, key, params, request, response) ⇒ Object
Execute our head.
-
#do_save(indirection, key, params, request, response) ⇒ Object
Execute our save.
-
#do_search(indirection, key, params, request, response) ⇒ Object
Execute our search.
- #format_to_mime(format) ⇒ Object
-
#headers(request) ⇒ Object
Retrieve all headers from the http request, as a hash with the header names (lower-cased) as the keys.
- #initialize_for_puppet(server) ⇒ Object
-
#process(request, response) ⇒ Object
handle an HTTP request.
- #request_format(request) ⇒ Object
-
#resolve_node(result) ⇒ Object
resolve node name from peer’s ip address this is used when the request is unauthenticated.
-
#set_content_type(response, format) ⇒ Object
Set the specified format as the content type of the response.
-
#set_response(response, body, status = 200) ⇒ Object
Set the response up, with the body and status.
Methods included from Authentication
Methods included from Authorization
#authconfig, #check_authorization
Methods included from API::V1
#indirection2uri, #indirection_method, #plurality, #pluralize, #request_to_uri_and_body, #uri2indirection
Instance Attribute Details
#handler ⇒ Object (readonly)
42 43 44 |
# File 'lib/puppet/network/http/handler.rb', line 42 def handler @handler end |
#server ⇒ Object (readonly)
42 43 44 |
# File 'lib/puppet/network/http/handler.rb', line 42 def server @server end |
Instance Method Details
#accept_header(request) ⇒ Object
Retrieve the accept header from the http request.
51 52 53 |
# File 'lib/puppet/network/http/handler.rb', line 51 def accept_header(request) raise NotImplementedError end |
#content_type_header(request) ⇒ Object
Retrieve the Content-Type header from the http request.
56 57 58 |
# File 'lib/puppet/network/http/handler.rb', line 56 def content_type_header(request) raise NotImplementedError end |
#do_destroy(indirection, key, params, request, response) ⇒ Object
Execute our destroy.
183 184 185 186 187 188 189 190 |
# File 'lib/puppet/network/http/handler.rb', line 183 def do_destroy(indirection, key, params, request, response) formatter = accepted_response_formatter_or_yaml_for(indirection.model, request) result = indirection.destroy(key, params) set_content_type(response, formatter) set_response(response, formatter.render(result)) end |
#do_exception(response, exception, status = 400) ⇒ Object
124 125 126 127 128 129 130 131 132 133 134 135 |
# File 'lib/puppet/network/http/handler.rb', line 124 def do_exception(response, exception, status=400) if exception.is_a?(Puppet::Network::AuthorizationError) # make sure we return the correct status code # for authorization issues status = 403 if status == 400 end Puppet.log_exception(exception) set_content_type(response, "text/plain") set_response(response, exception.to_s, status) end |
#do_find(indirection, key, params, request, response) ⇒ Object
Execute our find.
138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 |
# File 'lib/puppet/network/http/handler.rb', line 138 def do_find(indirection, key, params, request, response) unless result = indirection.find(key, params) raise HTTPNotFoundError, "Could not find #{indirection.name} #{key}" end format = accepted_response_formatter_for(indirection.model, request) set_content_type(response, format) rendered_result = result if result.respond_to?(:render) Puppet::Util::Profiler.profile("Rendered result in #{format}") do rendered_result = result.render(format) end end Puppet::Util::Profiler.profile("Sent response") do set_response(response, rendered_result) end end |
#do_head(indirection, key, params, request, response) ⇒ Object
Execute our head.
159 160 161 162 163 164 165 166 |
# File 'lib/puppet/network/http/handler.rb', line 159 def do_head(indirection, key, params, request, response) unless indirection.head(key, params) raise HTTPNotFoundError, "Could not find #{indirection.name} #{key}" end # No need to set a response because no response is expected from a # HEAD request. All we need to do is not die. end |
#do_save(indirection, key, params, request, response) ⇒ Object
Execute our save.
193 194 195 196 197 198 199 200 201 |
# File 'lib/puppet/network/http/handler.rb', line 193 def do_save(indirection, key, params, request, response) formatter = accepted_response_formatter_or_yaml_for(indirection.model, request) sent_object = read_body_into_model(indirection.model, request) result = indirection.save(sent_object, key) set_content_type(response, formatter) set_response(response, formatter.render(result)) end |
#do_search(indirection, key, params, request, response) ⇒ Object
Execute our search.
169 170 171 172 173 174 175 176 177 178 179 180 |
# File 'lib/puppet/network/http/handler.rb', line 169 def do_search(indirection, key, params, request, response) result = indirection.search(key, params) if result.nil? raise HTTPNotFoundError, "Could not find instances in #{indirection.name} with '#{key}'" end format = accepted_response_formatter_for(indirection.model, request) set_content_type(response, format) set_response(response, indirection.model.render_multiple(format, result)) end |
#format_to_mime(format) ⇒ Object
72 73 74 |
# File 'lib/puppet/network/http/handler.rb', line 72 def format_to_mime(format) format.is_a?(Puppet::Network::Format) ? format.mime : format end |
#headers(request) ⇒ Object
Retrieve all headers from the http request, as a hash with the header names (lower-cased) as the keys
46 47 48 |
# File 'lib/puppet/network/http/handler.rb', line 46 def headers(request) raise NotImplementedError end |
#initialize_for_puppet(server) ⇒ Object
76 77 78 |
# File 'lib/puppet/network/http/handler.rb', line 76 def initialize_for_puppet(server) @server = server end |
#process(request, response) ⇒ Object
handle an HTTP request
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 |
# File 'lib/puppet/network/http/handler.rb', line 81 def process(request, response) request_headers = headers(request) request_params = params(request) request_method = http_method(request) request_path = path(request) response[Puppet::Network::HTTP::HEADER_PUPPET_VERSION] = Puppet.version configure_profiler(request_headers, request_params) Puppet::Util::Profiler.profile("Processed request #{request_method} #{request_path}") do indirection_name, method, key, params = uri2indirection(request_method, request_path, request_params) (indirection_name, method, key, params) warn_if_near_expiration(client_cert(request)) indirection = Puppet::Indirector::Indirection.instance(indirection_name.to_sym) raise ArgumentError, "Could not find indirection '#{indirection_name}'" unless indirection if !indirection.allow_remote_requests? raise HTTPNotFoundError, "No handler for #{indirection.name}" end send("do_#{method}", indirection, key, params, request, response) end rescue HTTPError => e return do_http_control_exception(response, e) rescue Exception => e return do_exception(response, e) ensure cleanup(request) end |
#request_format(request) ⇒ Object
60 61 62 63 64 65 66 67 68 69 70 |
# File 'lib/puppet/network/http/handler.rb', line 60 def request_format(request) if header = content_type_header(request) header.gsub!(/\s*;.*$/,'') # strip any charset format = Puppet::Network::FormatHandler.mime(header) raise "Client sent a mime-type (#{header}) that doesn't correspond to a format we support" if format.nil? report_if_deprecated(format) return format.name.to_s if format.suitable? end raise "No Content-Type header was received, it isn't possible to unserialize the request" end |
#resolve_node(result) ⇒ Object
resolve node name from peer’s ip address this is used when the request is unauthenticated
205 206 207 208 209 210 211 212 |
# File 'lib/puppet/network/http/handler.rb', line 205 def resolve_node(result) begin return Resolv.getname(result[:ip]) rescue => detail Puppet.err "Could not resolve #{result[:ip]}: #{detail}" end result[:ip] end |
#set_content_type(response, format) ⇒ Object
Set the specified format as the content type of the response.
120 121 122 |
# File 'lib/puppet/network/http/handler.rb', line 120 def set_content_type(response, format) raise NotImplementedError end |
#set_response(response, body, status = 200) ⇒ Object
Set the response up, with the body and status.
115 116 117 |
# File 'lib/puppet/network/http/handler.rb', line 115 def set_response(response, body, status = 200) raise NotImplementedError end |