|
| 1 | +# frozen_string_literal: true |
| 2 | + |
| 3 | +module Smithy |
| 4 | + module Client |
| 5 | + module Plugins |
| 6 | + # @api private |
| 7 | + class HostPrefix < Plugin |
| 8 | + option( |
| 9 | + :disable_host_prefix_injection, |
| 10 | + default: false, |
| 11 | + doc_type: 'Boolean', |
| 12 | + docstring: 'When true, the SDK will not prepend the modeled host prefix to the endpoint.' |
| 13 | + ) do |_config| |
| 14 | + value = ENV['DISABLE_HOST_PREFIX_INJECTION'] || 'false' |
| 15 | + Util.str_to_bool(value) |
| 16 | + end |
| 17 | + |
| 18 | + def after_initialize(client) |
| 19 | + validate_disable_host_prefix_injection(client.config) |
| 20 | + end |
| 21 | + |
| 22 | + def validate_disable_host_prefix_injection(config) |
| 23 | + return if [true, false].include?(config.disable_host_prefix_injection) |
| 24 | + |
| 25 | + raise ArgumentError, |
| 26 | + ':disable_host_prefix_injection must be either `true` or `false`' |
| 27 | + end |
| 28 | + |
| 29 | + def add_handlers(handlers, config) |
| 30 | + handlers.add(Handler, priority: 25) unless config.disable_host_prefix_injection |
| 31 | + end |
| 32 | + |
| 33 | + # @api private |
| 34 | + class Handler < Smithy::Client::Handler |
| 35 | + def call(context) |
| 36 | + host_prefix = context.operation.traits.dig('smithy.api#endpoint', 'hostPrefix') |
| 37 | + apply_host_prefix(context, host_prefix) if host_prefix |
| 38 | + @handler.call(context) |
| 39 | + end |
| 40 | + |
| 41 | + private |
| 42 | + |
| 43 | + # TODO: optimize this to collect all labels in one pass |
| 44 | + def apply_host_prefix(context, host_prefix) |
| 45 | + input = context.operation.input |
| 46 | + prefix = host_prefix.gsub(/\{.+?}/) do |label| |
| 47 | + label_value(input, label.delete('{}'), context.params) |
| 48 | + end |
| 49 | + context.request.endpoint.host = prefix + context.request.endpoint.host |
| 50 | + end |
| 51 | + |
| 52 | + def label_value(input, label, params) |
| 53 | + name = nil |
| 54 | + input.members.each do |member_name, member_shape| |
| 55 | + next unless member_shape.traits.include?('smithy.api#hostLabel') |
| 56 | + next unless member_shape.name == label |
| 57 | + |
| 58 | + name = member_name |
| 59 | + end |
| 60 | + raise ArgumentError, "#{label} is not a valid host label" if name.nil? |
| 61 | + raise ArgumentError, "params[#{name}] must not be nil or blank" if params[name].nil? || params[name].empty? |
| 62 | + |
| 63 | + params[name] |
| 64 | + end |
| 65 | + end |
| 66 | + end |
| 67 | + end |
| 68 | + end |
| 69 | +end |
0 commit comments