Object
# File lib/rack/multipart/parser.rb, line 12 12: def parse 13: return nil unless setup_parse 14: 15: fast_forward_to_first_boundary 16: 17: loop do 18: head, filename, content_type, name, body = 19: get_current_head_and_filename_and_content_type_and_name_and_body 20: 21: # Save the rest. 22: if i = @buf.index(rx) 23: body << @buf.slice!(0, i) 24: @buf.slice!(0, @boundary_size+2) 25: 26: @content_length = 1 if $1 == "--" 27: end 28: 29: filename, data = get_data(filename, body, content_type, name, head) 30: 31: Utils.normalize_params(@params, name, data) unless data.nil? 32: 33: # break if we're at the end of a buffer, but not if it is the end of a field 34: break if (@buf.empty? && $1 != EOL) || @content_length == 1 35: end 36: 37: @io.rewind 38: 39: @params.to_params_hash 40: end
# File lib/rack/multipart/parser.rb, line 69 69: def fast_forward_to_first_boundary 70: loop do 71: read_buffer = @io.gets 72: break if read_buffer == full_boundary 73: raise EOFError, "bad content body" if read_buffer.nil? 74: end 75: end
# File lib/rack/multipart/parser.rb, line 61 61: def full_boundary 62: @boundary + EOL 63: end
# File lib/rack/multipart/parser.rb, line 77 77: def get_current_head_and_filename_and_content_type_and_name_and_body 78: head = nil 79: body = '' 80: filename = content_type = name = nil 81: content = nil 82: 83: until head && @buf =~ rx 84: if !head && i = @buf.index(EOL+EOL) 85: head = @buf.slice!(0, i+2) # First \r\n 86: 87: @buf.slice!(0, 2) # Second \r\n 88: 89: content_type = head[MULTIPART_CONTENT_TYPE, 1] 90: name = head[MULTIPART_CONTENT_DISPOSITION, 1] || head[MULTIPART_CONTENT_ID, 1] 91: 92: filename = get_filename(head) 93: 94: if filename 95: body = Tempfile.new("RackMultipart") 96: body.binmode if body.respond_to?(:binmode) 97: end 98: 99: next 100: end 101: 102: # Save the read body part. 103: if head && (@boundary_size+4 < @buf.size) 104: body << @buf.slice!(0, @buf.size - (@boundary_size+4)) 105: end 106: 107: content = @io.read(BUFSIZE < @content_length ? BUFSIZE : @content_length) 108: raise EOFError, "bad content body" if content.nil? || content.empty? 109: 110: @buf << content 111: @content_length -= content.size 112: end 113: 114: [head, filename, content_type, name, body] 115: end
# File lib/rack/multipart/parser.rb, line 137 137: def get_data(filename, body, content_type, name, head) 138: data = nil 139: if filename == "" 140: # filename is blank which means no file has been selected 141: return data 142: elsif filename 143: body.rewind 144: 145: # Take the basename of the upload's original filename. 146: # This handles the full Windows paths given by Internet Explorer 147: # (and perhaps other broken user agents) without affecting 148: # those which give the lone filename. 149: filename = filename.split(/[\/\\]/).last 150: 151: data = {:filename => filename, :type => content_type, 152: :name => name, :tempfile => body, :head => head} 153: elsif !filename && content_type && body.is_a?(IO) 154: body.rewind 155: 156: # Generic multipart cases, not coming from a form 157: data = {:type => content_type, 158: :name => name, :tempfile => body, :head => head} 159: else 160: data = body 161: end 162: 163: [filename, data] 164: end
# File lib/rack/multipart/parser.rb, line 117 117: def get_filename(head) 118: filename = nil 119: if head =~ RFC2183 120: filename = Hash[head.scan(DISPPARM)]['filename'] 121: filename = $1 if filename and filename =~ /^"(.*)"$/ 122: elsif head =~ BROKEN_QUOTED 123: filename = $1 124: elsif head =~ BROKEN_UNQUOTED 125: filename = $1 126: end 127: 128: if filename && filename.scan(/%.?.?/).all? { |s| s =~ /%[0-9a-fA-F]{2}/ } 129: filename = Utils.unescape(filename) 130: end 131: if filename && filename !~ /\\[^\\"]/ 132: filename = filename.gsub(/\\(.)/, '\1') 133: end 134: filename 135: end
# File lib/rack/multipart/parser.rb, line 65 65: def rx 66: @rx ||= /(?:#{EOL})?#{Regexp.quote(@boundary)}(#{EOL}|--)/ 67: end
# File lib/rack/multipart/parser.rb, line 43 43: def setup_parse 44: return false unless @env['CONTENT_TYPE'] =~ MULTIPART 45: 46: @boundary = "--#{$1}" 47: 48: @buf = "" 49: @params = Utils::KeySpaceConstrainedParams.new 50: 51: @content_length = @env['CONTENT_LENGTH'].to_i 52: @io = @env['rack.input'] 53: @io.rewind 54: 55: @boundary_size = Utils.bytesize(@boundary) + EOL.size 56: 57: @content_length -= @boundary_size 58: true 59: end
Disabled; run with --debug to generate this.
Generated with the Darkfish Rdoc Generator 1.1.6.