geminabox 0.9.0 → 0.10.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of geminabox might be problematic. Click here for more details.
- data/lib/geminabox.rb +58 -37
- data/lib/geminabox/incoming_gem.rb +49 -0
- data/lib/geminabox/version.rb +1 -1
- data/lib/geminabox_client.rb +2 -1
- metadata +4 -3
data/lib/geminabox.rb
CHANGED
@@ -4,6 +4,7 @@ require 'builder'
|
|
4
4
|
require 'sinatra/base'
|
5
5
|
require 'rubygems/builder'
|
6
6
|
require 'rubygems/indexer'
|
7
|
+
require 'rubygems/package'
|
7
8
|
require 'hostess'
|
8
9
|
require 'geminabox/version'
|
9
10
|
require 'rss/atom'
|
@@ -36,6 +37,7 @@ class Geminabox < Sinatra::Base
|
|
36
37
|
autoload :GemVersionCollection, "geminabox/gem_version_collection"
|
37
38
|
autoload :GemVersion, "geminabox/gem_version"
|
38
39
|
autoload :DiskCache, "geminabox/disk_cache"
|
40
|
+
autoload :IncomingGem, "geminabox/incoming_gem"
|
39
41
|
|
40
42
|
before do
|
41
43
|
headers 'X-Powered-By' => "geminabox #{GeminaboxVersion}"
|
@@ -96,58 +98,40 @@ class Geminabox < Sinatra::Base
|
|
96
98
|
end
|
97
99
|
|
98
100
|
post '/upload' do
|
99
|
-
|
100
|
-
error_response( 500, "Please ensure #{File.expand_path(Geminabox.data)} is a directory." ) unless File.directory? Geminabox.data
|
101
|
-
error_response( 500, "Please ensure #{File.expand_path(Geminabox.data)} is writable by the geminabox web server." ) unless File.writable? Geminabox.data
|
102
|
-
else
|
103
|
-
begin
|
104
|
-
FileUtils.mkdir_p(settings.data)
|
105
|
-
rescue Errno::EACCES, Errno::ENOENT, RuntimeError => e
|
106
|
-
error_response( 500, "Could not create #{File.expand_path(Geminabox.data)}.\n#{e}\n#{e.message}" )
|
107
|
-
end
|
108
|
-
end
|
109
|
-
|
110
|
-
unless params[:file] && (tmpfile = params[:file][:tempfile]) && (name = params[:file][:filename])
|
101
|
+
unless params[:file] && params[:file][:filename] && (tmpfile = params[:file][:tempfile])
|
111
102
|
@error = "No file selected"
|
112
103
|
halt [400, erb(:upload)]
|
113
104
|
end
|
105
|
+
handle_incoming_gem(IncomingGem.new(tmpfile))
|
106
|
+
end
|
114
107
|
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
if Geminabox.disallow_replace? and File.exist?(dest_filename)
|
123
|
-
existing_file_digest = Digest::SHA1.file(dest_filename).hexdigest
|
124
|
-
tmpfile_digest = Digest::SHA1.file(tmpfile.path).hexdigest
|
125
|
-
|
126
|
-
if existing_file_digest != tmpfile_digest
|
127
|
-
error_response(409, "Updating an existing gem is not permitted.\nYou should either delete the existing version, or change your version number.")
|
128
|
-
else
|
129
|
-
error_response(200, "Ignoring upload, you uploaded the same thing previously.")
|
108
|
+
post '/api/v1/gems' do
|
109
|
+
begin
|
110
|
+
handle_incoming_gem(IncomingGem.new(request.body))
|
111
|
+
rescue Object => o
|
112
|
+
File.open "/tmp/debug.txt", "a" do |io|
|
113
|
+
io.puts o, o.backtrace
|
130
114
|
end
|
131
115
|
end
|
116
|
+
end
|
132
117
|
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
118
|
+
private
|
119
|
+
|
120
|
+
def handle_incoming_gem(gem)
|
121
|
+
prepare_data_folders
|
122
|
+
error_response(400, "Cannot process gem") unless gem.valid?
|
123
|
+
handle_replacement(gem)
|
124
|
+
write_and_index(gem)
|
139
125
|
|
140
126
|
if api_request?
|
141
|
-
"Gem #{
|
127
|
+
"Gem #{gem.name} received and indexed."
|
142
128
|
else
|
143
129
|
redirect url("/")
|
144
130
|
end
|
145
131
|
end
|
146
132
|
|
147
|
-
private
|
148
|
-
|
149
133
|
def api_request?
|
150
|
-
request.accept.first
|
134
|
+
request.accept.first != "text/html"
|
151
135
|
end
|
152
136
|
|
153
137
|
def error_response(code, message)
|
@@ -164,6 +148,43 @@ HTML
|
|
164
148
|
halt [code, html]
|
165
149
|
end
|
166
150
|
|
151
|
+
def prepare_data_folders
|
152
|
+
if File.exists? Geminabox.data
|
153
|
+
error_response( 500, "Please ensure #{File.expand_path(Geminabox.data)} is a directory." ) unless File.directory? Geminabox.data
|
154
|
+
error_response( 500, "Please ensure #{File.expand_path(Geminabox.data)} is writable by the geminabox web server." ) unless File.writable? Geminabox.data
|
155
|
+
else
|
156
|
+
begin
|
157
|
+
FileUtils.mkdir_p(settings.data)
|
158
|
+
rescue Errno::EACCES, Errno::ENOENT, RuntimeError => e
|
159
|
+
error_response( 500, "Could not create #{File.expand_path(Geminabox.data)}.\n#{e}\n#{e.message}" )
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
FileUtils.mkdir_p(File.join(settings.data, "gems"))
|
164
|
+
end
|
165
|
+
|
166
|
+
def handle_replacement(gem)
|
167
|
+
if Geminabox.disallow_replace? and File.exist?(gem.dest_filename)
|
168
|
+
existing_file_digest = Digest::SHA1.file(gem.dest_filename).hexdigest
|
169
|
+
|
170
|
+
if existing_file_digest != gem.hexdigest
|
171
|
+
error_response(409, "Updating an existing gem is not permitted.\nYou should either delete the existing version, or change your version number.")
|
172
|
+
else
|
173
|
+
error_response(200, "Ignoring upload, you uploaded the same thing previously.")
|
174
|
+
end
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
def write_and_index(gem)
|
179
|
+
tmpfile = gem.gem_data
|
180
|
+
atomic_write(gem.dest_filename) do |f|
|
181
|
+
while blk = tmpfile.read(65536)
|
182
|
+
f << blk
|
183
|
+
end
|
184
|
+
end
|
185
|
+
reindex
|
186
|
+
end
|
187
|
+
|
167
188
|
def reindex(force_rebuild = false)
|
168
189
|
Geminabox.fixup_bundler_rubygems!
|
169
190
|
force_rebuild = true unless settings.incremental_updates
|
@@ -0,0 +1,49 @@
|
|
1
|
+
class Geminabox::IncomingGem
|
2
|
+
def initialize(gem_data, root_path = Geminabox.settings.data)
|
3
|
+
unless gem_data.respond_to? :read
|
4
|
+
raise ArgumentError, "Expected an instance of IO"
|
5
|
+
end
|
6
|
+
|
7
|
+
digest = Digest::SHA1.new
|
8
|
+
@tempfile = Tempfile.new("gem", :encoding => 'binary')
|
9
|
+
while data = gem_data.read(1024**2)
|
10
|
+
@tempfile.write data
|
11
|
+
digest << data
|
12
|
+
end
|
13
|
+
@tempfile.close
|
14
|
+
@sha1 = digest.hexdigest
|
15
|
+
|
16
|
+
@root_path = root_path
|
17
|
+
end
|
18
|
+
|
19
|
+
def gem_data
|
20
|
+
File.open(@tempfile.path, "rb")
|
21
|
+
end
|
22
|
+
|
23
|
+
def valid?
|
24
|
+
spec && spec.name && spec.version
|
25
|
+
rescue Gem::Package::Error
|
26
|
+
false
|
27
|
+
end
|
28
|
+
|
29
|
+
def spec
|
30
|
+
unless @spec
|
31
|
+
Gem::Package.open(gem_data, "r", nil) do |pkg|
|
32
|
+
@spec = pkg.metadata
|
33
|
+
end
|
34
|
+
end
|
35
|
+
@spec
|
36
|
+
end
|
37
|
+
|
38
|
+
def name
|
39
|
+
"#{spec.name}-#{spec.version}.gem"
|
40
|
+
end
|
41
|
+
|
42
|
+
def dest_filename
|
43
|
+
File.join(@root_path, "gems", name)
|
44
|
+
end
|
45
|
+
|
46
|
+
def hexdigest
|
47
|
+
@sha1
|
48
|
+
end
|
49
|
+
end
|
data/lib/geminabox/version.rb
CHANGED
@@ -1 +1 @@
|
|
1
|
-
GeminaboxVersion = '0.
|
1
|
+
GeminaboxVersion = '0.10.0' unless defined? GeminaboxVersion
|
data/lib/geminabox_client.rb
CHANGED
@@ -10,7 +10,8 @@ class GeminaboxClient
|
|
10
10
|
@http_client.set_auth(url_for(:upload), @username, @password) if @username or @password
|
11
11
|
@http_client.www_auth.basic_auth.challenge(url_for(:upload)) # Workaround: https://github.com/nahi/httpclient/issues/63
|
12
12
|
@http_client.ssl_config.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
13
|
-
@http_client.send_timeout =
|
13
|
+
@http_client.send_timeout = 0
|
14
|
+
@http_client.receive_timeout = 0
|
14
15
|
end
|
15
16
|
|
16
17
|
def extract_username_and_password_from_url!(url)
|
metadata
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
name: geminabox
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease:
|
5
|
-
version: 0.
|
5
|
+
version: 0.10.0
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Tom Lea
|
@@ -166,6 +166,7 @@ files:
|
|
166
166
|
- lib/geminabox/disk_cache.rb
|
167
167
|
- lib/geminabox/gem_version.rb
|
168
168
|
- lib/geminabox/gem_version_collection.rb
|
169
|
+
- lib/geminabox/incoming_gem.rb
|
169
170
|
- lib/geminabox/indexer.rb
|
170
171
|
- lib/geminabox/version.rb
|
171
172
|
- lib/geminabox.rb
|
@@ -197,7 +198,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
197
198
|
- !ruby/object:Gem::Version
|
198
199
|
segments:
|
199
200
|
- 0
|
200
|
-
hash:
|
201
|
+
hash: 1008215541658349139
|
201
202
|
version: '0'
|
202
203
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
203
204
|
none: false
|
@@ -206,7 +207,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
206
207
|
- !ruby/object:Gem::Version
|
207
208
|
segments:
|
208
209
|
- 0
|
209
|
-
hash:
|
210
|
+
hash: 1008215541658349139
|
210
211
|
version: '0'
|
211
212
|
requirements: []
|
212
213
|
rubyforge_project:
|