Methods
Class Public methods
new(server, local_path)
Link
Instance Public methods
do_GET(req, res)
Link
# File ../ruby/lib/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
make_partial_content(req, res, filename, filesize)
Link
# File ../ruby/lib/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: bytes #{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'] = "bytes #{first}-#{last}/#{filesize}" res['content-length'] = last - first + 1 res.body = content else raise HTTPStatus::BadRequest end } end
not_modified?(req, res, mtime, etag)
Link
# File ../ruby/lib/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
prepare_range(range, filesize)
Link
# File ../ruby/lib/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