NGINX is an awesome server, but unfortunately contains an error in earlier versions (pre 0.8.32), that sends the incorrect headers for 201 (created) responses. It does not set the Content-Length header, which causes modern browsers to keep the connection open and wait until the timeout value is exceeded.
There are two possible fixes for this; Upgrade NGINX to version 0.8.32 or greater, or fix the issue in your server side code. I’ll show you how we can do the latter, using Rack.
Rack provides a minimal, modular and adaptable interface for developing web applications in Ruby. By wrapping HTTP requests and responses in the simplest way possible, it unifies and distills the API for web servers, web frameworks, and software in between (the so-called middleware) into a single method call.
We will use a piece of Rack middleware to set the correct headers for any 201 responses.
Copy the code below into lib/content_length_fix.rb:
module Nginx
class ContentLengthFix
def initialize(app)
@app = app
end
def call(env)
status, headers, response = @app.call(env)
headers["Content-Length"] = response.length.to_s if status == 201
[status, headers, response]
end
end
end
Then add the following to your config.ru file:
require 'content_length_fix'
use Nginx::ContentLengthFix
Rejoice and your 201 responses now have the correct headers set!
How many times have you looked at some ruby code and found strange variable names (eg. $0, $:, etc) and wondered what they meant? Below is a list of cryptic global variable names in ruby and their meanings.
Environmental Global Variables
$: (Dollar Colon)
$: is basically a shorthand version of $LOAD_PATH. $: contains an array of paths that your script will search through when using require.
>> $: === $LOAD_PATH
=> true
>> $:
=> [".", "/Users/jimneath/.ruby"]
>> $: << '/test/path' # Add a directory to load path
=> [".", "/Users/jimneath/.ruby", "/test/path"]
$0 (Dollar Zero)
$0 contains the name of the ruby program being run. This is typically the script name.
example.rb
Jims-MacBook-Pro:~/Desktop ruby example.rb
example.rb
Jims-MacBook-Pro:~/Desktop irb
>> $0
=> "irb"
$* (Dollar Splat)
$* is basically shorthand for ARGV. $* contains the command line arguments that were passed to the script.
example.rb
puts "$*: " << $*.inspect
puts "ARGV: " << ARGV.inspect
Jims-MacBook-Pro:~/Desktop ruby example.rb hello world
$*: ["hello", "world"]
ARGV: ["hello", "world"]
$? (Dollar Question Mark)
$? returns the exit status of the last child process to finish.
>> `pwd` # Show current directory
=> "/Users/jimneath/Desktop\n"
>> $?
=> #<Process::Status: pid=17867,exited(0)>
>> `fake command` # This will fail
(irb):7: command not found: fake command
=> ""
>> $?
=> #<Process::Status: pid=17871,exited(127)>
$$ (Dollar Dollar)
$$ returns the process number of the program currently being ran.
Jims-MacBook-Pro:~/Desktop irb
>> $$ # Show process id
=> 17916
>> puts `ps aux | grep irb`
jimneath 17919 0.0 0.0 599780 388 s000 R+ 2:51PM 0:00.00 grep irb
jimneath 17917 0.0 0.0 600252 680 s000 S+ 2:51PM 0:00.01 sh -c ps aux | grep irb
jimneath 17916 0.0 0.6 85336 12568 s000 S+ 2:51PM 0:00.75 irb
Regular Expression Global Variables
$~ (Dollar Tilde)
$~ contains the MatchData from the previous successful pattern match.
>> "hello world".match(/world/) === $~
=> true
>> $~
=> #<MatchData:0x12be0e8>
>> $~.to_a
=> ["world"]
$1, $2, $3, $4 etc
$1-$9 represent the content of the previous successful pattern match.
>> "hello world".match(/(hello) (world)/)
=> #<MatchData:0x12b06f0>
>> $1
=> "hello"
>> $2
=> "world"
>> $3
=> nil
$& (Dollar Ampersand)
$& contains the matched string from the previous successful pattern match.
>> "the quick brown fox".match(/quick.*fox/)
=> #<MatchData:0x129cc40>
>> $&
=> "quick brown fox"
$+ (Dollar Plus)
$+ contains the last match from the previous successful pattern match.
>> "the quick brown fox".match(/(quick) (brown) (fox)/)
=> #<MatchData:0x1294a04>
>> $~.to_a
=> ["quick brown fox", "quick", "brown", "fox"]
>> $+
=> "fox"
$` (Dollar Backtick)
$` contains the string before the actual matched string of the previous successful pattern match.
>> "the quick brown fox".match(/quick.*fox/)
=> #<MatchData:0x12882cc>
>> $&
=> "quick brown fox" # The matched string
>> $`
=> "the " # The text preceding the matched string
$’ (Dollar Apostrophe)
$' contains the string after the actual matched string of the previous successful pattern match.
>> "the quick brown fox".match(/quick/)
=> #<MatchData:0x1280c48>
>> $&
=> "quick" # The matched string
>> $'
=> " brown fox" # The text following the matched string
Exceptional Global Variables
$! (Dollar Bang)
$! contains the Exception that was passed to raise.
>> 0 / 0 rescue $!
=> #<ZeroDivisionError: divided by 0>
$@ (Dollar At Symbol)
$@ contains the backtrace for the last Exception raised.
>> 0 / 0 rescue puts $@
(irb):16:in `/'
(irb):16:in `irb_binding'
/usr/local/lib/ruby/1.8/irb/workspace.rb:52:in `irb_binding'
/usr/local/lib/ruby/1.8/irb/workspace.rb:52
=> nil
Any More Cryptic Global Variables?
Let me know if I’ve missed any off the list and I’ll get it updated.