Class: Rack::Svn::File

Inherits:
Object
  • Object
show all
Defined in:
lib/rack/svn/file.rb

Constant Summary collapse

F =
::File

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(root) ⇒ File

Returns a new instance of File.



14
15
16
# File 'lib/rack/svn/file.rb', line 14

def initialize(root)
  @root = root
end

Instance Attribute Details

#path ⇒ Object Also known as: to_path

Returns the value of attribute path.



10
11
12
# File 'lib/rack/svn/file.rb', line 10

def path
  @path
end

#root ⇒ Object

Returns the value of attribute root.



9
10
11
# File 'lib/rack/svn/file.rb', line 9

def root
  @root
end

Instance Method Details

#_call(env) ⇒ Object



24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
# File 'lib/rack/svn/file.rb', line 24

def _call(env)
  @branch_name = env['PATH_PREFIX'] || ""
  @path_info = Rack::Utils.unescape(env["PATH_INFO"])
  return forbidden  if @path_info.include? ".."

  @path = F.join(@root, @branch_name, @path_info)

  begin
    #if F.file?(@path) && F.readable?(@path)
    serving
    #else
    #raise Errno::EPERM
    #end
  rescue SystemCallError
    not_found
  end
end

#call(env) ⇒ Object



18
19
20
# File 'lib/rack/svn/file.rb', line 18

def call(env)
  dup._call(env)
end

#each ⇒ Object



82
83
84
85
86
87
88
89
90
# File 'lib/rack/svn/file.rb', line 82

def each
  context   = ::Svn::Client::Context.new
  body      = context.cat(@path, "HEAD","HEAD")
  StringIO.new(body, "rb") do |file|
    while part = file.read(8192)
      yield part
    end
  end
end

#forbidden ⇒ Object



42
43
44
45
46
47
48
# File 'lib/rack/svn/file.rb', line 42

def forbidden
  body = "Forbidden\n"
  [403, {"Content-Type" => "text/plain",
      "Content-Length" => body.size.to_s,
      "X-Cascade" => "pass"},
    [body]]
end

#not_found ⇒ Object



74
75
76
77
78
79
80
# File 'lib/rack/svn/file.rb', line 74

def not_found
  body = "File not found: #{@path_info}\n"
  [404, {"Content-Type" => "text/plain",
      "Content-Length" => body.size.to_s,
      "X-Cascade" => "pass"},
    [body]]
end

#serving ⇒ Object

NOTE:

We check via File::size? whether this file provides size info
via stat (e.g. /proc files often don't), otherwise we have to
figure it out by reading the whole file into memory. And while
we're at it we also use this as body then.


56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
# File 'lib/rack/svn/file.rb', line 56

def serving
  context   = ::Svn::Client::Context.new
  body      = context.cat(@path, "HEAD","HEAD")

  last_modified = nil
  size          = nil
  context.list(@path ,"HEAD","HEAD") do |name,dirent,lock,abs_path|
    size          = dirent.size
    last_modified = dirent.time2
  end

  [200, {
      "Last-Modified"  => last_modified.httpdate,
      "Content-Type"   => Rack::Mime.mime_type(F.extname(@path_info), 'text/plain'),
      "Content-Length" => size.to_s
    }, body]
end