From 94e343e3e77f1a4724f4cb70cbd42d88c8e3558b Mon Sep 17 00:00:00 2001
From: Stan Hu <stanhu@gmail.com>
Date: Wed, 15 Jul 2020 07:18:55 +0000
Subject: [PATCH] Update to Grape v1.4.0

Grape v1.4.0 fixes a memory leak that was present in v1.3.3
(https://github.com/ruby-grape/grape/pull/2084).

Full list of changes:

* https://github.com/ruby-grape/grape/blob/master/CHANGELOG.md
* https://github.com/ruby-grape/grape/compare/v1.3.3..v1.4.0
---
 Gemfile                                       |  4 ++-
 Gemfile.lock                                  |  4 +--
 .../unreleased/sh-update-grape-1-4-0.yml      |  5 +++
 config/initializers/grape_patch.rb            | 31 +++++++++++++++++++
 lib/api/helpers.rb                            |  2 +-
 5 files changed, 42 insertions(+), 4 deletions(-)
 create mode 100644 changelogs/unreleased/sh-update-grape-1-4-0.yml
 create mode 100644 config/initializers/grape_patch.rb

diff --git a/Gemfile b/Gemfile
index c1f93c789325..4ecaacea7e45 100644
--- a/Gemfile
+++ b/Gemfile
@@ -81,7 +81,9 @@ gem 'gitlab_omniauth-ldap', '~> 2.1.1', require: 'omniauth-ldap'
 gem 'net-ldap'
 
 # API
-gem 'grape', '~> 1.3.3'
+# Locked at Grape v1.4.0 until https://github.com/ruby-grape/grape/pull/2088 is merged
+# Remove config/initializers/grape_patch.rb
+gem 'grape', '= 1.4.0'
 gem 'grape-entity', '~> 0.7.1'
 gem 'rack-cors', '~> 1.0.6', require: 'rack/cors'
 
diff --git a/Gemfile.lock b/Gemfile.lock
index 03c213333dfd..edcbbeb85953 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -453,7 +453,7 @@ GEM
       signet (~> 0.14)
     gpgme (2.0.20)
       mini_portile2 (~> 2.3)
-    grape (1.3.3)
+    grape (1.4.0)
       activesupport
       builder
       dry-types (>= 1.1)
@@ -1268,7 +1268,7 @@ DEPENDENCIES
   google-api-client (~> 0.33)
   google-protobuf (~> 3.8.0)
   gpgme (~> 2.0.19)
-  grape (~> 1.3.3)
+  grape (= 1.4.0)
   grape-entity (~> 0.7.1)
   grape-path-helpers (~> 1.3)
   grape_logging (~> 1.7)
diff --git a/changelogs/unreleased/sh-update-grape-1-4-0.yml b/changelogs/unreleased/sh-update-grape-1-4-0.yml
new file mode 100644
index 000000000000..d6273afea295
--- /dev/null
+++ b/changelogs/unreleased/sh-update-grape-1-4-0.yml
@@ -0,0 +1,5 @@
+---
+title: Update to Grape v1.4.0
+merge_request: 36628
+author:
+type: fixed
diff --git a/config/initializers/grape_patch.rb b/config/initializers/grape_patch.rb
new file mode 100644
index 000000000000..a9ac0840541d
--- /dev/null
+++ b/config/initializers/grape_patch.rb
@@ -0,0 +1,31 @@
+# frozen_string_literal: true
+# Monkey patch for Grape v1.4.0: https://github.com/ruby-grape/grape/pull/2088
+
+require 'grape'
+
+# rubocop:disable Gitlab/ModuleWithInstanceVariables
+module Grape
+  module DSL
+    module InsideRoute
+      def stream(value = nil)
+        return if value.nil? && @stream.nil?
+
+        header 'Content-Length', nil
+        header 'Transfer-Encoding', nil
+        header 'Cache-Control', 'no-cache' # Skips ETag generation (reading the response up front)
+
+        if value.is_a?(String)
+          file_body = Grape::ServeStream::FileBody.new(value)
+          @stream = Grape::ServeStream::StreamResponse.new(file_body)
+        elsif value.respond_to?(:each)
+          @stream = Grape::ServeStream::StreamResponse.new(value)
+        elsif !value.is_a?(NilClass)
+          raise ArgumentError, 'Stream object must respond to :each.'
+        else
+          @stream
+        end
+      end
+    end
+  end
+end
+# rubocop:enable Gitlab/ModuleWithInstanceVariables
diff --git a/lib/api/helpers.rb b/lib/api/helpers.rb
index 1aa21e24b71d..7b8bffb56176 100644
--- a/lib/api/helpers.rb
+++ b/lib/api/helpers.rb
@@ -494,7 +494,7 @@ def present_disk_file!(path, filename, content_type = 'application/octet-stream'
         header['X-Sendfile'] = path
         body
       else
-        file path
+        sendfile path
       end
     end
 
-- 
GitLab