1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
|
#!/usr/bin/env ruby
require 'rubygems'
require 'daemons'
require 'geoip'
require 'socket'
ENV["RAILS_ENV"] ||= "production"
require File.dirname(__FILE__)+'/../config/environment'
Rails.configuration.log_level = :info # Disable debug
BASE_PATH = File.expand_path(GitoriousConfig['repository_base_path'])
module Git
class Daemon
include Daemonize
def self.start
new
end
def initialize
daemonize(File.join(RAILS_ROOT, "log", "git-daemon.log"))
@geoip = GeoIP.new(File.join(RAILS_ROOT, "data", "GeoIP.dat"))
trap "CLD" do
pid = Process.wait
log(pid, "Disconnected. (status=#{$?.exitstatus})")
end
port = 9418
server = TCPServer.new('localhost', port)
service_regexp = /(\w{4})(git-[\w-]+)\s(.+)\x0host=([\w\.\-]+)/.freeze
while session = server.accept
line = session.recv(1000)
timeout = 30
if line =~ service_regexp
code = $1
service = $2
path = $3
host = $4
path = "#{BASE_PATH}/#{path}"
if !File.directory?(path)
log(Process.pid, "Invalid path: #{path}")
session.close
next
end
if !File.exist?(File.join(path, "git-daemon-export-ok"))
session.close
next
end
Dir.chdir(path) do
cmd = "git-upload-pack --strict --timeout=#{timeout} ."
fork do
repository = nil
begin
ActiveRecord::Base.allow_concurrency = true
repository = ::Repository.find_by_path(path)
rescue Exception
end
pid = Process.pid
domain, port, name, ip = session.addr
log(pid, "Connection from #{ip}")
$stdout.reopen(session)
$stdin.reopen(session)
session.close
if repository
localization = @geoip.country(ip)
repository.cloned_from(ip, localization[3], localization[5])
else
log(pid, "Cannot find repository: #{path}")
end
exec(cmd)
exit!
end
end
else
$stderr.puts "Invalid request: #{line}"
session.close
end
end
end
def log(pid, msg)
$stderr.puts "[#{pid}] #{msg}"
end
end
end
trap "SIGINT" do
$stderr.puts "Exiting..."
exit 0
end
Git::Daemon.start
|