BigW Consortium Gitlab

router.rb 2.5 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
module Gitlab
  module Lfs
    class Router
      def initialize(project, user, request)
        @project = project
        @user = user
        @env = request.env
        @request = request
      end

      def try_call
        return unless @request && @request.path.present?

        case @request.request_method
        when 'GET'
          get_response
        when 'POST'
          post_response
        when 'PUT'
          put_response
        else
          nil
        end
      end

      private

      def get_response
        path_match = @request.path.match(/\/(info\/lfs|gitlab-lfs)\/objects\/([0-9a-f]{64})$/)
        return nil unless path_match

        oid = path_match[2]
        return nil unless oid

        case path_match[1]
        when "info/lfs"
37
          lfs.render_unsupported_deprecated_api
38 39 40 41 42 43 44 45 46 47 48 49 50
        when "gitlab-lfs"
          lfs.render_download_object_response(oid)
        else
          nil
        end
      end

      def post_response
        post_path = @request.path.match(/\/info\/lfs\/objects(\/batch)?$/)
        return nil unless post_path

        # Check for Batch API
        if post_path[0].ends_with?("/info/lfs/objects/batch")
51
          lfs.render_batch_operation_response
52 53
        elsif post_path[0].ends_with?("/info/lfs/objects")
          lfs.render_unsupported_deprecated_api
54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97
        else
          nil
        end
      end

      def put_response
        object_match = @request.path.match(/\/gitlab-lfs\/objects\/([0-9a-f]{64})\/([0-9]+)(|\/authorize){1}$/)
        return nil if object_match.nil?

        oid = object_match[1]
        size = object_match[2].try(:to_i)
        return nil if oid.nil? || size.nil?

        # GitLab-workhorse requests
        # 1. Try to authorize the request
        # 2. send a request with a header containing the name of the temporary file
        if object_match[3] && object_match[3] == '/authorize'
          lfs.render_storage_upload_authorize_response(oid, size)
        else
          tmp_file_name = sanitize_tmp_filename(@request.env['HTTP_X_GITLAB_LFS_TMP'])
          return nil unless tmp_file_name

          lfs.render_storage_upload_store_response(oid, size, tmp_file_name)
        end
      end

      def lfs
        return unless @project

        Gitlab::Lfs::Response.new(@project, @user, @request)
      end

      def sanitize_tmp_filename(name)
        if name.present?
          name.gsub!(/^.*(\\|\/)/, '')
          name = name.match(/[0-9a-f]{73}/)
          name[0] if name
        else
          nil
        end
      end
    end
  end
end