我想回复一个Content-Length: 42
标题,而不是Transfer-Encoding: chunked
标题。
我在Rails 5.0.0.beta3上,这是我的application.rb:
require File.expand_path('../boot', __FILE__)
require "rails"
# Pick the frameworks you want:
require "active_model/railtie"
require "active_job/railtie"
require "active_record/railtie"
require "action_controller/railtie"
require "action_mailer/railtie"
require "action_view/railtie"
require "action_cable/engine"
require "sprockets/railtie"
# require "rails/test_unit/railtie"
# Require the gems listed in Gemfile, including any gems
# you've limited to :test, :development, or :production.
Bundler.require(*Rails.groups)
module FuuBarApp
class Application < Rails::Application
# Settings in config/environments/* take precedence over those specified here.
# Application configuration should go into files in config/initializers
# -- all .rb files in that directory are automatically loaded.
config.active_record.schema_format = :sql
# config.api_only = true
config.autoload_paths << Rails.root.join('lib')
# content compression
config.middleware.use(Rack::Deflater)
# looks like for view partial caching
config.middleware.delete(ActionView::Digestor::PerRequestDigestCacheExpiry)
# remove session related middleware
config.middleware.delete(ActionDispatch::Cookies)
config.middleware.delete(ActionDispatch::Session::CookieStore)
config.middleware.delete(ActionDispatch::Flash)
# remove browser related middleware
# config.middleware.delete(ActionDispatch::BestStandardsSupport)
config.middleware.delete(Rack::MethodOverride)
# used to serve static assets
config.middleware.delete(ActionDispatch::Static)
# sets env["rack.multithread"] flag to true and wraps the application within a Mutex
config.middleware.delete(Rack::Lock)
# used for memory caching. This cache is not thread safe
# config.middleware.delete(ActiveSupport::Cache::Strategy::LocalCache::Middleware)
# sets an X-Runtime header, containing the time (in seconds) taken to execute the request
config.middleware.delete(Rack::Runtime)
# makes a unique X-Request-Id header available to the response and enables the ActionDispatch::Request#uuid method
config.middleware.delete(ActionDispatch::RequestId)
# notifies the logs that the request has began
# after request is complete, flushes all the logs
config.middleware.delete(Rails::Rack::Logger)
# rescues any exception returned by the application and calls an exceptions app that will wrap it in a format for the end user
config.middleware.delete(ActionDispatch::ShowExceptions)
# responsible for logging exceptions and showing a debugging page in case the request is local
config.middleware.delete(ActionDispatch::DebugExceptions)
# checks for IP spoofing attacks
config.middleware.delete(ActionDispatch::RemoteIp)
# runs the prepare callbacks before serving the request
config.middleware.delete(ActionDispatch::Callbacks)
# cleans active connections after each request, unless the rack.test key in the request environment is set to true
config.middleware.delete(ActiveRecord::ConnectionAdapters::ConnectionManagement)
# adds support for "Conditional GET" so that server responds with nothing if page wasn't changed
config.middleware.delete(Rack::ConditionalGet)
# adds ETag header on all String bodies
# ETags are used to validate cache
config.middleware.delete(Rack::ETag)
config.middleware.use(Rack::ContentLength)
config.action_dispatch.default_headers = {}
end
end
我们可以看到Rack::ContentLength
存在。
在操作中,我还将标题设置为:
response.headers['Content-Length'] = body.length
但是HTTP响应中没有任何Content-Length
标头:
Allow:GET, HEAD, OPTIONS
Cache-Control:max-age=31557600, public
Content-Encoding:gzip
Content-Language:en
Content-Type:application/json; charset=utf-8
ETag:3bfc269594ef649228e9a74bab00f042efc91d5acc6fbee31a382e80d42388fe
Last-Modified:Tue, 03 May 2016 19:59:21 GMT
Link:</>; class="home"; rel="self"
Transfer-Encoding:chunked
Vary:Accept-Encoding
顺便说一句,我不知道如何删除Transfer-Encoding
不需要的标题。
如果您有最佳做法或小费,请欢迎。感谢。
答案 0 :(得分:1)
当我在response.headers["Content-Length"] = **
中的after_action
处写这样的控制器时:
class ActivitiesController < ApplicationController
after_action :set_version_header
def index
return render plain: params[:echostr]
end
private
def set_version_header
response.headers["Content-Length"] = params[:echostr].length
end
end
它会在响应标头
中将Transfer-Encoding
替换为Content-Length
答案 1 :(得分:1)
这里看起来问题是客户端(浏览器)要求压缩响应(使用accept-encoding标头)。我可以告诉这个,因为响应有一个gzip的Content-Encoding。因此,您的Rails应用程序可能设置了未压缩内容的Content-Length标头,但随后压缩了响应(在客户端请求时)。大多数服务器压缩响应内联(流/块压缩),因此它们在整个流被压缩之前开始返回字节,这意味着无法知道最终大小。由于标题需要在响应字节之前设置,服务器可以做的最好是使用Transfer-Encoding:Chunked替换未压缩(无效)的内容长度。
您需要在客户端请求压缩(不是浏览器的实际选项)或关闭Ruby服务器上的压缩。默认的Rack :: Deflater中间件可以配置为仅压缩某些内容类型,或者您可以配置:if块,它可以根据您想要的任何条件关闭压缩。有关配置选项,请参阅Rack::Deflater。