In: |
webrick/httpservlet/filehandler.rb
|
Parent: | AbstractServlet |
# File webrick/httpservlet/filehandler.rb, line 22 def initialize(server, local_path) super @local_path = local_path end
# 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 BadRequest, "Unrecognized range-spec: \"#{range}\"" end open(filename, "rb"){|io| if ranges.size > 1 boundary = "#{time.sec}_#{time.usec}_#{Process::pid}" body = '' ranges.each{|r| 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 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_valie(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 115 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