gitlab-grack 2.0.0.rc2 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/CHANGELOG +8 -0
- data/Gemfile +1 -0
- data/Gemfile.lock +9 -1
- data/Rakefile +1 -1
- data/bin/console +6 -0
- data/bin/testserver +14 -0
- data/lib/grack/git.rb +69 -0
- data/lib/grack/server.rb +67 -105
- data/lib/grack/version.rb +1 -1
- data/tests/main_test.rb +22 -13
- metadata +11 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fdf3609511e6c0a489c572a4add4f89af65bae4b
|
4
|
+
data.tar.gz: 8ad35782833f609c0dba191250746d5a2dfd20bc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4f506cdcc801556af8b5ab796d8ebf46585ef4025805307bc2cef094a653c5a3a2b3efa941bf61f48593def2696b99ba31c4a026e0195309d63e1ede3d70f0e9
|
7
|
+
data.tar.gz: 0c5bb7dd97d1d5f07e57d3642a0f27b3bdc3d65b00586780d0e23a435e16f2ff5fd2f2185b563070ad77cd0ff15e695471466498dc7868af04ba4416e4ebfbd1
|
data/.gitignore
CHANGED
data/CHANGELOG
CHANGED
@@ -1,2 +1,10 @@
|
|
1
|
+
2.0.0
|
2
|
+
- Use safer shell commands and avoid Dir.chdir
|
3
|
+
- Restrict the environment for shell commands
|
4
|
+
- Make Grack::Server thread-safe (zimbatm)
|
5
|
+
- Make sure child processes get reaped after popen
|
6
|
+
- Verify requested path is actually a Git directory (Ryan Canty)
|
7
|
+
|
8
|
+
|
1
9
|
1.1.0
|
2
10
|
- Modifies service_rpc to use chunked transfer (https://github.com/gitlabhq/grack/pull/1)
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,19 +1,26 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
gitlab-grack (2.0.0.
|
4
|
+
gitlab-grack (2.0.0.rc2)
|
5
5
|
rack (~> 1.5.1)
|
6
6
|
|
7
7
|
GEM
|
8
8
|
remote: https://rubygems.org/
|
9
9
|
specs:
|
10
|
+
coderay (1.1.0)
|
10
11
|
metaclass (0.0.1)
|
12
|
+
method_source (0.8.2)
|
11
13
|
mocha (0.14.0)
|
12
14
|
metaclass (~> 0.0.1)
|
15
|
+
pry (0.10.1)
|
16
|
+
coderay (~> 1.1.0)
|
17
|
+
method_source (~> 0.8.1)
|
18
|
+
slop (~> 3.4)
|
13
19
|
rack (1.5.2)
|
14
20
|
rack-test (0.6.2)
|
15
21
|
rack (>= 1.0)
|
16
22
|
rake (10.1.0)
|
23
|
+
slop (3.6.0)
|
17
24
|
|
18
25
|
PLATFORMS
|
19
26
|
ruby
|
@@ -21,5 +28,6 @@ PLATFORMS
|
|
21
28
|
DEPENDENCIES
|
22
29
|
gitlab-grack!
|
23
30
|
mocha (~> 0.11)
|
31
|
+
pry
|
24
32
|
rack-test
|
25
33
|
rake
|
data/Rakefile
CHANGED
data/bin/console
ADDED
data/bin/testserver
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#! /usr/bin/env ruby
|
2
|
+
libdir = File.absolute_path( File.join( File.dirname(__FILE__), '../lib' ) )
|
3
|
+
$LOAD_PATH.unshift(libdir) unless $LOAD_PATH.include?(libdir)
|
4
|
+
|
5
|
+
require 'grack'
|
6
|
+
require 'rack'
|
7
|
+
root = File.absolute_path( File.join( File.dirname(__FILE__), '../examples' ) )
|
8
|
+
app = Grack::Server.new({
|
9
|
+
project_root: root,
|
10
|
+
upload_pack: true,
|
11
|
+
receive_pack:true
|
12
|
+
})
|
13
|
+
|
14
|
+
Rack::Server.start app: app, Port: 3001
|
data/lib/grack/git.rb
ADDED
@@ -0,0 +1,69 @@
|
|
1
|
+
module Grack
|
2
|
+
class Git
|
3
|
+
attr_reader :repo
|
4
|
+
|
5
|
+
def initialize(git_path, repo_path)
|
6
|
+
@git_path = git_path
|
7
|
+
@repo = repo_path
|
8
|
+
end
|
9
|
+
|
10
|
+
def update_server_info
|
11
|
+
execute(%W(update-server-info))
|
12
|
+
end
|
13
|
+
|
14
|
+
def command(cmd)
|
15
|
+
[@git_path || 'git'] + cmd
|
16
|
+
end
|
17
|
+
|
18
|
+
def capture(cmd)
|
19
|
+
IO.popen(popen_env, cmd, popen_options).read
|
20
|
+
end
|
21
|
+
|
22
|
+
def execute(cmd)
|
23
|
+
cmd = command(cmd)
|
24
|
+
if block_given?
|
25
|
+
IO.popen(popen_env, cmd, File::RDWR, popen_options) do |pipe|
|
26
|
+
yield(pipe)
|
27
|
+
end
|
28
|
+
else
|
29
|
+
capture(cmd).chomp
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def popen_options
|
34
|
+
{ chdir: repo, unsetenv_others: true }
|
35
|
+
end
|
36
|
+
|
37
|
+
def popen_env
|
38
|
+
{ 'PATH' => ENV['PATH'], 'GL_ID' => ENV['GL_ID'] }
|
39
|
+
end
|
40
|
+
|
41
|
+
def config_setting(service_name)
|
42
|
+
service_name = service_name.gsub('-', '')
|
43
|
+
setting = config("http.#{service_name}")
|
44
|
+
|
45
|
+
if service_name == 'uploadpack'
|
46
|
+
setting != 'false'
|
47
|
+
else
|
48
|
+
setting == 'true'
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def config(config_name)
|
53
|
+
execute(%W(config #{config_name}))
|
54
|
+
end
|
55
|
+
|
56
|
+
def valid_repo?
|
57
|
+
return false unless File.exists?(repo) && File.realpath(repo) == repo
|
58
|
+
|
59
|
+
match = execute(%W(rev-parse --git-dir)).match(/\.$|\.git$/)
|
60
|
+
|
61
|
+
if match.to_s == '.git'
|
62
|
+
# Since the parent could be a git repo, we want to make sure the actual repo contains a git dir.
|
63
|
+
return false unless Dir.entries(repo).include?('.git')
|
64
|
+
end
|
65
|
+
|
66
|
+
match
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
data/lib/grack/server.rb
CHANGED
@@ -4,8 +4,11 @@ require 'rack/response'
|
|
4
4
|
require 'rack/utils'
|
5
5
|
require 'time'
|
6
6
|
|
7
|
+
require 'grack/git'
|
8
|
+
|
7
9
|
module Grack
|
8
10
|
class Server
|
11
|
+
attr_reader :git
|
9
12
|
|
10
13
|
SERVICES = [
|
11
14
|
["POST", 'service_rpc', "(.*?)/git-upload-pack$", 'upload-pack'],
|
@@ -45,12 +48,12 @@ module Grack
|
|
45
48
|
cmd, path, @reqfile, @rpc = match_routing
|
46
49
|
|
47
50
|
return render_method_not_allowed if cmd == 'not_allowed'
|
48
|
-
return render_not_found
|
51
|
+
return render_not_found unless cmd
|
49
52
|
|
50
|
-
@
|
51
|
-
return render_not_found
|
53
|
+
@git = get_git(path)
|
54
|
+
return render_not_found unless git.valid_repo?
|
52
55
|
|
53
|
-
self.method(cmd).call
|
56
|
+
self.method(cmd).call
|
54
57
|
end
|
55
58
|
|
56
59
|
# ---------------------------------
|
@@ -64,7 +67,8 @@ module Grack
|
|
64
67
|
CRLF = "\r\n"
|
65
68
|
|
66
69
|
def service_rpc
|
67
|
-
return render_no_access
|
70
|
+
return render_no_access unless has_access?(@rpc, true)
|
71
|
+
|
68
72
|
input = read_body
|
69
73
|
|
70
74
|
@res = Rack::Response.new
|
@@ -74,14 +78,14 @@ module Grack
|
|
74
78
|
@res["Cache-Control"] = "no-cache"
|
75
79
|
|
76
80
|
@res.finish do
|
77
|
-
|
78
|
-
IO.popen(popen_env, command, File::RDWR, popen_options) do |pipe|
|
81
|
+
git.execute([@rpc, '--stateless-rpc', git.repo]) do |pipe|
|
79
82
|
pipe.write(input)
|
80
83
|
pipe.close_write
|
81
|
-
|
82
|
-
|
83
|
-
@res.write encode_chunk(block)
|
84
|
+
|
85
|
+
while block = pipe.read(8192) # 8KB at a time
|
86
|
+
@res.write encode_chunk(block) # stream it to the client
|
84
87
|
end
|
88
|
+
|
85
89
|
@res.write terminating_chunk
|
86
90
|
end
|
87
91
|
end
|
@@ -89,35 +93,33 @@ module Grack
|
|
89
93
|
|
90
94
|
def encode_chunk(chunk)
|
91
95
|
size_in_hex = chunk.size.to_s(16)
|
92
|
-
[
|
96
|
+
[size_in_hex, CRLF, chunk, CRLF].join
|
93
97
|
end
|
94
98
|
|
95
99
|
def terminating_chunk
|
96
|
-
[
|
100
|
+
[0, CRLF, CRLF].join
|
97
101
|
end
|
98
102
|
|
99
103
|
def get_info_refs
|
100
104
|
service_name = get_service_type
|
105
|
+
return dumb_info_refs unless has_access?(service_name)
|
101
106
|
|
102
|
-
|
103
|
-
cmd = git_command(%W(#{service_name} --stateless-rpc --advertise-refs #{@dir}))
|
104
|
-
refs = capture(cmd)
|
107
|
+
refs = git.execute([service_name, '--stateless-rpc', '--advertise-refs', git.repo])
|
105
108
|
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
end
|
109
|
+
@res = Rack::Response.new
|
110
|
+
@res.status = 200
|
111
|
+
@res["Content-Type"] = "application/x-git-%s-advertisement" % service_name
|
112
|
+
hdr_nocache
|
113
|
+
|
114
|
+
@res.write(pkt_write("# service=git-#{service_name}\n"))
|
115
|
+
@res.write(pkt_flush)
|
116
|
+
@res.write(refs)
|
117
|
+
|
118
|
+
@res.finish
|
117
119
|
end
|
118
120
|
|
119
121
|
def dumb_info_refs
|
120
|
-
update_server_info
|
122
|
+
git.update_server_info
|
121
123
|
send_file(@reqfile, "text/plain; charset=utf-8") do
|
122
124
|
hdr_nocache
|
123
125
|
end
|
@@ -158,38 +160,33 @@ module Grack
|
|
158
160
|
# logic helping functions
|
159
161
|
# ------------------------
|
160
162
|
|
161
|
-
F = ::File
|
162
|
-
|
163
163
|
# some of this borrowed from the Rack::File implementation
|
164
164
|
def send_file(reqfile, content_type)
|
165
|
-
reqfile = File.join(
|
166
|
-
return render_not_found
|
165
|
+
reqfile = File.join(git.repo, reqfile)
|
166
|
+
return render_not_found unless File.exists?(reqfile)
|
167
167
|
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
# reqfile does not look trustworthy; abort
|
172
|
-
return render_not_found
|
173
|
-
end
|
168
|
+
return render_not_found unless reqfile == File.realpath(reqfile)
|
169
|
+
|
170
|
+
# reqfile looks legit: no path traversal, no leading '|'
|
174
171
|
|
175
172
|
@res = Rack::Response.new
|
176
173
|
@res.status = 200
|
177
174
|
@res["Content-Type"] = content_type
|
178
|
-
@res["Last-Modified"] =
|
175
|
+
@res["Last-Modified"] = File.mtime(reqfile).httpdate
|
179
176
|
|
180
177
|
yield
|
181
178
|
|
182
|
-
if size =
|
179
|
+
if size = File.size?(reqfile)
|
183
180
|
@res["Content-Length"] = size.to_s
|
184
181
|
@res.finish do
|
185
|
-
|
182
|
+
File.open(reqfile, "rb") do |file|
|
186
183
|
while part = file.read(8192)
|
187
184
|
@res.write part
|
188
185
|
end
|
189
186
|
end
|
190
187
|
end
|
191
188
|
else
|
192
|
-
body = [
|
189
|
+
body = [File.read(reqfile)]
|
193
190
|
size = Rack::Utils.bytesize(body.first)
|
194
191
|
@res["Content-Length"] = size
|
195
192
|
@res.write body
|
@@ -197,21 +194,15 @@ module Grack
|
|
197
194
|
end
|
198
195
|
end
|
199
196
|
|
200
|
-
def
|
197
|
+
def get_git(path)
|
201
198
|
root = @config[:project_root] || Dir.pwd
|
202
199
|
path = File.join(root, path)
|
203
|
-
|
204
|
-
false
|
205
|
-
elsif File.realpath(path) != path # looks like path traversal
|
206
|
-
false
|
207
|
-
else
|
208
|
-
path # TODO: check is a valid git directory
|
209
|
-
end
|
200
|
+
Grack::Git.new(@config[:git_path], path)
|
210
201
|
end
|
211
202
|
|
212
203
|
def get_service_type
|
213
204
|
service_type = @req.params['service']
|
214
|
-
return false
|
205
|
+
return false unless service_type
|
215
206
|
return false if service_type[0, 4] != 'git-'
|
216
207
|
service_type.gsub('git-', '')
|
217
208
|
end
|
@@ -219,81 +210,54 @@ module Grack
|
|
219
210
|
def match_routing
|
220
211
|
cmd = nil
|
221
212
|
path = nil
|
213
|
+
|
222
214
|
SERVICES.each do |method, handler, match, rpc|
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
215
|
+
next unless m = Regexp.new(match).match(@req.path_info)
|
216
|
+
|
217
|
+
return ['not_allowed'] unless method == @req.request_method
|
218
|
+
|
219
|
+
cmd = handler
|
220
|
+
path = m[1]
|
221
|
+
file = @req.path_info.sub(path + '/', '')
|
222
|
+
|
223
|
+
return [cmd, path, file, rpc]
|
230
224
|
end
|
231
|
-
|
225
|
+
|
226
|
+
nil
|
232
227
|
end
|
233
228
|
|
234
|
-
def has_access(rpc, check_content_type = false)
|
229
|
+
def has_access?(rpc, check_content_type = false)
|
235
230
|
if check_content_type
|
236
|
-
|
231
|
+
conten_type = "application/x-git-%s-request" % rpc
|
232
|
+
return false unless @req.content_type == conten_type
|
237
233
|
end
|
238
|
-
|
234
|
+
|
235
|
+
return false unless ['upload-pack', 'receive-pack'].include?(rpc)
|
236
|
+
|
239
237
|
if rpc == 'receive-pack'
|
240
|
-
return @config[:receive_pack] if @config.include?
|
238
|
+
return @config[:receive_pack] if @config.include?(:receive_pack)
|
241
239
|
end
|
242
|
-
if rpc == 'upload-pack'
|
243
|
-
return @config[:upload_pack] if @config.include? :upload_pack
|
244
|
-
end
|
245
|
-
return get_config_setting(rpc)
|
246
|
-
end
|
247
240
|
|
248
|
-
|
249
|
-
|
250
|
-
setting = get_git_config("http.#{service_name}")
|
251
|
-
if service_name == 'uploadpack'
|
252
|
-
return setting != 'false'
|
253
|
-
else
|
254
|
-
return setting == 'true'
|
241
|
+
if rpc == 'upload-pack'
|
242
|
+
return @config[:upload_pack] if @config.include?(:upload_pack)
|
255
243
|
end
|
256
|
-
end
|
257
244
|
|
258
|
-
|
259
|
-
cmd = git_command(%W(config #{config_name}))
|
260
|
-
capture(cmd).chomp
|
245
|
+
git.config_setting(rpc)
|
261
246
|
end
|
262
247
|
|
263
248
|
def read_body
|
264
249
|
if @env["HTTP_CONTENT_ENCODING"] =~ /gzip/
|
265
|
-
|
250
|
+
Zlib::GzipReader.new(@req.body).read
|
266
251
|
else
|
267
|
-
|
252
|
+
@req.body.read
|
268
253
|
end
|
269
254
|
end
|
270
255
|
|
271
|
-
def update_server_info
|
272
|
-
cmd = git_command(%W(update-server-info))
|
273
|
-
capture(cmd)
|
274
|
-
end
|
275
|
-
|
276
|
-
def git_command(command)
|
277
|
-
[@config[:git_path] || 'git'] + command
|
278
|
-
end
|
279
|
-
|
280
|
-
def capture(command)
|
281
|
-
IO.popen(popen_env, command, popen_options) { |p| p.read }
|
282
|
-
end
|
283
|
-
|
284
|
-
def popen_options
|
285
|
-
{chdir: @dir, unsetenv_others: true}
|
286
|
-
end
|
287
|
-
|
288
|
-
def popen_env
|
289
|
-
{'PATH' => ENV['PATH'], 'GL_ID' => ENV['GL_ID']}
|
290
|
-
end
|
291
|
-
|
292
256
|
# --------------------------------------
|
293
257
|
# HTTP error response handling functions
|
294
258
|
# --------------------------------------
|
295
259
|
|
296
|
-
PLAIN_TYPE = {"Content-Type" => "text/plain"}
|
260
|
+
PLAIN_TYPE = { "Content-Type" => "text/plain" }
|
297
261
|
|
298
262
|
def render_method_not_allowed
|
299
263
|
if @env['SERVER_PROTOCOL'] == "HTTP/1.1"
|
@@ -321,10 +285,9 @@ module Grack
|
|
321
285
|
end
|
322
286
|
|
323
287
|
def pkt_write(str)
|
324
|
-
(str.size + 4).to_s(
|
288
|
+
(str.size + 4).to_s(16).rjust(4, '0') + str
|
325
289
|
end
|
326
290
|
|
327
|
-
|
328
291
|
# ------------------------
|
329
292
|
# header writing functions
|
330
293
|
# ------------------------
|
@@ -341,6 +304,5 @@ module Grack
|
|
341
304
|
@res["Expires"] = (now + 31536000).to_s;
|
342
305
|
@res["Cache-Control"] = "public, max-age=31536000";
|
343
306
|
end
|
344
|
-
|
345
307
|
end
|
346
308
|
end
|
data/lib/grack/version.rb
CHANGED
data/tests/main_test.rb
CHANGED
@@ -5,6 +5,7 @@ require 'mocha'
|
|
5
5
|
require 'digest/sha1'
|
6
6
|
|
7
7
|
require_relative '../lib/grack/server.rb'
|
8
|
+
require_relative '../lib/grack/git.rb'
|
8
9
|
require 'pp'
|
9
10
|
|
10
11
|
class GitHttpTest < Test::Unit::TestCase
|
@@ -52,11 +53,13 @@ class GitHttpTest < Test::Unit::TestCase
|
|
52
53
|
end
|
53
54
|
|
54
55
|
def test_no_access_wrong_path_rcp
|
56
|
+
Grack::Git.any_instance.stubs(:valid_repo?).returns(false)
|
55
57
|
post "/example-wrong/git-upload-pack"
|
56
58
|
assert_equal 404, r.status
|
57
59
|
end
|
58
60
|
|
59
61
|
def test_upload_pack_rpc
|
62
|
+
Grack::Git.any_instance.stubs(:valid_repo?).returns(true)
|
60
63
|
IO.stubs(:popen).returns(MockProcess.new)
|
61
64
|
post "/example/git-upload-pack", {}, {"CONTENT_TYPE" => "application/x-git-upload-pack-request"}
|
62
65
|
assert_equal 200, r.status
|
@@ -74,6 +77,7 @@ class GitHttpTest < Test::Unit::TestCase
|
|
74
77
|
end
|
75
78
|
|
76
79
|
def test_recieve_pack_rpc
|
80
|
+
Grack::Git.any_instance.stubs(:valid_repo?).returns(true)
|
77
81
|
IO.stubs(:popen).yields(MockProcess.new)
|
78
82
|
post "/example/git-receive-pack", {}, {"CONTENT_TYPE" => "application/x-git-receive-pack-request"}
|
79
83
|
assert_equal 200, r.status
|
@@ -151,52 +155,56 @@ class GitHttpTest < Test::Unit::TestCase
|
|
151
155
|
|
152
156
|
def test_git_config_receive_pack
|
153
157
|
app1 = Grack::Server.new({:project_root => example})
|
158
|
+
app1.instance_variable_set(:@git, Grack::Git.new('git', example ))
|
154
159
|
session = Rack::Test::Session.new(app1)
|
155
|
-
|
156
|
-
|
160
|
+
git = Grack::Git
|
161
|
+
git.any_instance.stubs(:config).with('http.receivepack').returns('')
|
157
162
|
session.get "/example/info/refs?service=git-receive-pack"
|
158
163
|
assert_equal 404, session.last_response.status
|
159
164
|
|
160
|
-
|
165
|
+
git.any_instance.stubs(:config).with('http.receivepack').returns('true')
|
161
166
|
session.get "/example/info/refs?service=git-receive-pack"
|
162
167
|
assert_equal 200, session.last_response.status
|
163
168
|
|
164
|
-
|
169
|
+
git.any_instance.stubs(:config).with('http.receivepack').returns('false')
|
165
170
|
session.get "/example/info/refs?service=git-receive-pack"
|
166
171
|
assert_equal 404, session.last_response.status
|
167
172
|
end
|
168
173
|
|
169
174
|
def test_git_config_upload_pack
|
170
175
|
app1 = Grack::Server.new({:project_root => example})
|
176
|
+
# app1.instance_variable_set(:@git, Grack::Git.new('git', example ))
|
171
177
|
session = Rack::Test::Session.new(app1)
|
172
|
-
|
173
|
-
|
178
|
+
git = Grack::Git
|
179
|
+
git.any_instance.stubs(:config).with('http.uploadpack').returns('')
|
174
180
|
session.get "/example/info/refs?service=git-upload-pack"
|
175
181
|
assert_equal 200, session.last_response.status
|
176
182
|
|
177
|
-
|
183
|
+
git.any_instance.stubs(:config).with('http.uploadpack').returns('true')
|
178
184
|
session.get "/example/info/refs?service=git-upload-pack"
|
179
185
|
assert_equal 200, session.last_response.status
|
180
186
|
|
181
|
-
|
187
|
+
git.any_instance.stubs(:config).with('http.uploadpack').returns('false')
|
182
188
|
session.get "/example/info/refs?service=git-upload-pack"
|
183
189
|
assert_equal 404, session.last_response.status
|
184
190
|
end
|
185
191
|
|
186
192
|
def test_send_file
|
187
193
|
app1 = app
|
188
|
-
app1.instance_variable_set(:@
|
194
|
+
app1.instance_variable_set(:@git, Grack::Git.new('git', Dir.pwd))
|
189
195
|
# Reject path traversal
|
190
196
|
assert_equal 404, app1.send_file('tests/../tests', 'text/plain').first
|
191
197
|
# Reject paths starting with '|', avoid File.read('|touch /tmp/pawned; ls /tmp')
|
192
198
|
assert_equal 404, app1.send_file('|tests', 'text/plain').first
|
193
199
|
end
|
194
200
|
|
195
|
-
def
|
201
|
+
def test_get_git
|
196
202
|
# Guard against non-existent directories
|
197
|
-
|
203
|
+
git1 = Grack::Git.new('git', 'foobar')
|
204
|
+
assert_equal false, git1.valid_repo?
|
198
205
|
# Guard against path traversal
|
199
|
-
|
206
|
+
git2 = Grack::Git.new('git', '/../tests')
|
207
|
+
assert_equal false, git2.valid_repo?
|
200
208
|
end
|
201
209
|
|
202
210
|
private
|
@@ -241,7 +249,8 @@ class MockProcess
|
|
241
249
|
def write(data)
|
242
250
|
end
|
243
251
|
|
244
|
-
def read(data)
|
252
|
+
def read(data = nil)
|
253
|
+
''
|
245
254
|
end
|
246
255
|
|
247
256
|
def eof?
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: gitlab-grack
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.0.0
|
4
|
+
version: 2.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Scott Chacon
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-03-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rack
|
@@ -41,7 +41,9 @@ dependencies:
|
|
41
41
|
description: Ruby/Rack Git Smart-HTTP Server Handler
|
42
42
|
email:
|
43
43
|
- schacon@gmail.com
|
44
|
-
executables:
|
44
|
+
executables:
|
45
|
+
- console
|
46
|
+
- testserver
|
45
47
|
extensions: []
|
46
48
|
extra_rdoc_files: []
|
47
49
|
files:
|
@@ -53,12 +55,15 @@ files:
|
|
53
55
|
- Gemfile.lock
|
54
56
|
- README.md
|
55
57
|
- Rakefile
|
58
|
+
- bin/console
|
59
|
+
- bin/testserver
|
56
60
|
- examples/dispatch.fcgi
|
57
61
|
- grack.gemspec
|
58
62
|
- install.txt
|
59
63
|
- lib/grack.rb
|
60
64
|
- lib/grack/auth.rb
|
61
65
|
- lib/grack/bundle.rb
|
66
|
+
- lib/grack/git.rb
|
62
67
|
- lib/grack/server.rb
|
63
68
|
- lib/grack/version.rb
|
64
69
|
- tests/main_test.rb
|
@@ -76,9 +81,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
76
81
|
version: '0'
|
77
82
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
78
83
|
requirements:
|
79
|
-
- - "
|
84
|
+
- - ">="
|
80
85
|
- !ruby/object:Gem::Version
|
81
|
-
version:
|
86
|
+
version: '0'
|
82
87
|
requirements: []
|
83
88
|
rubyforge_project:
|
84
89
|
rubygems_version: 2.2.2
|
@@ -87,3 +92,4 @@ specification_version: 4
|
|
87
92
|
summary: Ruby/Rack Git Smart-HTTP Server Handler
|
88
93
|
test_files:
|
89
94
|
- tests/main_test.rb
|
95
|
+
has_rdoc:
|