From cc065fbeaa8b5e480d6ba5349198042e8a84b011 Mon Sep 17 00:00:00 2001 From: Stan Hu Date: Sat, 12 Mar 2016 01:09:37 -0800 Subject: [PATCH] Support Golang subpackage fetching Closes #13805 --- CHANGELOG | 1 + config/initializers/go_get.rb | 1 + lib/gitlab/middleware/go.rb | 51 +++++++++++++++++++++++++++++++++++ 3 files changed, 53 insertions(+) create mode 100644 config/initializers/go_get.rb create mode 100644 lib/gitlab/middleware/go.rb diff --git a/CHANGELOG b/CHANGELOG index 1847c5193ab..b29ad11e6ad 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,6 +1,7 @@ Please view this file on the master branch, on stable branches it's out of date. v 8.6.0 (unreleased) + - Support Golang subpackage fetching (Stan Hu) - Contributions to forked projects are included in calendar - Improve the formatting for the user page bio (Connor Shea) - Removed the default password from the initial admin account created during diff --git a/config/initializers/go_get.rb b/config/initializers/go_get.rb new file mode 100644 index 00000000000..7e7896b4900 --- /dev/null +++ b/config/initializers/go_get.rb @@ -0,0 +1 @@ +Rails.application.config.middleware.use(Gitlab::Middleware::Go) diff --git a/lib/gitlab/middleware/go.rb b/lib/gitlab/middleware/go.rb new file mode 100644 index 00000000000..bc9bee7cbb6 --- /dev/null +++ b/lib/gitlab/middleware/go.rb @@ -0,0 +1,51 @@ +# A dumb middleware that returns a Go HTML document if the go-get=1 query string +# is used irrespective if the namespace/project exists +module Gitlab + module Middleware + class Go + def initialize(app) + @app = app + end + + def call(env) + request = Rack::Request.new(env) + + if go_request?(request) + render_go_doc(request) + else + @app.call(env) + end + end + + private + + def render_go_doc(request) + body = go_body(request) + response = Rack::Response.new(body, 200, { 'Content-Type' => 'text/html' }) + response.finish + end + + def go_request?(request) + return request["go-get"].to_i == 1 + end + + def go_body(request) + base_url = Settings.gitlab['url'] + # Go subpackages may be in the form of namespace/project/path1/path2/../pathN + # We can just ignore the paths and leave the namespace/project + path_info = request.env["PATH_INFO"] + path_info.sub!(/^\//, '') + project_path = path_info.split('/').first(2).join('/') + request_url = URI.join(base_url, project_path) + domain_path = strip_url(request_url.to_s) + + "\n"; + end + + def strip_url(url) + url.gsub('http://', ''). + gsub('https://', '') + end + end + end +end