Class: Gitlab::Middleware::Multipart::Handler

Inherits:
Object
  • Object
show all
Defined in:
lib/gitlab/middleware/multipart.rb

Instance Method Summary collapse

Constructor Details

#initialize(env, message) ⇒ Handler

Returns a new instance of Handler.



37
38
39
40
41
# File 'lib/gitlab/middleware/multipart.rb', line 37

def initialize(env, message)
  @request = Rack::Request.new(env)
  @rewritten_fields = message['rewritten_fields']
  @open_files = []
end

Instance Method Details

#decorate_params_value(hash_path, value_hash) ⇒ Object

This function calls itself recursively



70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
# File 'lib/gitlab/middleware/multipart.rb', line 70

def decorate_params_value(hash_path, value_hash)
  unless hash_path.is_a?(Hash) && hash_path.count == 1
    raise "invalid path: #{hash_path.inspect}"
  end

  path_key, path_value = hash_path.first

  unless value_hash.is_a?(Hash) && value_hash[path_key]
    raise "invalid value hash: #{value_hash.inspect}"
  end

  case path_value
  when nil
    value_hash[path_key] = open_file(extract_upload_params_from(value_hash[path_key]))
    @open_files << value_hash[path_key]
    value_hash
  when Hash
    decorate_params_value(path_value, value_hash[path_key])
    value_hash
  else
    raise "unexpected path value: #{path_value.inspect}"
  end
end

#open_file(params) ⇒ Object



94
95
96
# File 'lib/gitlab/middleware/multipart.rb', line 94

def open_file(params)
  ::UploadedFile.from_params(params, allowed_paths)
end

#update_param(key, value) ⇒ Object

update_params ensures that both rails controllers and rack middleware can find workhorse accelerate files in the request



100
101
102
103
104
105
106
107
108
109
110
# File 'lib/gitlab/middleware/multipart.rb', line 100

def update_param(key, value)
  # we make sure we have key in POST otherwise update_params will add it in GET
  @request.POST[key] ||= value

  # this will force Rack::Request to properly update env keys
  @request.update_param(key, value)

  # ActionDispatch::Request is based on Rack::Request but it caches params
  # inside other env keys, here we ensure everything is updated correctly
  ActionDispatch::Request.new(@request.env).update_param(key, value)
end

#with_open_filesObject



43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
# File 'lib/gitlab/middleware/multipart.rb', line 43

def with_open_files
  @rewritten_fields.keys.each do |field|
    raise "invalid field: #{field.inspect}" unless valid_field_name?(field)

    parsed_field = Rack::Utils.parse_nested_query(field)
    raise "unexpected field: #{field.inspect}" unless parsed_field.count == 1

    key, value = parsed_field.first
    if value.nil? # we have a top level param, eg. field = 'foo' and not 'foo[bar]'
      raise "invalid field: #{field.inspect}" if field != key

      value = open_file(extract_upload_params_from(@request.params, with_prefix: key))
      @open_files << value
    else
      value = decorate_params_value(value, @request.params[key])
    end

    update_param(key, value)
  end

  yield
ensure
  @open_files.compact
             .each(&:close)
end