Browse Source

[ruby/rack-sequel] Only set headers not created by servers (#9570)

Some servers already set the 'Date' or 'Content-Length' headers.

+-----------+------------------------------------+-----+-----+------+-------+--------------+
|       name|                         branch_name|   db|query|update|fortune|weighted_score|
+-----------+------------------------------------+-----+-----+------+-------+--------------+
|rack-sequel|                              master|44962|19605| 10677|  34058|          1373|
|rack-sequel|rack-sequel/remove-redundant-headers|45573|20403| 12342|  34488|          1507|
+-----------+------------------------------------+-----+-----+------+-------+--------------+
Petrik de Heus 5 months ago
parent
commit
befd25d691
2 changed files with 75 additions and 55 deletions
  1. 0 24
      frameworks/Ruby/rack-sequel/boot.rb
  2. 75 31
      frameworks/Ruby/rack-sequel/hello_world.rb

+ 0 - 24
frameworks/Ruby/rack-sequel/boot.rb

@@ -1,31 +1,7 @@
 # frozen_string_literal: true
 require 'bundler/setup'
-require 'time'
 
-MAX_PK = 10_000
-ID_RANGE = (1..10_000).freeze
-ALL_IDS = ID_RANGE.to_a
-QUERIES_MIN = 1
-QUERIES_MAX = 500
 SEQUEL_NO_ASSOCIATIONS = true
-CONTENT_TYPE = 'Content-Type'
-JSON_TYPE = 'application/json'
-HTML_TYPE = 'text/html; charset=utf-8'
-PLAINTEXT_TYPE = 'text/plain'
-DATE_HEADER = 'Date'
-SERVER_HEADER = 'Server'
-
-SERVER_STRING =
-  if defined?(PhusionPassenger)
-    [
-      PhusionPassenger::SharedConstants::SERVER_TOKEN_NAME,
-      PhusionPassenger::VERSION_STRING
-    ].join('/').freeze
-  elsif defined?(Puma)
-    Puma::Const::PUMA_SERVER_STRING
-  elsif defined?(Unicorn)
-    Unicorn::HttpParser::DEFAULTS['SERVER_SOFTWARE']
-  end
 
 Bundler.require(:default) # Load core modules
 

+ 75 - 31
frameworks/Ruby/rack-sequel/hello_world.rb

@@ -1,12 +1,31 @@
 # frozen_string_literal: true
+require 'time'
 
 # Our Rack application to be executed by rackup
 class HelloWorld
-  DEFAULT_HEADERS = {}.tap do |h|
-    h[SERVER_HEADER] = SERVER_STRING if SERVER_STRING
-
-    h.freeze
-  end
+  MAX_PK = 10_000
+  ID_RANGE = (1..10_000).freeze
+  ALL_IDS = ID_RANGE.to_a
+  QUERIES_MIN = 1
+  QUERIES_MAX = 500
+  CONTENT_TYPE = 'Content-Type'
+  CONTENT_LENGTH = 'Content-Length'
+  JSON_TYPE = 'application/json'
+  HTML_TYPE = 'text/html; charset=utf-8'
+  PLAINTEXT_TYPE = 'text/plain'
+  DATE = 'Date'
+  SERVER = 'Server'
+  SERVER_STRING = if defined?(PhusionPassenger)
+                    'Passenger'
+                  elsif defined?(Puma)
+                    'Puma'
+                  elsif defined?(Iodine)
+                    'Iodine'
+                  elsif defined?(Unicorn)
+                    'Unicorn'
+                  else
+                    'Ruby Rack'
+                  end
 
   def bounded_queries(env)
     params = Rack::Utils.parse_query(env['QUERY_STRING'])
@@ -87,35 +106,60 @@ class HelloWorld
   end
 
   def call(env)
-    content_type, *body =
-      case env['PATH_INFO']
-      when '/json'
-        # Test type 1: JSON serialization
-        [JSON_TYPE, { message: 'Hello, World!' }.to_json]
-      when '/db'
-        # Test type 2: Single database query
-        [JSON_TYPE, db.to_json]
-      when '/queries'
-        # Test type 3: Multiple database queries
-        [JSON_TYPE, queries(env).to_json]
-      when '/fortunes'
-        # Test type 4: Fortunes
-        [HTML_TYPE, fortunes]
-      when '/updates'
-        # Test type 5: Database updates
-        [JSON_TYPE, updates(env).to_json]
-      when '/plaintext'
-        # Test type 6: Plaintext
-        [PLAINTEXT_TYPE, 'Hello, World!']
-      end
+    case env['PATH_INFO']
+    when '/json'
+      # Test type 1: JSON serialization
+      respond JSON_TYPE, { message: 'Hello, World!' }.to_json
+    when '/db'
+      # Test type 2: Single database query
+      respond JSON_TYPE, db.to_json
+    when '/queries'
+      # Test type 3: Multiple database queries
+      respond JSON_TYPE, queries(env).to_json
+    when '/fortunes'
+      # Test type 4: Fortunes
+      respond HTML_TYPE, fortunes
+    when '/updates'
+      # Test type 5: Database updates
+      respond JSON_TYPE, updates(env).to_json
+    when '/plaintext'
+      # Test type 6: Plaintext
+      respond PLAINTEXT_TYPE, 'Hello, World!'
+    end
+  end
+
+  private
 
+  def respond(content_type, body)
     [
       200,
-      DEFAULT_HEADERS.merge(
-        CONTENT_TYPE => content_type,
-        DATE_HEADER => Time.now.httpdate
-      ),
-      body
+      headers(content_type, body),
+      [body]
     ]
   end
+
+  if defined?(Unicorn)
+    def headers(content_type, body)
+      {
+        CONTENT_TYPE => content_type,
+        SERVER => SERVER_STRING,
+        CONTENT_LENGTH => body.bytesize.to_s
+      }
+    end
+  elsif defined?(Puma)
+    def headers(content_type, _)
+      {
+        CONTENT_TYPE => content_type,
+        SERVER => SERVER_STRING,
+        DATE => Time.now.utc.httpdate
+      }
+    end
+  else
+    def headers(content_type, _)
+      {
+        CONTENT_TYPE => content_type,
+        SERVER => SERVER_STRING
+      }
+    end
+  end
 end