| |   |
| 9 | 9 | :order => "status, id desc", :dependent => :destroy |
| 10 | 10 | has_many :proposed_merge_requests, :foreign_key => 'source_repository_id', |
| 11 | 11 | :class_name => 'MergeRequest', :order => "id desc", :dependent => :destroy |
| 12 | has_many :cloners, :dependent => :destroy |
| 12 | 13 | |
| 13 | 14 | validates_presence_of :user_id, :project_id, :name |
| 14 | 15 | validates_format_of :name, :with => /^[a-z0-9_\-]+$/i, |
| … | … | |
| 31 | 31 | |
| 32 | 32 | def self.find_by_path(path) |
| 33 | 33 | repo_name, project_name = (path.split('/') - GitoriousConfig['repository_base_path'].split('/')).reverse |
| 34 | |
| 34 | 35 | project = Project.find_by_slug!(project_name) |
| 35 | 36 | project.repositories.find_by_name(repo_name.sub(/\.git/, "")) |
| 36 | 37 | end |
| … | … | |
| 229 | 229 | users_by_email = users.inject({}){|hash, user| hash[user.email] = user; hash } |
| 230 | 230 | users_by_email |
| 231 | 231 | end |
| 232 | |
| 233 | def cloned_from(ip, country_code = "--", country_name = nil) |
| 234 | cloners.create(:ip => ip, :date => Time.now.utc, :country_code => country_code, :country => country_name) |
| 235 | end |
| 232 | 236 | |
| 233 | 237 | protected |
| 234 | 238 | def set_as_mainline_if_first |
| toggle raw diff |
--- a/app/models/repository.rb
+++ b/app/models/repository.rb
@@ -9,6 +9,7 @@ class Repository < ActiveRecord::Base
:order => "status, id desc", :dependent => :destroy
has_many :proposed_merge_requests, :foreign_key => 'source_repository_id',
:class_name => 'MergeRequest', :order => "id desc", :dependent => :destroy
+ has_many :cloners, :dependent => :destroy
validates_presence_of :user_id, :project_id, :name
validates_format_of :name, :with => /^[a-z0-9_\-]+$/i,
@@ -30,6 +31,7 @@ class Repository < ActiveRecord::Base
def self.find_by_path(path)
repo_name, project_name = (path.split('/') - GitoriousConfig['repository_base_path'].split('/')).reverse
+
project = Project.find_by_slug!(project_name)
project.repositories.find_by_name(repo_name.sub(/\.git/, ""))
end
@@ -227,6 +229,10 @@ class Repository < ActiveRecord::Base
users_by_email = users.inject({}){|hash, user| hash[user.email] = user; hash }
users_by_email
end
+
+ def cloned_from(ip, country_code = "--", country_name = nil)
+ cloners.create(:ip => ip, :date => Time.now.utc, :country_code => country_code, :country => country_name)
+ end
protected
def set_as_mainline_if_first |
| |   |
| 2 | 2 | |
| 3 | 3 | require 'rubygems' |
| 4 | 4 | require 'daemons' |
| 5 | require 'geoip' |
| 5 | 6 | require 'socket' |
| 6 | 7 | |
| 8 | ENV["RAILS_ENV"] ||= "production" |
| 7 | 9 | require File.dirname(__FILE__)+'/../config/environment' |
| 8 | 10 | |
| 11 | Rails.configuration.log_level = :info # Disable debug |
| 12 | |
| 9 | 13 | BASE_PATH = File.expand_path(GitoriousConfig['repository_base_path']) |
| 10 | 14 | |
| 11 | 15 | module Git |
| … | … | |
| 24 | 24 | def initialize |
| 25 | 25 | daemonize(File.join(RAILS_ROOT, "log", "git-daemon.log")) |
| 26 | 26 | |
| 27 | @geoip = GeoIP.new(File.join(RAILS_ROOT, "data", "GeoIP.dat")) |
| 27 | 28 | trap "CLD" do |
| 28 | 29 | pid = Process.wait |
| 29 | 30 | log(pid, "Disconnected. (status=#{$?.exitstatus})") |
| … | … | |
| 32 | 32 | |
| 33 | 33 | port = 9418 |
| 34 | 34 | server = TCPServer.new('localhost', port) |
| 35 | | |
| 36 | | service_regexp = /(\d{4})(git-[\w-]+)\s(.+)\x0host=([\w\.\-]+)/.freeze |
| 35 | service_regexp = /(\w{4})(git-[\w-]+)\s(.+)\x0host=([\w\.\-]+)/.freeze |
| 37 | 36 | while session = server.accept |
| 38 | 37 | line = session.recv(1000) |
| 39 | 38 | timeout = 30 |
| … | … | |
| 43 | 43 | host = $4 |
| 44 | 44 | |
| 45 | 45 | path = "#{BASE_PATH}/#{path}" |
| 46 | | |
| 47 | 46 | if !File.directory?(path) |
| 48 | 47 | log(Process.pid, "Invalid path: #{path}") |
| 49 | 48 | session.close |
| 50 | 49 | next |
| 51 | 50 | end |
| 52 | 51 | |
| 52 | if !File.exist?(File.join(path, "git-daemon-export-ok")) |
| 53 | session.close |
| 54 | next |
| 55 | end |
| 56 | |
| 53 | 57 | Dir.chdir(path) do |
| 54 | 58 | cmd = "git-upload-pack --strict --timeout=#{timeout} ." |
| 55 | 59 | |
| 56 | 60 | fork do |
| 61 | repository = nil |
| 62 | begin |
| 63 | ActiveRecord::Base.allow_concurrency = true |
| 64 | repository = ::Repository.find_by_path(path) |
| 65 | rescue Exception |
| 66 | end |
| 57 | 67 | pid = Process.pid |
| 58 | 68 | domain, port, name, ip = session.addr |
| 59 | 69 | log(pid, "Connection from #{ip}") |
| … | … | |
| 72 | 72 | $stdin.reopen(session) |
| 73 | 73 | session.close |
| 74 | 74 | |
| 75 | if repository |
| 76 | localization = @geoip.country(ip) |
| 77 | repository.cloned_from(ip, localization[3], localization[5]) |
| 78 | else |
| 79 | log(pid, "Cannot find repository: #{path}") |
| 80 | end |
| 81 | |
| 75 | 82 | exec(cmd) |
| 76 | | exit |
| 83 | |
| 84 | exit! |
| 77 | 85 | end |
| 78 | 86 | end |
| 87 | else |
| 88 | $stderr.puts "Invalid request: #{line}" |
| 89 | session.close |
| 79 | 90 | end |
| 80 | 91 | end |
| 81 | 92 | end |
| toggle raw diff |
--- a/script/git-daemon
+++ b/script/git-daemon
@@ -2,10 +2,14 @@
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
@@ -20,6 +24,7 @@ class Daemon
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})")
@@ -27,8 +32,7 @@ class Daemon
port = 9418
server = TCPServer.new('localhost', port)
-
- service_regexp = /(\d{4})(git-[\w-]+)\s(.+)\x0host=([\w\.\-]+)/.freeze
+ service_regexp = /(\w{4})(git-[\w-]+)\s(.+)\x0host=([\w\.\-]+)/.freeze
while session = server.accept
line = session.recv(1000)
timeout = 30
@@ -39,17 +43,27 @@ class Daemon
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}")
@@ -58,10 +72,21 @@ class Daemon
$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
+
+ exit!
end
end
+ else
+ $stderr.puts "Invalid request: #{line}"
+ session.close
end
end
end |
| |   |
| 1 | require File.dirname(__FILE__) + '/../spec_helper' |
| 2 | require 'geoip' |
| 3 | |
| 4 | describe Cloner do |
| 5 | before(:all) do |
| 6 | @geoip = GeoIP.new(File.join(RAILS_ROOT, "data", "GeoIP.dat")) |
| 7 | end |
| 8 | |
| 9 | before(:each) do |
| 10 | @cloner = Cloner.new |
| 11 | end |
| 12 | |
| 13 | it "should has a valid country" do |
| 14 | localization = @geoip.country(cloners(:argentina).ip) |
| 15 | localization[3].should == cloners(:argentina).country_code |
| 16 | localization[5].should == cloners(:argentina).country |
| 17 | end |
| 18 | end |
| toggle raw diff |
--- /dev/null
+++ b/spec/models/cloner_spec.rb
@@ -0,0 +1,18 @@
+require File.dirname(__FILE__) + '/../spec_helper'
+require 'geoip'
+
+describe Cloner do
+ before(:all) do
+ @geoip = GeoIP.new(File.join(RAILS_ROOT, "data", "GeoIP.dat"))
+ end
+
+ before(:each) do
+ @cloner = Cloner.new
+ end
+
+ it "should has a valid country" do
+ localization = @geoip.country(cloners(:argentina).ip)
+ localization[3].should == cloners(:argentina).country_code
+ localization[5].should == cloners(:argentina).country
+ end
+end |