rack-cgi 0.2.3 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a57e39eb35e6fbd1bf45f61d55dc6573ebdfdd1d
4
- data.tar.gz: 14ba6dbf2ba1a2de9f667af129677ec3631ddc6e
3
+ metadata.gz: 4618ec968b358ef35f6d1ea3399aa48229fadaec
4
+ data.tar.gz: 17b358d43485c6cacb06d371f1ce7d6b8873436f
5
5
  SHA512:
6
- metadata.gz: 596e99e2e0f7e6cf232897087252457a72a0c44c434d0e9e3bd0e1f2825aa97eddbab57f7ce16ba4437dd6e2320cd495fe24eea7031d073e0b3698b42cd4c0d4
7
- data.tar.gz: 25d98ca0ee4d4eed6e59baf8779e9f9d884cba91f98026b33a0dfdbbf843fcbb3fe043c165278c509f9cd34064395aa1a9cddd4f0b24587f9a9d2f1c80a54e45
6
+ metadata.gz: 4e401f35c930f09fbe29b44329b1c39b03be50df738891f2c1ab9b535d223c473cf3f92f82030a09c85fdd604c0717bafd88fbc209b49dad0fa4db8753c9814a
7
+ data.tar.gz: 8ef794dcd8a596bfda31a2967aba5583f6e0010af48e2320ecb00091383a6f5a334d201a23cef8b15206dcbcedf96ea6cb70264ca071091bbd9e538ff90c99ec
@@ -1,5 +1,5 @@
1
1
  module Rack
2
2
  module Cgi
3
- VERSION = "0.2.3"
3
+ VERSION = "0.3.0"
4
4
  end
5
5
  end
data/lib/rack/cgi.rb CHANGED
@@ -1 +1,174 @@
1
- require 'rack-cgi'
1
+ require 'childprocess'
2
+
3
+ module Rack
4
+ class CGI
5
+ class Executable
6
+ def self.=~ rhs
7
+ ::File.executable? rhs
8
+ end
9
+ end
10
+
11
+ def initialize app, args = {}
12
+ @app = app
13
+ @opts = args.select {|k, _| k.is_a? Symbol}
14
+ @rules = args.select {|k, _| !k.is_a? Symbol}
15
+
16
+ @root = @opts[:cgi_path]
17
+ if @root !~ /^\//
18
+ @root = ::File.join(Dir.pwd, @root)
19
+ end
20
+
21
+ @index = @opts[:index] || []
22
+ @index = [@index] if not @index.is_a? Hash
23
+ end
24
+
25
+ def solve_path path
26
+ path = ::File.join(@root, path)
27
+ if ::File.directory? path
28
+ @index.each do |f|
29
+ path2 = ::File.join(path, f)
30
+ return path2 if ::File.file? path2
31
+ end
32
+ else
33
+ return path if ::File.file? path
34
+ end
35
+ nil
36
+ end
37
+
38
+ def cgi_env env, path
39
+ env = env.select {|k, _| k =~ /^[A-Z]/}
40
+ env['SCRIPT_FILENAME'] = path
41
+ env['DOCUMENT_ROOT'] = @root
42
+ env['REDIRECT_STATUS'] = "200"
43
+ env
44
+ end
45
+
46
+ def match_cgi_rule path
47
+ @rules.each do |m, r|
48
+ if m =~ path
49
+ return r
50
+ end
51
+ end
52
+ return nil
53
+ end
54
+
55
+ def run_cgi rule, path, env
56
+ if rule.empty?
57
+ args = [path]
58
+ else
59
+ args = [rule, path]
60
+ end
61
+
62
+ process = ChildProcess.build(*args)
63
+ process.io.stdout = Tempfile.new('rack-cgi-stdout')
64
+ process.io.stderr = Tempfile.new('rack-cgi-stderr')
65
+ env.each do |k, v|
66
+ process.environment[k] = v
67
+ end
68
+ process.cwd = Dir.pwd
69
+ process.start
70
+ process.wait
71
+
72
+ cont_out = ::File.read(process.io.stdout.path)
73
+ cont_err = ::File.read(process.io.stderr.path)
74
+ process.io.stdout.unlink
75
+ process.io.stderr.unlink
76
+
77
+ [process.exit_code, cont_out, cont_err]
78
+ end
79
+
80
+ def split_header_content output
81
+ lines = output.lines.to_a
82
+ header = []
83
+
84
+ until lines.empty?
85
+ l = lines.shift
86
+ if l == "\n" or l == "\r\n"
87
+ # find break line between header and content
88
+ return header.join, lines.join
89
+ elsif l =~ /:/
90
+ header << l
91
+ else
92
+ # content break header ruler, so deal as no header
93
+ return "", output
94
+ end
95
+ end
96
+
97
+ # deal all content as header
98
+ return output, ""
99
+ end
100
+
101
+ def parse_output output
102
+ header, content = split_header_content output
103
+
104
+ h = {}
105
+ header.each_line do |l|
106
+ k, v = l.split ':', 2
107
+ k.strip!
108
+ v.strip!
109
+ h[k.downcase] = [k, v]
110
+ end
111
+
112
+ if h['status']
113
+ status = h['status'][1].to_i
114
+ h.delete 'status'
115
+ else
116
+ status = 200
117
+ end
118
+
119
+ header_hash = Hash[h.values]
120
+
121
+ [status, header_hash, [content]]
122
+ end
123
+
124
+ def report_error code, out, err, cgi_env
125
+ h = {'Content-Type' => 'text/plain'}
126
+ status = 500
127
+ reports = []
128
+
129
+ reports << "CGI Error!\n\n"
130
+ reports << "stdout output:\n"
131
+ reports << out
132
+ reports << "\n"
133
+ reports << "stderr output:\n"
134
+ reports << err
135
+ reports << "\n"
136
+ reports << "environments:\n"
137
+ cgi_env.each do |k, v|
138
+ reports << "#{k} => #{v}\n"
139
+ end
140
+
141
+ [status, h, reports]
142
+ end
143
+
144
+ def call(env)
145
+ path = solve_path env["PATH_INFO"]
146
+ if not path
147
+ return @app.call(env)
148
+ end
149
+
150
+ rule = match_cgi_rule path
151
+ if not rule
152
+ return @app.call(env)
153
+ end
154
+
155
+ cgi_env = cgi_env(env, path)
156
+ code, out, err = run_cgi rule, path, cgi_env
157
+ if code == 0
158
+ parse_output out
159
+ else
160
+ report_error code, out, err, cgi_env
161
+ end
162
+ end
163
+ def run(env, rule, path)
164
+ cgi_env = cgi_env(env, path)
165
+ code, out, err = run_cgi rule, path, cgi_env
166
+ if code == 0
167
+ parse_output out
168
+ else
169
+ report_error code, out, err, cgi_env
170
+ end
171
+ end
172
+ end
173
+ end
174
+
data/lib/rack-cgi.rb CHANGED
@@ -1,165 +1 @@
1
- require 'childprocess'
2
-
3
- module Rack
4
- class CGI
5
- class Executable
6
- def self.=~ rhs
7
- ::File.executable? rhs
8
- end
9
- end
10
-
11
- def initialize app, args = {}
12
- @app = app
13
- @opts = args.select {|k, _| k.is_a? Symbol}
14
- @rules = args.select {|k, _| !k.is_a? Symbol}
15
-
16
- @root = @opts[:cgi_path]
17
- if @root !~ /^\//
18
- @root = ::File.join(Dir.pwd, @root)
19
- end
20
-
21
- @index = @opts[:index] || []
22
- @index = [@index] if not @index.is_a? Hash
23
- end
24
-
25
- def solve_path path
26
- path = ::File.join(@root, path)
27
- if ::File.directory? path
28
- @index.each do |f|
29
- path2 = ::File.join(path, f)
30
- return path2 if ::File.file? path2
31
- end
32
- else
33
- return path if ::File.file? path
34
- end
35
- nil
36
- end
37
-
38
- def cgi_env env, path
39
- env = env.select {|k, _| k =~ /^[A-Z]/}
40
- env['SCRIPT_FILENAME'] = path
41
- env['DOCUMENT_ROOT'] = @root
42
- env['REDIRECT_STATUS'] = "200"
43
- env
44
- end
45
-
46
- def match_cgi_rule path
47
- @rules.each do |m, r|
48
- if m =~ path
49
- return r
50
- end
51
- end
52
- return nil
53
- end
54
-
55
- def run_cgi rule, path, env
56
- if rule.empty?
57
- args = [path]
58
- else
59
- args = [rule, path]
60
- end
61
-
62
- process = ChildProcess.build(*args)
63
- process.io.stdout = Tempfile.new('rack-cgi-stdout')
64
- process.io.stderr = Tempfile.new('rack-cgi-stderr')
65
- env.each do |k, v|
66
- process.environment[k] = v
67
- end
68
- process.cwd = Dir.pwd
69
- process.start
70
- process.wait
71
-
72
- cont_out = ::File.read(process.io.stdout.path)
73
- cont_err = ::File.read(process.io.stderr.path)
74
- process.io.stdout.unlink
75
- process.io.stderr.unlink
76
-
77
- [process.exit_code, cont_out, cont_err]
78
- end
79
-
80
- def split_header_content output
81
- lines = output.lines.to_a
82
- header = []
83
-
84
- until lines.empty?
85
- l = lines.shift
86
- if l == "\n" or l == "\r\n"
87
- # find break line between header and content
88
- return header.join, lines.join
89
- elsif l =~ /:/
90
- header << l
91
- else
92
- # content break header ruler, so deal as no header
93
- return "", output
94
- end
95
- end
96
-
97
- # deal all content as header
98
- return output, ""
99
- end
100
-
101
- def parse_output output
102
- header, content = split_header_content output
103
-
104
- h = {}
105
- header.each_line do |l|
106
- k, v = l.split ':', 2
107
- k.strip!
108
- v.strip!
109
- h[k.downcase] = [k, v]
110
- end
111
-
112
- if h['status']
113
- status = h['status'][1].to_i
114
- h.delete 'status'
115
- else
116
- status = 200
117
- end
118
-
119
- header_hash = Hash[h.values]
120
-
121
- [status, header_hash, [content]]
122
- end
123
-
124
- def report_error code, out, err, cgi_env
125
- h = {'Content-Type' => 'text/plain'}
126
- status = 500
127
- reports = []
128
-
129
- reports << "CGI Error!\n\n"
130
- reports << "stdout output:\n"
131
- reports << out
132
- reports << "\n"
133
- reports << "stderr output:\n"
134
- reports << err
135
- reports << "\n"
136
- reports << "environments:\n"
137
- cgi_env.each do |k, v|
138
- reports << "#{k} => #{v}\n"
139
- end
140
-
141
- [status, h, reports]
142
- end
143
-
144
- def call(env)
145
- path = solve_path env["PATH_INFO"]
146
- if not path
147
- return @app.call(env)
148
- end
149
-
150
- rule = match_cgi_rule path
151
- if not rule
152
- return @app.call(env)
153
- end
154
-
155
- cgi_env = cgi_env(env, path)
156
- code, out, err = run_cgi rule, path, cgi_env
157
- if code == 0
158
- parse_output out
159
- else
160
- report_error code, out, err, cgi_env
161
- end
162
- end
163
- end
164
- end
165
-
1
+ require_relative 'rack/cgi'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rack-cgi
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.3
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Chizhong Jin