3 # Copyright (C) 2011-2014 Gitorious AS
5 # This program is free software: you can redistribute it and/or modify
6 # it under the terms of the GNU Affero General Public License as published by
7 # the Free Software Foundation, either version 3 of the License, or
8 # (at your option) any later version.
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU Affero General Public License for more details.
15 # You should have received a copy of the GNU Affero General Public License
16 # along with this program. If not, see <http://www.gnu.org/licenses/>.
19 # Run with `env RAILS_ENV="development" proxymachine -c config/git-proxymachine.rb`
21 ENV["RAILS_ENV"] ||= "production"
22 require File.dirname(__FILE__) + "/../config/environment" unless defined?(Rails)
25 # Lookup the real repository path based on +path+
26 def self.lookup_repository(path)
27 LOGGER.info "Looking up #{path.inspect}"
28 ActiveRecord::Base.verify_active_connections!
29 ::Repository.find_by_path(path)
32 def self.error_message(msg)
33 message = ["\n----------------------------------------------"]
35 message << "----------------------------------------------\n"
36 sideband_message(message.join("\n"))
39 def self.sideband_message(message, channel = 2)
40 msg = "%s%s" % [channel.chr, message]
41 "%04x%s" % [msg.length+4, msg]
44 def self.header_tag(path)
46 header_data = "git-upload-pack /#{path}\000host=#{host}\000"
47 "%04x%s" % [header_data.length+4, header_data]
51 # Do the proxying to the proper host, and send the real path onwards
52 # to the backend git-daemon
53 remote_host = ENV['GIT_DAEMON_PORT_9418_TCP_ADDR'] || 'localhost'
54 remote_port = ENV['GIT_DAEMON_PORT_9418_TCP_PORT'] || 9400
55 remote = "#{remote_host}:#{remote_port}"
58 if data =~ /^....(git\-upload\-pack|git\ upload\-pack)\s(.+)\x00host=(.+)\x00/
59 service, path, host = $1, $2, $3
60 if repository = GitRouter.lookup_repository(path)
63 :data => GitRouter.header_tag(repository.hashed_path + ".git")
66 { :close => GitRouter.error_message("Cannot find repository #{path}") }
68 elsif data =~ /^....(git\-receive\-pack|git\ receive\-pack)/
70 :close => GitRouter.error_message("The git:// protocol is read-only.\n\n" +
71 "Please use the push url as listed on the repository page.")