Class WEBrick::HTTPServlet::DefaultFileHandler
In: lib/webrick/httpservlet/filehandler.rb
Parent: AbstractServlet

Methods

Public Class methods

[Source]

    # File lib/webrick/httpservlet/filehandler.rb, line 22
22:       def initialize(server, local_path)
23:         super
24:         @local_path = local_path
25:       end

Public Instance methods

[Source]

    # File lib/webrick/httpservlet/filehandler.rb, line 27
27:       def do_GET(req, res)
28:         st = File::stat(@local_path)
29:         mtime = st.mtime
30:         res['etag'] = sprintf("%x-%x-%x", st.ino, st.size, st.mtime.to_i)
31: 
32:         if not_modified?(req, res, mtime, res['etag'])
33:           res.body = ''
34:           raise HTTPStatus::NotModified
35:         elsif req['range'] 
36:           make_partial_content(req, res, @local_path, st.size)
37:           raise HTTPStatus::PartialContent
38:         else
39:           mtype = HTTPUtils::mime_type(@local_path, @config[:MimeTypes])
40:           res['content-type'] = mtype
41:           res['content-length'] = st.size
42:           res['last-modified'] = mtime.httpdate
43:           res.body = open(@local_path, "rb")
44:         end
45:       end

[Source]

     # File lib/webrick/httpservlet/filehandler.rb, line 72
 72:       def make_partial_content(req, res, filename, filesize)
 73:         mtype = HTTPUtils::mime_type(filename, @config[:MimeTypes])
 74:         unless ranges = HTTPUtils::parse_range_header(req['range'])
 75:           raise HTTPStatus::BadRequest,
 76:             "Unrecognized range-spec: \"#{req['range']}\""
 77:         end
 78:         open(filename, "rb"){|io|
 79:           if ranges.size > 1
 80:             time = Time.now
 81:             boundary = "#{time.sec}_#{time.usec}_#{Process::pid}"
 82:             body = ''
 83:             ranges.each{|range|
 84:               first, last = prepare_range(range, filesize)
 85:               next if first < 0
 86:               io.pos = first
 87:               content = io.read(last-first+1)
 88:               body << "--" << boundary << CRLF
 89:               body << "Content-Type: #{mtype}" << CRLF
 90:               body << "Content-Range: #{first}-#{last}/#{filesize}" << CRLF
 91:               body << CRLF
 92:               body << content
 93:               body << CRLF
 94:             }
 95:             raise HTTPStatus::RequestRangeNotSatisfiable if body.empty?
 96:             body << "--" << boundary << "--" << CRLF
 97:             res["content-type"] = "multipart/byteranges; boundary=#{boundary}"
 98:             res.body = body
 99:           elsif range = ranges[0]
100:             first, last = prepare_range(range, filesize)
101:             raise HTTPStatus::RequestRangeNotSatisfiable if first < 0
102:             if last == filesize - 1
103:               content = io.dup
104:               content.pos = first
105:             else
106:               io.pos = first
107:               content = io.read(last-first+1)
108:             end
109:             res['content-type'] = mtype
110:             res['content-range'] = "#{first}-#{last}/#{filesize}"
111:             res['content-length'] = last - first + 1
112:             res.body = content
113:           else
114:             raise HTTPStatus::BadRequest
115:           end
116:         }
117:       end

[Source]

    # File lib/webrick/httpservlet/filehandler.rb, line 47
47:       def not_modified?(req, res, mtime, etag)
48:         if ir = req['if-range']
49:           begin
50:             if Time.httpdate(ir) >= mtime
51:               return true
52:             end
53:           rescue
54:             if HTTPUtils::split_header_value(ir).member?(res['etag'])
55:               return true
56:             end
57:           end
58:         end
59: 
60:         if (ims = req['if-modified-since']) && Time.parse(ims) >= mtime
61:           return true
62:         end
63: 
64:         if (inm = req['if-none-match']) &&
65:            HTTPUtils::split_header_value(inm).member?(res['etag'])
66:           return true
67:         end
68: 
69:         return false
70:       end

[Source]

     # File lib/webrick/httpservlet/filehandler.rb, line 119
119:       def prepare_range(range, filesize)
120:         first = range.first < 0 ? filesize + range.first : range.first
121:         return -1, -1 if first < 0 || first >= filesize
122:         last = range.last < 0 ? filesize + range.last : range.last
123:         last = filesize - 1 if last >= filesize
124:         return first, last
125:       end

[Validate]