geminabox 0.9.0 → 0.10.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.
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: 
         |