在Rack中间件中如何忽略默认请求头,仅打印additional headers?
解决Rack::Request仅记录自定义请求头的问题
要在Rack::Request的env中仅提取你自己传递的额外请求头,核心是区分Rack自动生成/客户端默认携带的头和你自定义的头,下面提供几种可行的实现方式:
方法一:筛选特定前缀的自定义头
如果你的自定义请求头都遵循X-前缀规范(比如X-Custom-Header),可以直接筛选env中以HTTP_X_开头的键:
request = Rack::Request.new(env) custom_headers = request.env.select do |key, value| key.start_with?('HTTP_X_') end # 还原原始头名称:去掉HTTP_前缀,下划线转连字符,首字母大写 formatted_custom_headers = custom_headers.transform_keys do |key| key.sub('HTTP_', '').split('_').map(&:capitalize).join('-') end p formatted_custom_headers
方法二:排除已知的默认请求头
先定义一组常见的默认请求头对应的env键,再从env中排除这些键:
DEFAULT_HTTP_HEADERS = %w[ HTTP_ACCEPT HTTP_ACCEPT_ENCODING HTTP_ACCEPT_LANGUAGE HTTP_HOST HTTP_USER_AGENT HTTP_CONNECTION HTTP_CACHE_CONTROL ] request = Rack::Request.new(env) custom_headers = request.env.reject do |key, value| DEFAULT_HTTP_HEADERS.include?(key) || !key.start_with?('HTTP_') end # 格式化头名称(同方法一) formatted_custom_headers = custom_headers.transform_keys do |key| key.sub('HTTP_', '').split('_').map(&:capitalize).join('-') end p formatted_custom_headers
方法三:对比空请求的默认头集合
如果不确定默认头范围,可以先生成空请求的env,提取其中的HTTP头集合,再和当前请求的env取差集:
# 生成空请求的默认env empty_env = Rack::MockRequest.env_for('http://example.com') default_http_keys = empty_env.keys.select { |k| k.start_with?('HTTP_') } request = Rack::Request.new(env) current_http_keys = request.env.keys.select { |k| k.start_with?('HTTP_') } # 计算差集得到自定义头的键 custom_keys = current_http_keys - default_http_keys custom_headers = request.env.slice(*custom_keys) # 格式化头名称 formatted_custom_headers = custom_headers.transform_keys do |key| key.sub('HTTP_', '').split('_').map(&:capitalize).join('-') end p formatted_custom_headers
注意:Rack会将请求头转换为HTTP_开头、大写加下划线的格式(比如X-Custom-Header变成HTTP_X_CUSTOM_HEADER),最后格式化时需要还原回原始头名称格式。
内容的提问来源于stack exchange,提问作者Ramachandra Hegde
相关产品推荐
相关产品推荐

