mirror of
https://github.com/cmur2/dyndnsd.git
synced 2025-07-01 22:30:19 +02:00
responder: refactor into Rack middleware and improve API conformance
This commit is contained in:
@ -2,19 +2,53 @@
|
||||
module Dyndnsd
|
||||
module Responder
|
||||
class DynDNSStyle
|
||||
def response_for_error(state)
|
||||
# general http errors
|
||||
return [405, {"Content-Type" => "text/plain"}, ["Method Not Allowed"]] if state == :method_forbidden
|
||||
return [404, {"Content-Type" => "text/plain"}, ["Not Found"]] if state == :not_found
|
||||
# specific errors
|
||||
return [200, {"Content-Type" => "text/plain"}, ["notfqdn"]] if state == :hostname_missing
|
||||
return [200, {"Content-Type" => "text/plain"}, ["nohost"]] if state == :host_forbidden
|
||||
return [200, {"Content-Type" => "text/plain"}, ["notfqdn"]] if state == :hostname_malformed
|
||||
def initialize(app)
|
||||
@app = app
|
||||
end
|
||||
|
||||
def response_for_changes(states, ip)
|
||||
body = states.map { |state| "#{state} #{ip.is_a?(Array) ? ip.join(' ') : ip}" }.join("\n")
|
||||
return [200, {"Content-Type" => "text/plain"}, [body]]
|
||||
def call(env)
|
||||
@app.call(env).tap do |status_code, headers, body|
|
||||
if headers.has_key?("X-DynDNS-Response")
|
||||
return decorate_dyndnsd_response(status_code, headers, body)
|
||||
else
|
||||
return decorate_other_response(status_code, headers, body)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def decorate_dyndnsd_response(status_code, headers, body)
|
||||
if status_code == 200
|
||||
[200, {"Content-Type" => "text/plain"}, [get_success_body(body[0], body[1])]]
|
||||
elsif status_code == 422
|
||||
get_error_response_map[headers["X-DynDNS-Response"]]
|
||||
end
|
||||
end
|
||||
|
||||
def decorate_other_response(status_code, headers, body)
|
||||
if status_code == 400
|
||||
[status_code, headers, "Bad Request"]
|
||||
elsif status_code == 401
|
||||
[status_code, headers, "badauth"]
|
||||
end
|
||||
end
|
||||
|
||||
def get_success_body(states, ip)
|
||||
ips = ip.is_a?(Array) ? ip.join(' ') : ip
|
||||
states.map { |state| "#{state} #{ips}" }.join("\n")
|
||||
end
|
||||
|
||||
def get_error_response_map
|
||||
{
|
||||
# general http errors
|
||||
'method_forbidden' => [405, {"Content-Type" => "text/plain"}, ["Method Not Allowed"]],
|
||||
'not_found' => [404, {"Content-Type" => "text/plain"}, ["Not Found"]],
|
||||
# specific errors
|
||||
'hostname_missing' => [200, {"Content-Type" => "text/plain"}, ["notfqdn"]],
|
||||
'hostname_malformed' => [200, {"Content-Type" => "text/plain"}, ["notfqdn"]],
|
||||
'host_forbidden' => [200, {"Content-Type" => "text/plain"}, ["nohost"]]
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -2,19 +2,54 @@
|
||||
module Dyndnsd
|
||||
module Responder
|
||||
class RestStyle
|
||||
def response_for_error(state)
|
||||
# general http errors
|
||||
return [405, {"Content-Type" => "text/plain"}, ["Method Not Allowed"]] if state == :method_forbidden
|
||||
return [404, {"Content-Type" => "text/plain"}, ["Not Found"]] if state == :not_found
|
||||
# specific errors
|
||||
return [422, {"Content-Type" => "text/plain"}, ["Hostname missing"]] if state == :hostname_missing
|
||||
return [403, {"Content-Type" => "text/plain"}, ["Forbidden"]] if state == :host_forbidden
|
||||
return [422, {"Content-Type" => "text/plain"}, ["Hostname malformed"]] if state == :hostname_malformed
|
||||
def initialize(app)
|
||||
@app = app
|
||||
end
|
||||
|
||||
def response_for_changes(states, ip)
|
||||
body = states.map { |state| state == :good ? "Changed to #{ip.is_a?(Array) ? ip.join(' ') : ip}" : "No change needed for #{ip.is_a?(Array) ? ip.join(' ') : ip}" }.join("\n")
|
||||
return [200, {"Content-Type" => "text/plain"}, [body]]
|
||||
def call(env)
|
||||
@app.call(env).tap do |status_code, headers, body|
|
||||
if headers.has_key?("X-DynDNS-Response")
|
||||
return decorate_dyndnsd_response(status_code, headers, body)
|
||||
else
|
||||
return decorate_other_response(status_code, headers, body)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def decorate_dyndnsd_response(status_code, headers, body)
|
||||
if status_code == 200
|
||||
[200, {"Content-Type" => "text/plain"}, [get_success_body(body[0], body[1])]]
|
||||
elsif status_code == 422
|
||||
get_error_response_map[headers["X-DynDNS-Response"]]
|
||||
end
|
||||
end
|
||||
|
||||
def decorate_other_response(status_code, headers, body)
|
||||
if status_code == 400
|
||||
[status_code, headers, "Bad Request"]
|
||||
elsif status_code == 401
|
||||
[status_code, headers, "Unauthorized"]
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
def get_success_response(states, ip)
|
||||
ips = ip.is_a?(Array) ? ip.join(' ') : ip
|
||||
states.map { |state| state == :good ? "Changed to #{ips}" : "No change needed for #{ips}" }.join("\n")
|
||||
end
|
||||
|
||||
def get_error_response_map
|
||||
{
|
||||
# general http errors
|
||||
'method_forbidden' => [405, {"Content-Type" => "text/plain"}, ["Method Not Allowed"]],
|
||||
'not_found' => [404, {"Content-Type" => "text/plain"}, ["Not Found"]],
|
||||
# specific errors
|
||||
'hostname_missing' => [422, {"Content-Type" => "text/plain"}, ["Hostname missing"]],
|
||||
'hostname_malformed' => [422, {"Content-Type" => "text/plain"}, ["Hostname malformed"]],
|
||||
'host_forbidden' => [403, {"Content-Type" => "text/plain"}, ["Forbidden"]]
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
Reference in New Issue
Block a user