diff options
Diffstat (limited to 'lib/rainbows/response/range.rb')
-rw-r--r-- | lib/rainbows/response/range.rb | 34 |
1 files changed, 34 insertions, 0 deletions
diff --git a/lib/rainbows/response/range.rb b/lib/rainbows/response/range.rb new file mode 100644 index 0000000..4c0d4a1 --- /dev/null +++ b/lib/rainbows/response/range.rb @@ -0,0 +1,34 @@ +# -*- encoding: binary -*- +# :enddoc: +module Rainbows::Response::Range + HTTP_RANGE = 'HTTP_RANGE' + Content_Range = 'Content-Range'.freeze + Content_Length = 'Content-Length'.freeze + + # This does not support multipart responses (does anybody actually + # use those?) +headers+ is always a Rack::Utils::HeaderHash + def parse_range(env, status, headers) + if 200 == status.to_i && + (clen = headers[Content_Length]) && + /\Abytes=(\d+-\d*|\d*-\d+)\z/ =~ env[HTTP_RANGE] + a, b = $1.split(/-/) + clen = clen.to_i + if b.nil? # bytes=M- + offset = a.to_i + count = clen - offset + elsif a.empty? # bytes=-N + offset = clen - b.to_i + count = clen - offset + else # bytes=M-N + offset = a.to_i + count = b.to_i + 1 - offset + end + raise Rainbows::Response416 if count <= 0 || offset >= clen + count = clen if count > clen + headers[Content_Length] = count.to_s + headers[Content_Range] = "bytes #{offset}-#{offset+count-1}/#{clen}" + [ status, offset, count ] + end + # nil if no status + end +end |