Class: Paquette::GemServer
- Inherits:
-
Object
- Object
- Paquette::GemServer
- Defined in:
- lib/paquette/gem_server.rb,
lib/paquette/gem_server/gem_repacker.rb,
lib/paquette/gem_server/personalizer.rb,
lib/paquette/gem_server/gem_repository.rb,
lib/paquette/gem_server/read_gated_repository.rb,
lib/paquette/gem_server/directory_gem_repository.rb
Defined Under Namespace
Classes: DirectoryGemRepository, GemRepacker, GemRepository, Personalizer, ReadGatedRepository
Constant Summary collapse
- @@routes =
Routes.draw do |r| # Root endpoint r.get "/" do text_ok("Paquette RubyGems Repository") end # API endpoints r.post "/api/v1/gems" do handle_push end r.delete "/api/v1/gems/yank" do handle_yank end r.get "/api/v1/versions" do handle_versions end r.get "/api/v1/names" do handle_names end r.get "/api/v1/search.json" do |query: nil| handle_search(query) end # Specs endpoints r.get "/specs.4.8" do handle_specs("4.8") end r.get "/specs.4.8.gz" do handle_specs("4.8.gz") end r.get "/latest_specs.4.8" do handle_latest_specs("4.8") end r.get "/latest_specs.4.8.gz" do handle_latest_specs("4.8.gz") end # Compact index endpoints r.get "/names" do handle_compact_names end r.get "/versions" do handle_compact_versions end # Dynamic endpoints with parameters r.get "/info/:gem_name" do |gem_name:| info_lines = @repository.compact_info(gem_name) if info_lines.empty? not_found("Not Found") else text_ok(info_lines.join("\n")) end end r.get "/quick/Marshal.4.8/:gem_spec_name.gemspec.rz" do |gem_spec_name:| # Parse gem name and version from the spec name (e.g., "zip_kit-6.3.2") if (match = gem_spec_name.match(/^(.+?)-(\d+\.\d+\.\d+.*)$/)) gem_name, version = match[1], match[2] if @repository.gem_exists?(gem_name, version) spec = @repository.gem_spec(gem_name, version) if spec # Marshal the spec and compress it with raw deflate (not gzip) marshaled_spec = Marshal.dump(spec) compressed_spec = Zlib::Deflate.deflate(marshaled_spec) [200, {"Content-Type" => "application/octet-stream"}, [compressed_spec]] else not_found("Spec not found") end else not_found("Gem not found: #{gem_name}-#{version}") end else not_found("Invalid gem spec name: #{gem_spec_name}") end end r.get "/gems/:gem_filename" do |gem_filename:| # Extract gem name and version from filename if (match = gem_filename.match(/^(.+)-(\d+\.\d+\.\d+.*)\.gem$/)) gem_name, version = match[1], match[2] return not_found("Gem not found or it is not within your license") unless @repository.gem_exists?(gem_name, version) # gem_file_path now automatically returns personalized gem gem_path = @repository.gem_file_path(gem_name, version) clen = File.size(gem_path).to_s hh = {"Content-Type" => "application/octet-stream", "Content-Length" => clen} [200, hh, File.open(gem_path, "rb")] else not_found("Invalid gem filename") end end end
Instance Method Summary collapse
- #call(env) ⇒ Object
-
#initialize(repository) ⇒ GemServer
constructor
Build a gem server backed by ‘repository`.
Constructor Details
#initialize(repository) ⇒ GemServer
Build a gem server backed by ‘repository`. Reads, writes, and yanks all flow through this one object — whether writes are accepted depends on the wrapper chain the caller assembled. A ReadGatedRepository, for example, refuses add_gem and yank_gem; a bare DirectoryGemRepository accepts both. Callers typically construct the stack per-request so user-specific state (entitlements, license keys) is captured in plain closures rather than stored on the server.
128 129 130 |
# File 'lib/paquette/gem_server.rb', line 128 def initialize(repository) @repository = repository end |
Instance Method Details
#call(env) ⇒ Object
132 133 134 135 136 137 138 139 |
# File 'lib/paquette/gem_server.rb', line 132 def call(env) request = Rack::Request.new(env) route = @@routes.match(request) return not_found("Not found") unless route @request = request @@routes.perform_action(route, self, request) end |