Read about our upcoming Code of Conduct on this issue

web_upload_strategy.rb 1.96 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
module Gitlab
  module ImportExport
    module AfterExportStrategies
      class WebUploadStrategy < BaseAfterExportStrategy
        PUT_METHOD = 'PUT'.freeze
        POST_METHOD = 'POST'.freeze
        INVALID_HTTP_METHOD = 'invalid. Only PUT and POST methods allowed.'.freeze

        validates :url, url: true

        validate do
          unless [PUT_METHOD, POST_METHOD].include?(http_method.upcase)
            errors.add(:http_method, INVALID_HTTP_METHOD)
          end
        end

        def initialize(url:, http_method: PUT_METHOD)
          super
        end

        protected

        def strategy_execute
          handle_response_error(send_file)

          project.remove_exported_project_file
        end

        def handle_response_error(response)
          unless response.success?
            error_code = response.dig('Error', 'Code') || response.code
            error_message = response.dig('Error', 'Message') || response.message

            raise StrategyError.new("Error uploading the project. Code #{error_code}: #{error_message}")
          end
        end

        private

        def send_file
41
          Gitlab::HTTP.public_send(http_method.downcase, url, send_file_options) # rubocop:disable GitlabSecurity/PublicSend
42
        ensure
43
44
45
46
47
48
49
50
51
          export_file.close if export_file && !object_storage?
        end

        def export_file
          if object_storage?
            project.import_export_upload.export_file.file.open
          else
            File.open(project.export_project_path)
          end
52
53
        end

54
        def send_file_options
55
56
57
58
59
60
61
          {
            body_stream: export_file,
            headers: headers
          }
        end

        def headers
62
63
64
65
66
67
68
69
70
          { 'Content-Length' => export_size.to_s }
        end

        def export_size
          if object_storage?
            project.import_export_upload.export_file.file.size
          else
            File.size(project.export_project_path)
          end
71
72
73
74
75
        end
      end
    end
  end
end