# File webrick/httpservlet/filehandler.rb, line 27
def do_GET(req, res)
st = File::stat(@local_path)
mtime = st.mtime
res['etag'] = sprintf("%x-%x-%x", st.ino, st.size, st.mtime.to_i)
if not_modified?(req, res, mtime, res['etag'])
res.body = ''
raise HTTPStatus::NotModified
elsif req['range']
make_partial_content(req, res, @local_path, st.size)
raise HTTPStatus::PartialContent
else
mtype = HTTPUtils::mime_type(@local_path, @config[:MimeTypes])
res['content-type'] = mtype
res['content-length'] = st.size
res['last-modified'] = mtime.httpdate
res.body = open(@local_path, "rb")
end
end
# File webrick/httpservlet/filehandler.rb, line 72
def make_partial_content(req, res, filename, filesize)
mtype = HTTPUtils::mime_type(filename, @config[:MimeTypes])
unless ranges = HTTPUtils::parse_range_header(req['range'])
raise HTTPStatus::BadRequest,
"Unrecognized range-spec: \"#{req['range']}\""
end
open(filename, "rb"){|io|
if ranges.size > 1
time = Time.now
boundary = "#{time.sec}_#{time.usec}_#{Process::pid}"
body = ''
ranges.each{|range|
first, last = prepare_range(range, filesize)
next if first < 0
io.pos = first
content = io.read(last-first+1)
body << "--" << boundary << CRLF
body << "Content-Type: #{mtype}" << CRLF
body << "Content-Range: #{first}-#{last}/#{filesize}" << CRLF
body << CRLF
body << content
body << CRLF
}
raise HTTPStatus::RequestRangeNotSatisfiable if body.empty?
body << "--" << boundary << "--" << CRLF
res["content-type"] = "multipart/byteranges; boundary=#{boundary}"
res.body = body
elsif range = ranges[0]
first, last = prepare_range(range, filesize)
raise HTTPStatus::RequestRangeNotSatisfiable if first < 0
if last == filesize - 1
content = io.dup
content.pos = first
else
io.pos = first
content = io.read(last-first+1)
end
res['content-type'] = mtype
res['content-range'] = "#{first}-#{last}/#{filesize}"
res['content-length'] = last - first + 1
res.body = content
else
raise HTTPStatus::BadRequest
end
}
end
# File webrick/httpservlet/filehandler.rb, line 47
def not_modified?(req, res, mtime, etag)
if ir = req['if-range']
begin
if Time.httpdate(ir) >= mtime
return true
end
rescue
if HTTPUtils::split_header_value(ir).member?(res['etag'])
return true
end
end
end
if (ims = req['if-modified-since']) && Time.parse(ims) >= mtime
return true
end
if (inm = req['if-none-match']) &&
HTTPUtils::split_header_value(inm).member?(res['etag'])
return true
end
return false
end
# File webrick/httpservlet/filehandler.rb, line 119
def prepare_range(range, filesize)
first = range.first < 0 ? filesize + range.first : range.first
return -1, -1 if first < 0 || first >= filesize
last = range.last < 0 ? filesize + range.last : range.last
last = filesize - 1 if last >= filesize
return first, last
end
Commenting is here to help enhance the documentation. For example, code samples, or clarification of the documentation.
If you have questions about Ruby or the documentation, please post to one of the Ruby mailing lists. You will get better, faster, help that way.
If you wish to post a correction of the docs, please do so, but also file bug report so that it can be corrected for the next release. Thank you.
If you want to help improve the Ruby documentation, please visit Documenting-ruby.org.