knjrbfw 0.0.21 → 0.0.22
Sign up to get free protection for your applications and to get access to all the features.
- data/VERSION +1 -1
- data/knjrbfw.gemspec +2 -2
- data/lib/knj/arrayext.rb +17 -3
- data/lib/knj/cmd_parser.rb +26 -4
- data/lib/knj/csv.rb +3 -0
- data/lib/knj/datarow.rb +19 -4
- data/lib/knj/datet.rb +1 -1
- data/lib/knj/gettext_threadded.rb +2 -2
- data/lib/knj/google_sitemap.rb +57 -18
- data/lib/knj/http2.rb +100 -56
- data/lib/knj/knjdb/drivers/mysql/knjdb_mysql.rb +10 -5
- data/lib/knj/knjdb/drivers/mysql/knjdb_mysql_columns.rb +1 -1
- data/lib/knj/knjdb/drivers/mysql/knjdb_mysql_indexes.rb +11 -1
- data/lib/knj/knjdb/drivers/mysql/knjdb_mysql_tables.rb +0 -2
- data/lib/knj/knjdb/libknjdb.rb +41 -1
- data/lib/knj/knjdb/revision.rb +9 -2
- data/lib/knj/locales.rb +16 -9
- data/lib/knj/objects.rb +83 -61
- data/lib/knj/objects/objects_sqlhelper.rb +1 -1
- data/lib/knj/os.rb +5 -1
- data/lib/knj/php.rb +2 -0
- data/lib/knj/process_meta.rb +149 -14
- data/lib/knj/scripts/process_meta_exec.rb +36 -2
- data/lib/knj/unix_proc.rb +42 -33
- data/lib/knj/web.rb +34 -12
- data/lib/knj/wref.rb +4 -2
- metadata +15 -15
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0.
|
1
|
+
0.0.22
|
data/knjrbfw.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{knjrbfw}
|
8
|
-
s.version = "0.0.
|
8
|
+
s.version = "0.0.22"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Kasper Johansen"]
|
12
|
-
s.date = %q{2012-03-
|
12
|
+
s.date = %q{2012-03-16}
|
13
13
|
s.description = %q{Including stuff for HTTP, SSH and much more.}
|
14
14
|
s.email = %q{k@spernj.org}
|
15
15
|
s.extra_rdoc_files = [
|
data/lib/knj/arrayext.rb
CHANGED
@@ -79,10 +79,24 @@ module Knj::ArrayExt
|
|
79
79
|
end
|
80
80
|
end
|
81
81
|
|
82
|
-
adds
|
83
|
-
|
82
|
+
hash_given.merge!(adds)
|
83
|
+
|
84
|
+
return hash_given
|
85
|
+
end
|
86
|
+
|
87
|
+
#Converts all keys in the given hash to strings.
|
88
|
+
def self.hash_str(hash_given)
|
89
|
+
adds = {}
|
90
|
+
|
91
|
+
hash_given.each do |key, val|
|
92
|
+
if !key.is_a?(String)
|
93
|
+
adds[key.to_s] = val
|
94
|
+
hash_given.delete(key)
|
95
|
+
end
|
84
96
|
end
|
85
97
|
|
98
|
+
hash_given.merge!(adds)
|
99
|
+
|
86
100
|
return hash_given
|
87
101
|
end
|
88
102
|
|
@@ -201,7 +215,7 @@ module Knj::ArrayExt
|
|
201
215
|
Knj::Php.foreach(hash) do |key, val|
|
202
216
|
if val.is_a?(String)
|
203
217
|
begin
|
204
|
-
hash[key] = Knj::Php.utf8_encode(
|
218
|
+
hash[key] = Knj::Php.utf8_encode(val)
|
205
219
|
rescue Encoding::UndefinedConversionError => e
|
206
220
|
if args["ignore_encoding_errors"]
|
207
221
|
next
|
data/lib/knj/cmd_parser.rb
CHANGED
@@ -4,15 +4,37 @@ class Knj::Cmd_parser
|
|
4
4
|
|
5
5
|
str.lines.each do |line|
|
6
6
|
next if line.match(/^total ([\d\.,]+)(M|k|G|)$/)
|
7
|
-
match = line.match(/^(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)\s+(\d+)\s+(.+)\s+([^\W].+?)\s+([\d\.,]+)(M|k|G|K|)\s+((\d+)-(\d+)-(\d+)|(([A-z]{3})\s+(\d+)))\s+(\d+):(\d+)\s+(.+)$/)
|
7
|
+
match = line.match(/^(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)\s+(\d+)\s+(.+)\s+([^\W].+?)\s+([\d\.,]+)(M|k|G|K|)\s+((\d+)-(\d+)-(\d+)|(([A-z]{3})\s+(\d+)))\s+((\d+):(\d+)|(\d{4}))\s+(.+)$/)
|
8
8
|
raise "Could not match: '#{line}'." if !match
|
9
9
|
|
10
|
+
year = nil
|
11
|
+
|
12
|
+
if match[17].to_i > 0
|
13
|
+
year = match[17].to_i
|
14
|
+
elsif match[26].to_i > 0
|
15
|
+
year = match[26].to_i
|
16
|
+
end
|
17
|
+
|
18
|
+
hour = match[24].to_i
|
19
|
+
min = match[25].to_i
|
20
|
+
|
10
21
|
if match[17] and match[18] and match[19]
|
11
|
-
|
22
|
+
month = match[18].to_i
|
23
|
+
date = match[19].to_i
|
12
24
|
elsif match[20] and match[21] and match[22]
|
13
|
-
|
25
|
+
month = Knj::Datet.month_str_to_no(match[21])
|
26
|
+
date = match[22].to_i
|
27
|
+
end
|
28
|
+
|
29
|
+
if !year
|
30
|
+
if month > Time.now.month
|
31
|
+
year = Time.now.year - 1
|
32
|
+
else
|
33
|
+
year = Time.now.year
|
34
|
+
end
|
14
35
|
end
|
15
36
|
|
37
|
+
time = Time.local(year, month, date, hour, min)
|
16
38
|
bytes = match[14].gsub(",", ".").to_f
|
17
39
|
|
18
40
|
size_match = match[15]
|
@@ -50,7 +72,7 @@ class Knj::Cmd_parser
|
|
50
72
|
:grp => match[13],
|
51
73
|
:size => bytes.to_i,
|
52
74
|
:time => time,
|
53
|
-
:file => match[
|
75
|
+
:file => match[27]
|
54
76
|
}
|
55
77
|
end
|
56
78
|
|
data/lib/knj/csv.rb
CHANGED
data/lib/knj/datarow.rb
CHANGED
@@ -11,6 +11,11 @@ class Knj::Datarow
|
|
11
11
|
return @depending_data
|
12
12
|
end
|
13
13
|
|
14
|
+
def self.autodelete_data
|
15
|
+
@autodelete_data = [] if !@autodelete_data
|
16
|
+
return @autodelete_data
|
17
|
+
end
|
18
|
+
|
14
19
|
#This helps various parts of the framework determine if this is a datarow class without requiring it.
|
15
20
|
def is_knj?
|
16
21
|
return true
|
@@ -33,7 +38,14 @@ class Knj::Datarow
|
|
33
38
|
methodname = val[:method]
|
34
39
|
|
35
40
|
if val[:depends]
|
36
|
-
depending_data << {
|
41
|
+
self.depending_data << {
|
42
|
+
:colname => colname,
|
43
|
+
:classname => classname
|
44
|
+
}
|
45
|
+
end
|
46
|
+
|
47
|
+
if val[:autodelete]
|
48
|
+
self.autodelete_data << {
|
37
49
|
:colname => colname,
|
38
50
|
:classname => classname
|
39
51
|
}
|
@@ -106,7 +118,7 @@ class Knj::Datarow
|
|
106
118
|
|
107
119
|
if val[:required]
|
108
120
|
colname = "#{classname.to_s.downcase}_id".to_sym if !colname
|
109
|
-
required_data << {
|
121
|
+
self.required_data << {
|
110
122
|
:col => colname,
|
111
123
|
:class => classname
|
112
124
|
}
|
@@ -378,6 +390,7 @@ class Knj::Datarow
|
|
378
390
|
sql = "SELECT #{table_str}.*"
|
379
391
|
end
|
380
392
|
|
393
|
+
qargs = nil
|
381
394
|
ret = self.list_helper(d)
|
382
395
|
|
383
396
|
sql << " FROM #{table_str}"
|
@@ -389,6 +402,8 @@ class Knj::Datarow
|
|
389
402
|
case key
|
390
403
|
when "return_sql"
|
391
404
|
#ignore
|
405
|
+
when :cloned_ubuf
|
406
|
+
qargs = {:cloned_ubuf => true}
|
392
407
|
else
|
393
408
|
raise "Invalid key: '#{key}' for '#{self.name}'. Valid keys are: '#{@columns_sqlhelper_args[:cols].keys.sort}'."
|
394
409
|
end
|
@@ -418,7 +433,7 @@ class Knj::Datarow
|
|
418
433
|
|
419
434
|
if select_col_as_array
|
420
435
|
ids = [] if !block
|
421
|
-
d.db.q(sql) do |data|
|
436
|
+
d.db.q(sql, qargs) do |data|
|
422
437
|
if block
|
423
438
|
block.call(data[:id])
|
424
439
|
else
|
@@ -437,7 +452,7 @@ class Knj::Datarow
|
|
437
452
|
return 0
|
438
453
|
end
|
439
454
|
|
440
|
-
return d.ob.list_bysql(self.classname, sql, &block)
|
455
|
+
return d.ob.list_bysql(self.classname, sql, qargs, &block)
|
441
456
|
end
|
442
457
|
|
443
458
|
def self.list_helper(d)
|
data/lib/knj/datet.rb
CHANGED
@@ -129,7 +129,7 @@ class Knj::Datet
|
|
129
129
|
#Is a year a leap year in the Gregorian calendar? Copied from Date-class.
|
130
130
|
def self.gregorian_leap?(y)
|
131
131
|
if Date.respond_to?("gregorian_leap?")
|
132
|
-
return Date.gregorian_leap?
|
132
|
+
return Date.gregorian_leap?(y)
|
133
133
|
elsif y % 4 == 0 && y % 100 != 0
|
134
134
|
return true
|
135
135
|
elsif y % 400 == 0
|
@@ -30,11 +30,11 @@ class Knj::Gettext_threadded
|
|
30
30
|
|
31
31
|
cont = nil
|
32
32
|
File.open(pofn, {:encoding => @args[:encoding]}) do |fp|
|
33
|
-
cont = fp.read
|
33
|
+
cont = fp.read.encode("utf-8")
|
34
34
|
end
|
35
35
|
|
36
36
|
cont.scan(/msgid\s+\"(.+)\"\nmsgstr\s+\"(.+)\"\n\n/) do |match|
|
37
|
-
@langs[file][match[0]] = match[1]
|
37
|
+
@langs[file][match[0]] = match[1].to_s.encode("utf-8")
|
38
38
|
end
|
39
39
|
end
|
40
40
|
end
|
data/lib/knj/google_sitemap.rb
CHANGED
@@ -2,58 +2,97 @@ class Knj::Google_sitemap
|
|
2
2
|
attr_reader :doc
|
3
3
|
|
4
4
|
def initialize(args = {})
|
5
|
+
raise "No block given." if !block_given?
|
6
|
+
|
5
7
|
@args = args
|
6
8
|
|
7
9
|
#used for Time.iso8601.
|
8
10
|
require "time"
|
9
11
|
|
10
|
-
|
11
|
-
@
|
12
|
+
#REXML is known to leak memory - use subprocess.
|
13
|
+
@subproc = Knj::Process_meta.new("id" => "google_sitemap", "debug_err" => true)
|
12
14
|
|
13
|
-
|
14
|
-
|
15
|
+
begin
|
16
|
+
@subproc.static("Object", "require", "rexml/rexml")
|
17
|
+
@subproc.static("Object", "require", "rexml/document")
|
18
|
+
|
19
|
+
@doc = @subproc.new("REXML::Document")
|
20
|
+
|
21
|
+
xmldecl = @subproc.new("REXML::XMLDecl", "1.0", "UTF-8")
|
22
|
+
@doc._pm_send_noret("<<", xmldecl)
|
23
|
+
|
24
|
+
urlset = @subproc.proxy_from_call(@doc, "add_element", "urlset")
|
25
|
+
urlset._pm_send_noret("add_attributes", {"xmlns" => "http://www.sitemaps.org/schemas/sitemap/0.9"})
|
26
|
+
|
27
|
+
@root = @subproc.proxy_from_call(@doc, "root")
|
28
|
+
yield(self)
|
29
|
+
ensure
|
30
|
+
@doc = nil
|
31
|
+
@root = nil
|
32
|
+
@subproc.destroy
|
33
|
+
@subproc = nil
|
34
|
+
end
|
15
35
|
end
|
16
36
|
|
17
37
|
def add_url(url_value, lastmod_value, cf_value = nil, priority_value = nil)
|
18
|
-
el = REXML::Element.new("url")
|
19
|
-
|
20
|
-
loc = el.add_element("loc")
|
21
|
-
loc.text = url_value
|
22
|
-
|
23
38
|
if !lastmod_value or lastmod_value.to_i == 0
|
24
39
|
raise sprintf("Invalid date: %1$s, url: %2$s", lastmod_value.to_s, url_value)
|
25
40
|
end
|
26
41
|
|
27
|
-
|
42
|
+
el = @subproc.new("REXML::Element", "url")
|
43
|
+
|
44
|
+
loc = @subproc.proxy_from_call(el, "add_element", "loc")
|
45
|
+
loc._pm_send_noret("text=", url_value)
|
46
|
+
|
47
|
+
lm = @subproc.proxy_from_call(el, "add_element", "lastmod")
|
28
48
|
if @args.key?(:date_min) and @args[:date_min] > lastmod_value
|
29
49
|
lastmod_value = @args[:date_min]
|
30
50
|
end
|
31
51
|
|
32
|
-
lm.text
|
52
|
+
lm._pm_send_noret("text=", lastmod_value.iso8601)
|
33
53
|
|
34
54
|
if cf_value
|
35
|
-
cf =
|
36
|
-
cf.text
|
55
|
+
cf = @subproc.proxy_from_call(el, "add_element", "changefreq")
|
56
|
+
cf._pm_send_noret("text=", cf_value)
|
37
57
|
end
|
38
58
|
|
39
59
|
if priority_value
|
40
|
-
priority =
|
41
|
-
priority.text
|
60
|
+
priority = @subproc.proxy_from_call("el", "add_element", "priority")
|
61
|
+
priority._pm_send_noret("text=", priority_value)
|
42
62
|
end
|
43
63
|
|
44
|
-
@
|
64
|
+
@root._pm_send_noret("<<", el)
|
45
65
|
end
|
46
66
|
|
67
|
+
#This will return a non-human-readable XML-string.
|
47
68
|
def to_xml
|
48
69
|
return @doc.to_s
|
49
70
|
end
|
50
71
|
|
72
|
+
#This will return a non-human-readable XML-string.
|
51
73
|
def to_s
|
52
74
|
return @doc.to_s
|
53
75
|
end
|
54
76
|
|
77
|
+
#This will print the result.
|
55
78
|
def write
|
56
|
-
|
57
|
-
|
79
|
+
#Require and spawn StringIO in the subprocess.
|
80
|
+
@subproc.static("Object", "require", "stringio")
|
81
|
+
string_io = @subproc.spawn_object("StringIO")
|
82
|
+
|
83
|
+
#We want a human-readable print.
|
84
|
+
writer = @subproc.spawn_object("REXML::Formatters::Pretty", 5)
|
85
|
+
writer._pm_send_noret("write", @doc, string_io)
|
86
|
+
|
87
|
+
#Prepare printing by rewinding StringIO to read from beginning.
|
88
|
+
string_io._pm_send_noret("rewind")
|
89
|
+
|
90
|
+
#Buffer results from subprocess in order to speed up printing.
|
91
|
+
string_io._process_meta_block_buffer_use = true
|
92
|
+
|
93
|
+
#Print out the result in bits to avoid raping the memory (subprocess is already raped - no question there...).
|
94
|
+
string_io._pm_send_noret("each", 4096) do |str|
|
95
|
+
print str
|
96
|
+
end
|
58
97
|
end
|
59
98
|
end
|
data/lib/knj/http2.rb
CHANGED
@@ -33,6 +33,14 @@ class Knj::Http2
|
|
33
33
|
|
34
34
|
raise "No host was given." if !@args[:host]
|
35
35
|
self.reconnect
|
36
|
+
|
37
|
+
if block_given?
|
38
|
+
begin
|
39
|
+
yield(self)
|
40
|
+
ensure
|
41
|
+
self.destroy
|
42
|
+
end
|
43
|
+
end
|
36
44
|
end
|
37
45
|
|
38
46
|
def socket_working?
|
@@ -49,6 +57,25 @@ class Knj::Http2
|
|
49
57
|
return true
|
50
58
|
end
|
51
59
|
|
60
|
+
def destroy
|
61
|
+
@args = nil
|
62
|
+
@cookies = nil
|
63
|
+
@debug = nil
|
64
|
+
@mutex = nil
|
65
|
+
@uagent = nil
|
66
|
+
@keepalive_timeout = nil
|
67
|
+
@request_last = nil
|
68
|
+
|
69
|
+
@sock.close if @sock and !@sock.closed?
|
70
|
+
@sock = nil
|
71
|
+
|
72
|
+
@sock_plain.close if @sock_plain and !@sock_plain.closed?
|
73
|
+
@sock_plain = nil
|
74
|
+
|
75
|
+
@sock_ssl.close if @sock_ssl and !@sock_ssl.closed?
|
76
|
+
@sock_ssl = nil
|
77
|
+
end
|
78
|
+
|
52
79
|
#Reconnects to the host.
|
53
80
|
def reconnect
|
54
81
|
print "Http2: Reconnect.\n" if @debug
|
@@ -106,19 +133,25 @@ class Knj::Http2
|
|
106
133
|
end
|
107
134
|
|
108
135
|
def get(addr, args = {})
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
136
|
+
begin
|
137
|
+
@mutex.synchronize do
|
138
|
+
header_str = "GET /#{addr} HTTP/1.1#{@nl}"
|
139
|
+
header_str << self.header_str(self.default_headers(args), args)
|
140
|
+
header_str << "#{@nl}"
|
141
|
+
|
142
|
+
print "Http2: Writing headers.\n" if @debug
|
143
|
+
self.write(header_str)
|
144
|
+
|
145
|
+
print "Http2: Reading response.\n" if @debug
|
146
|
+
resp = self.read_response(args)
|
147
|
+
|
148
|
+
print "Http2: Done with get request.\n" if @debug
|
149
|
+
return resp
|
150
|
+
end
|
151
|
+
rescue Knj::Errors::Retry => e
|
152
|
+
print "Redirecting to: #{e.message}\n"
|
119
153
|
|
120
|
-
|
121
|
-
return resp
|
154
|
+
return self.get(e.message, args)
|
122
155
|
end
|
123
156
|
end
|
124
157
|
|
@@ -159,59 +192,67 @@ class Knj::Http2
|
|
159
192
|
end
|
160
193
|
|
161
194
|
def post(addr, pdata = {}, args = {})
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
195
|
+
begin
|
196
|
+
@mutex.synchronize do
|
197
|
+
praw = ""
|
198
|
+
pdata.each do |key, val|
|
199
|
+
praw << "&" if praw != ""
|
200
|
+
praw << "#{Knj::Web.urlenc(key)}=#{Knj::Web.urlenc(val)}"
|
201
|
+
end
|
202
|
+
|
203
|
+
header_str = "POST /#{addr} HTTP/1.1#{@nl}"
|
204
|
+
header_str << self.header_str(self.default_headers(args).merge("Content-Length" => praw.length), args)
|
205
|
+
header_str << "#{@nl}"
|
206
|
+
header_str << praw
|
207
|
+
|
208
|
+
self.write(header_str)
|
209
|
+
return self.read_response(args)
|
167
210
|
end
|
168
|
-
|
169
|
-
|
170
|
-
header_str << self.header_str(self.default_headers(args).merge("Content-Length" => praw.length), args)
|
171
|
-
header_str << "#{@nl}"
|
172
|
-
header_str << praw
|
173
|
-
|
174
|
-
self.write(header_str)
|
175
|
-
return self.read_response(args)
|
211
|
+
rescue Knj::Errors::Retry => e
|
212
|
+
return self.get(e.message, args)
|
176
213
|
end
|
177
214
|
end
|
178
215
|
|
179
216
|
def post_multipart(addr, pdata, args = {})
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
praw = ""
|
184
|
-
pdata.each do |key, val|
|
185
|
-
praw << "--#{boundary}#{@nl}"
|
217
|
+
begin
|
218
|
+
@mutex.synchronize do
|
219
|
+
boundary = Digest::MD5.hexdigest(Time.now.to_f.to_s)
|
186
220
|
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
221
|
+
praw = ""
|
222
|
+
pdata.each do |key, val|
|
223
|
+
praw << "--#{boundary}#{@nl}"
|
224
|
+
|
225
|
+
if val.class.name == "Tempfile" and val.respond_to?("original_filename")
|
226
|
+
praw << "Content-Disposition: form-data; name=\"#{key}\"; filename=\"#{val.original_filename}\";#{@nl}"
|
227
|
+
else
|
228
|
+
praw << "Content-Disposition: form-data; name=\"#{key}\";#{@nl}"
|
229
|
+
end
|
230
|
+
|
231
|
+
praw << "Content-Type: text/plain#{@nl}"
|
232
|
+
praw << "Content-Length: #{val.length}#{@nl}"
|
233
|
+
praw << @nl
|
234
|
+
|
235
|
+
if val.is_a?(StringIO)
|
236
|
+
praw << val.read
|
237
|
+
else
|
238
|
+
praw << val.to_s
|
239
|
+
end
|
240
|
+
|
241
|
+
praw << @nl
|
191
242
|
end
|
192
243
|
|
193
|
-
|
194
|
-
|
195
|
-
|
244
|
+
header_str = "POST /#{addr} HTTP/1.1#{@nl}"
|
245
|
+
header_str << "Content-Type: multipart/form-data; boundary=#{boundary}#{@nl}"
|
246
|
+
header_str << self.header_str(self.default_headers(args).merge("Content-Length" => praw.length), args)
|
247
|
+
header_str << "#{@nl}"
|
248
|
+
header_str << praw
|
249
|
+
header_str << "--#{boundary}--"
|
196
250
|
|
197
|
-
|
198
|
-
|
199
|
-
else
|
200
|
-
praw << val.to_s
|
201
|
-
end
|
202
|
-
|
203
|
-
praw << @nl
|
251
|
+
self.write(header_str)
|
252
|
+
return self.read_response(args)
|
204
253
|
end
|
205
|
-
|
206
|
-
|
207
|
-
header_str << "Content-Type: multipart/form-data; boundary=#{boundary}#{@nl}"
|
208
|
-
header_str << self.header_str(self.default_headers(args).merge("Content-Length" => praw.length), args)
|
209
|
-
header_str << "#{@nl}"
|
210
|
-
header_str << praw
|
211
|
-
header_str << "--#{boundary}--"
|
212
|
-
|
213
|
-
self.write(header_str)
|
214
|
-
return self.read_response(args)
|
254
|
+
rescue Knj::Errors::Retry => e
|
255
|
+
return self.get(e.message, args)
|
215
256
|
end
|
216
257
|
end
|
217
258
|
|
@@ -313,13 +354,15 @@ class Knj::Http2
|
|
313
354
|
args[:port] = uri.port if uri.port
|
314
355
|
|
315
356
|
if !args[:host] or args[:host] == @args[:host]
|
316
|
-
|
357
|
+
raise Knj::Errors::Retry, resp.header("location")
|
317
358
|
else
|
318
359
|
http = Knj::Http2.new(args)
|
319
360
|
return http.get(uri.path)
|
320
361
|
end
|
321
362
|
elsif resp.args[:code].to_s == "500"
|
322
363
|
raise "500 - Internal server error."
|
364
|
+
elsif resp.args[:code].to_s == "403"
|
365
|
+
raise Knj::Errors::NoAccess
|
323
366
|
else
|
324
367
|
return resp
|
325
368
|
end
|
@@ -428,6 +471,7 @@ class Knj::Http2::Response
|
|
428
471
|
return @args[:headers][key].first.to_s
|
429
472
|
end
|
430
473
|
|
474
|
+
#Returns true if a header of the given string exists.
|
431
475
|
def header?(key)
|
432
476
|
return true if @args[:headers].key?(key) and @args[:headers][key].first.to_s.length > 0
|
433
477
|
return false
|