knjrbfw 0.0.7 → 0.0.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (65) hide show
  1. data/Gemfile +3 -1
  2. data/VERSION +1 -1
  3. data/knjrbfw.gemspec +14 -4
  4. data/lib/knj/amixer.rb +148 -0
  5. data/lib/knj/arrayext.rb +14 -5
  6. data/lib/knj/autoload.rb +63 -57
  7. data/lib/knj/autoload/backups/facets_dictionary.rb +2 -2
  8. data/lib/knj/autoload/erubis.rb +2 -0
  9. data/lib/knj/cmd_gen.rb +71 -0
  10. data/lib/knj/compiler.rb +2 -2
  11. data/lib/knj/datarow.rb +138 -38
  12. data/lib/knj/datestamp.rb +2 -2
  13. data/lib/knj/datet.rb +72 -17
  14. data/lib/knj/erb/include.rb +5 -5
  15. data/lib/knj/errors.rb +4 -1
  16. data/lib/knj/eruby.rb +25 -11
  17. data/lib/knj/event_filemod.rb +27 -26
  18. data/lib/knj/event_handler.rb +8 -8
  19. data/lib/knj/exchangerates.rb +1 -1
  20. data/lib/knj/facebook_connect.rb +37 -0
  21. data/lib/knj/gettext_threadded.rb +4 -3
  22. data/lib/knj/google_sitemap.rb +1 -1
  23. data/lib/knj/hash_methods.rb +1 -1
  24. data/lib/knj/http.rb +35 -19
  25. data/lib/knj/http2.rb +249 -0
  26. data/lib/knj/image.rb +128 -0
  27. data/lib/knj/jruby-gtk2/gtk2.rb +1 -1
  28. data/lib/knj/knj.rb +1 -1
  29. data/lib/knj/knj_controller.rb +0 -2
  30. data/lib/knj/knjdb/drivers/mysql/knjdb_mysql.rb +3 -3
  31. data/lib/knj/knjdb/drivers/mysql/knjdb_mysql_columns.rb +11 -11
  32. data/lib/knj/knjdb/drivers/mysql/knjdb_mysql_tables.rb +2 -2
  33. data/lib/knj/knjdb/drivers/sqlite3/knjdb_sqlite3.rb +71 -14
  34. data/lib/knj/knjdb/drivers/sqlite3/knjdb_sqlite3_columns.rb +17 -14
  35. data/lib/knj/knjdb/drivers/sqlite3/knjdb_sqlite3_tables.rb +5 -5
  36. data/lib/knj/knjdb/libknjdb.rb +33 -16
  37. data/lib/knj/knjdb/libknjdb_row.rb +8 -8
  38. data/lib/knj/maemo/fremantle-calendar/fremantle-calendar.rb +1 -1
  39. data/lib/knj/mount.rb +6 -6
  40. data/lib/knj/mutexcl.rb +2 -2
  41. data/lib/knj/objects.rb +286 -73
  42. data/lib/knj/opts.rb +11 -4
  43. data/lib/knj/os.rb +16 -3
  44. data/lib/knj/php.rb +73 -26
  45. data/lib/knj/php_parser/php_parser.rb +1 -77
  46. data/lib/knj/retry.rb +4 -4
  47. data/lib/knj/rhodes/rhodes.rb +106 -0
  48. data/lib/knj/sshrobot/sshrobot.rb +1 -1
  49. data/lib/knj/strings.rb +72 -0
  50. data/lib/knj/sysuser.rb +1 -1
  51. data/lib/knj/tests/test_http2.rb +18 -0
  52. data/lib/knj/thread.rb +1 -5
  53. data/lib/knj/thread2.rb +3 -3
  54. data/lib/knj/threadhandler.rb +2 -2
  55. data/lib/knj/threadpool.rb +4 -4
  56. data/lib/knj/translations.rb +2 -17
  57. data/lib/knj/unix_proc.rb +3 -3
  58. data/lib/knj/web.rb +156 -77
  59. data/lib/knj/webscripts/image.rhtml +22 -3
  60. data/lib/knj/x11vnc.rb +3 -3
  61. data/spec/amixer_spec.rb +27 -0
  62. data/spec/knjrbfw_spec.rb +70 -12
  63. data/testfiles/image.jpg +0 -0
  64. metadata +32 -14
  65. data/Gemfile.lock +0 -32
@@ -164,7 +164,7 @@ class KnjEruby < Erubis::Eruby
164
164
  end
165
165
 
166
166
  if !args[:custom_io]
167
- print self.print_headers if !args.has_key?(:with_headers) or args[:with_headers]
167
+ print self.print_headers if !args.key?(:with_headers) or args[:with_headers]
168
168
  tmp_out.rewind
169
169
  print tmp_out.read
170
170
  end
@@ -216,7 +216,7 @@ class KnjEruby < Erubis::Eruby
216
216
  rescue Exception => e
217
217
  #An error occurred while trying to run the on-error-block - show this as an normal error.
218
218
  print "\n\n<pre>\n\n"
219
- print "<b>#{CGI.escapeHTML(e.class.name)}: #{CGI.escapeHTML(e.message)}</b>\n\n"
219
+ print "<b>#{Knj::Web.html(e.class.name)}: #{Knj::Web.html(e.message)}</b>\n\n"
220
220
 
221
221
  #Lets hide all the stuff in what is not the users files to make it easier to debug.
222
222
  bt = e.backtrace
@@ -224,14 +224,14 @@ class KnjEruby < Erubis::Eruby
224
224
  #bt = bt[0..to]
225
225
 
226
226
  bt.each do |line|
227
- print CGI.escapeHTML(line) + "\n"
227
+ print Knj::Web.html(line) + "\n"
228
228
  end
229
229
 
230
230
  print "</pre>"
231
231
  end
232
232
 
233
233
  print "\n\n<pre>\n\n"
234
- print "<b>#{CGI.escapeHTML(e.class.name)}: #{CGI.escapeHTML(e.message)}</b>\n\n"
234
+ print "<b>#{Knj::Web.html(e.class.name)}: #{Knj::Web.html(e.message)}</b>\n\n"
235
235
 
236
236
  #Lets hide all the stuff in what is not the users files to make it easier to debug.
237
237
  bt = e.backtrace
@@ -239,7 +239,7 @@ class KnjEruby < Erubis::Eruby
239
239
  bt = bt[0..to]
240
240
 
241
241
  bt.each do |line|
242
- print CGI.escapeHTML(line) + "\n"
242
+ print Knj::Web.html(line) + "\n"
243
243
  end
244
244
 
245
245
  KnjEruby.printcont(tmp_out, args)
@@ -4,13 +4,16 @@ module Knj::Errors
4
4
  class InvalidData < StandardError; end
5
5
  class Retry < StandardError; end
6
6
  class NoAccess < StandardError; end
7
+ class Exists < StandardError; end
7
8
 
8
9
  def self.error_str(err, args = {})
10
+ str = ""
11
+
9
12
  if args[:html]
10
13
  str += "<b>#{err.class.name}</b>: #{err.message}<br />\n<br />\n"
11
14
  str += err.backtrace.join("<br />\n")
12
15
  else
13
- str = "#{err.class.name}: #{err.message}\n\n"
16
+ str += "#{err.class.name}: #{err.message}\n\n"
14
17
  str += err.backtrace.join("\n")
15
18
  end
16
19
 
@@ -1,6 +1,6 @@
1
1
  class Knj::Eruby
2
2
  attr_reader :fcgi
3
- attr_reader :connects, :headers
3
+ attr_reader :connects, :headers, :cookies
4
4
 
5
5
  def initialize(args = {})
6
6
  @args = args
@@ -26,6 +26,7 @@ class Knj::Eruby
26
26
  end
27
27
 
28
28
  if @cache_mode == :compile_knj
29
+ require "knj/compiler"
29
30
  @compiler = Knj::Compiler.new(:cache_hash => @cache)
30
31
  end
31
32
 
@@ -46,7 +47,7 @@ class Knj::Eruby
46
47
  Knj::Eruby::Handler.load_file(filename, {:cachename => cachename})
47
48
  cachetime = File.mtime(cachename)
48
49
  reload_cache = true
49
- elsif !@cache.has_key?(cachename)
50
+ elsif !@cache.key?(cachename)
50
51
  reload_cache = true
51
52
  end
52
53
 
@@ -60,7 +61,7 @@ class Knj::Eruby
60
61
  if reload_cache or @cache[cachename][:time] < cachetime
61
62
  @cache[cachename] = {
62
63
  :inseq => RubyVM::InstructionSequence.compile(File.read(cachename), filename, nil, 1),
63
- :time => Time.new
64
+ :time => Time.now
64
65
  }
65
66
  end
66
67
 
@@ -79,13 +80,15 @@ class Knj::Eruby
79
80
  def destroy
80
81
  @connects.clear if @connects.is_a?(Hash)
81
82
  @headers.clear if @headers.is_a?(Array)
83
+ @cookies.clear if @cookies.is_a?(Array)
82
84
 
83
- @cache.clear if @cache.is_a?(Hash) and @args and !@args.has_key?(:cache_hash)
85
+ @cache.clear if @cache.is_a?(Hash) and @args and !@args.key?(:cache_hash)
84
86
  @args.clear if @args.is_a?(Hash)
85
87
  @args = nil
86
88
  @cache = nil
87
89
  @connects = nil
88
90
  @headers = nil
91
+ @cookies = nil
89
92
  end
90
93
 
91
94
  def print_headers(args = {})
@@ -95,6 +98,10 @@ class Knj::Eruby
95
98
  header_str += "#{header[0]}: #{header[1]}\n"
96
99
  end
97
100
 
101
+ @cookies.each do |cookie|
102
+ header_str += "Set-Cookie: #{Knj::Web.cookie_str(cookie)}\n"
103
+ end
104
+
98
105
  header_str += "\n"
99
106
  self.reset_headers if @fcgi
100
107
  return header_str
@@ -114,14 +121,19 @@ class Knj::Eruby
114
121
 
115
122
  def reset_headers
116
123
  @headers = []
124
+ @cookies = []
117
125
  end
118
126
 
119
127
  def header(key, value)
120
128
  @headers << [key, value]
121
129
  end
122
130
 
131
+ def cookie(cookie_data)
132
+ @cookies << cookie_data
133
+ end
134
+
123
135
  def connect(signal, &block)
124
- @connects[signal] = [] if !@connects.has_key?(signal)
136
+ @connects[signal] = [] if !@connects.key?(signal)
125
137
  @connects[signal] << block
126
138
  end
127
139
 
@@ -139,7 +151,7 @@ class Knj::Eruby
139
151
  end
140
152
 
141
153
  if !args[:custom_io]
142
- print self.print_headers if !args.has_key?(:with_headers) or args[:with_headers]
154
+ print self.print_headers if !args.key?(:with_headers) or args[:with_headers]
143
155
  tmp_out.rewind
144
156
  print tmp_out.read
145
157
  end
@@ -186,7 +198,7 @@ class Knj::Eruby
186
198
 
187
199
  def handle_error(e)
188
200
  begin
189
- if @connects and @connects.has_key?("error")
201
+ if @connects and @connects.key?("error")
190
202
  @connects["error"].each do |block|
191
203
  block.call(e)
192
204
  end
@@ -196,7 +208,7 @@ class Knj::Eruby
196
208
  rescue Exception => e
197
209
  #An error occurred while trying to run the on-error-block - show this as an normal error.
198
210
  print "\n\n<pre>\n\n"
199
- print "<b>#{CGI.escapeHTML(e.class.name)}: #{CGI.escapeHTML(e.message)}</b>\n\n"
211
+ print "<b>#{Knj::Web.html(e.class.name)}: #{Knj::Web.html(e.message)}</b>\n\n"
200
212
 
201
213
  #Lets hide all the stuff in what is not the users files to make it easier to debug.
202
214
  bt = e.backtrace
@@ -204,18 +216,20 @@ class Knj::Eruby
204
216
  #bt = bt[0..to]
205
217
 
206
218
  bt.each do |line|
207
- print CGI.escapeHTML(line) + "\n"
219
+ print Knj::Web.html(line) + "\n"
208
220
  end
209
221
 
210
222
  print "</pre>"
211
223
  end
212
224
 
213
225
  print "\n\n<pre>\n\n"
214
- print "<b>#{CGI.escapeHTML(e.class.name)}: #{CGI.escapeHTML(e.message)}</b>\n\n"
226
+ print "<b>#{Knj::Web.html(e.class.name)}: #{Knj::Web.html(e.message)}</b>\n\n"
215
227
 
216
228
  e.backtrace.each do |line|
217
- print CGI.escapeHTML(line) + "\n"
229
+ print Knj::Web.html(line) + "\n"
218
230
  end
231
+
232
+ print "</pre>"
219
233
  end
220
234
  end
221
235
 
@@ -6,7 +6,7 @@ class Knj::Event_filemod
6
6
  @run = true
7
7
  @mutex = Mutex.new
8
8
 
9
- @args[:wait] = 1 if !@args.has_key?(:wait)
9
+ @args[:wait] = 1 if !@args.key?(:wait)
10
10
 
11
11
  @mtimes = {}
12
12
  args[:paths].each do |path|
@@ -18,31 +18,32 @@ class Knj::Event_filemod
18
18
  break if !@args or !@args[:paths] or @args[:paths].empty?
19
19
 
20
20
  @mutex.synchronize do
21
- @args[:paths].each do |path|
22
- changed = false
23
-
24
- if @mtimes and !@mtimes.has_key?(path) and @mtimes.is_a?(Hash)
25
- @mtimes[path] = File.mtime(path)
26
- end
27
-
28
- begin
29
- newdate = File.mtime(path)
30
- rescue Errno::ENOENT
31
- #file does not exist.
32
- changed = true
33
- end
34
-
35
- if !changed and newdate and @mtimes and newdate > @mtimes[path]
36
- changed = true
37
- end
38
-
39
- if changed
40
- block.call(self, path)
41
- @args[:paths].delete(path) if @args and @args[:break_when_changed]
42
- end
43
- end
44
-
45
- sleep @args[:wait] if @args and @run
21
+ @args[:paths].each do |path|
22
+ changed = false
23
+
24
+ if @mtimes and !@mtimes.key?(path) and @mtimes.is_a?(Hash)
25
+ @mtimes[path] = File.mtime(path)
26
+ end
27
+
28
+ begin
29
+ newdate = File.mtime(path)
30
+ rescue Errno::ENOENT
31
+ #file does not exist.
32
+ changed = true
33
+ end
34
+
35
+ if !changed and newdate and @mtimes and newdate > @mtimes[path]
36
+ changed = true
37
+ end
38
+
39
+ if changed
40
+ block.call(self, path)
41
+ @args[:paths].delete(path) if @args and @args[:break_when_changed]
42
+ end
43
+ end
44
+
45
+ sleep @args[:wait] if @args and @run
46
+ end
46
47
  end
47
48
  end
48
49
  end
@@ -7,7 +7,7 @@ class Knj::Event_handler
7
7
  def add_event(event)
8
8
  raise "No name given." if !event[:name]
9
9
 
10
- @events[event[:name]] = [] if !@events.has_key?(event[:name])
10
+ @events[event[:name]] = [] if !@events.key?(event[:name])
11
11
  @events[event[:name]] = {
12
12
  :event => event,
13
13
  :callbacks => {},
@@ -22,11 +22,11 @@ class Knj::Event_handler
22
22
  end
23
23
 
24
24
  def connect(name, &block)
25
- raise "No such event: '#{name}'." if !@events.has_key?(name)
25
+ raise "No such event: '#{name}'." if !@events.key?(name)
26
26
 
27
27
  event = @events[name]
28
28
 
29
- if event[:event].has_key?(:connections_max) and event[:callbacks].length >= event[:event][:connections_max].to_i
29
+ if event[:event].key?(:connections_max) and event[:callbacks].length >= event[:event][:connections_max].to_i
30
30
  raise "The event '#{name}' has reached its maximum connections of '#{event[:event][:connections_max]}'"
31
31
  end
32
32
 
@@ -40,24 +40,24 @@ class Knj::Event_handler
40
40
  end
41
41
 
42
42
  def disconnect(name, callback_id)
43
- raise "No such event: '#{name}'." if !@events.has_key?(name)
44
- raise "No such connection: '#{name}' --> '#{callback_id}'" if !@events[name].has_key?(callback_id)
43
+ raise "No such event: '#{name}'." if !@events.key?(name)
44
+ raise "No such connection: '#{name}' --> '#{callback_id}'" if !@events[name].key?(callback_id)
45
45
  @events[name][callback_id].clear
46
46
  @events[name].delete(callback_id)
47
47
  end
48
48
 
49
49
  def count_connects(name)
50
- raise "No such event." if !@events.has_key?(name)
50
+ raise "No such event." if !@events.key?(name)
51
51
  return @events[name][:callbacks].length
52
52
  end
53
53
 
54
54
  def connected?(name)
55
- raise "No such event." if !@events.has_key?(name)
55
+ raise "No such event." if !@events.key?(name)
56
56
  return !@events[name][:callbacks].empty?
57
57
  end
58
58
 
59
59
  def call(name, *args)
60
- raise "No such event: '#{name}'." if !@events.has_key?(name)
60
+ raise "No such event: '#{name}'." if !@events.key?(name)
61
61
  event = @events[name]
62
62
  ret = nil
63
63
  event[:callbacks].clone.each do |callback_id, callback_hash|
@@ -22,7 +22,7 @@ class Knj::Exchangerates
22
22
  floatval = floatval.to_f
23
23
  locale = locale.to_s
24
24
 
25
- raise "No such locale: '#{locale}' in '#{@rates.keys.join(",")}'." if !@rates.has_key?(locale)
25
+ raise "No such locale: '#{locale}' in '#{@rates.keys.join(",")}'." if !@rates.key?(locale)
26
26
 
27
27
  base_rate = @rates[@base][:rate].to_f
28
28
  cur_rate = @rates[locale][:rate].to_f
@@ -0,0 +1,37 @@
1
+ class Knj::Facebook_connect
2
+ def initialize(args)
3
+ @args = args
4
+
5
+ raise "No app-ID given." if !@args[:app_id]
6
+ raise "No app-secret given." if !@args[:app_secret]
7
+ end
8
+
9
+ def login(args)
10
+ hash = {}
11
+ Knj::Php.parse_str(args[:token], hash)
12
+ hash = Knj::Php.ksort(hash)
13
+
14
+ payload = ""
15
+ hash.each do |key, val|
16
+ next if key == "sig"
17
+ payload += "#{key}=#{val}"
18
+ end
19
+
20
+ raise "Invalid payload or signature." if Digest::MD5.hexdigest("#{payload}#{@args[:app_secret]}") != hash["sig"]
21
+
22
+ http = Knj::Http.new(
23
+ "host" => "graph.facebook.com",
24
+ "ssl" => true
25
+ )
26
+ data = http.get("/me?access_token=#{hash["access_token"]}")
27
+ data = {:access_token => JSON.parse(data["data"])}
28
+
29
+ if args[:profile_picture]
30
+ pic_data = http.get("/#{data[:access_token]["id"]}/picture?type=large")
31
+ pic_obj = Magick::Image.from_blob(pic_data["data"].to_s)[0]
32
+ data[:pic] = pic_obj
33
+ end
34
+
35
+ return data
36
+ end
37
+ end
@@ -40,11 +40,11 @@ class Knj::Gettext_threadded
40
40
  locale = locale.to_s
41
41
  str = str.to_s
42
42
 
43
- if !@langs.has_key?(locale)
43
+ if !@langs.key?(locale)
44
44
  raise "Locale was not found: '#{locale}' in '#{@langs.keys.join(", ")}'."
45
45
  end
46
46
 
47
- return str if !@langs[locale].has_key?(str)
47
+ return str if !@langs[locale].key?(str)
48
48
  return @langs[locale][str]
49
49
  end
50
50
 
@@ -53,6 +53,7 @@ class Knj::Gettext_threadded
53
53
  return trans(locale, str)
54
54
  end
55
55
 
56
+ #Returns a hash with the language ID string as key and the language human-readable-title as value.
56
57
  def lang_opts
57
58
  langs = {}
58
59
  @langs.keys.sort.each do |lang|
@@ -63,7 +64,7 @@ class Knj::Gettext_threadded
63
64
  if File.exists?(title_file_path)
64
65
  title = File.read(title_file_path).to_s.strip
65
66
  else
66
- title = lang.strip
67
+ title = lang.to_s.strip
67
68
  end
68
69
 
69
70
  break if title
@@ -25,7 +25,7 @@ class Knj::Google_sitemap
25
25
  end
26
26
 
27
27
  lm = el.add_element("lastmod")
28
- if @args.has_key?(:date_min) and @args[:date_min] > lastmod_value
28
+ if @args.key?(:date_min) and @args[:date_min] > lastmod_value
29
29
  lastmod_value = @args[:date_min]
30
30
  end
31
31
 
@@ -28,7 +28,7 @@ class Knj::Hash_methods
28
28
  end
29
29
 
30
30
  def method_missing(method, *paras)
31
- if !@data.has_key?(method)
31
+ if !@data.key?(method)
32
32
  raise "No such method '#{method}' on class '#{self.class.name}'"
33
33
  end
34
34
 
@@ -45,7 +45,7 @@ class Knj::Http
45
45
  @http.set_debug_output($stderr) if @opts["debug"]
46
46
  @http.use_ssl = true if @opts["ssl"]
47
47
 
48
- if @opts.has_key?("validate") and !@opts["validate"]
48
+ if @opts.key?("validate") and !@opts["validate"]
49
49
  @http.verify_mode = OpenSSL::SSL::VERIFY_NONE
50
50
  end
51
51
 
@@ -59,49 +59,65 @@ class Knj::Http
59
59
  def cookiestr
60
60
  cookiestr = ""
61
61
  @cookies.each do |key, value|
62
- if cookiestr != ""
63
- cookiestr += "; "
64
- end
65
-
66
- cookiestr += value.to_s
62
+ cookiestr += "; " if cookiestr != ""
63
+ cookiestr += "#{Knj::Php.urlencode(key)}=#{Knj::Php.urlencode(value.to_s)}"
67
64
  end
68
65
 
69
66
  return cookiestr
70
67
  end
71
68
 
72
69
  def cookie_add(cgi_cookie)
73
- @cookies[cgi_cookie.name] = cgi_cookie
70
+ if cgi_cookie.class.name == "CGI::Cookie"
71
+ @cookies[cgi_cookie.name] = cgi_cookie.value
72
+ elsif cgi_cookie.is_a?(Hash)
73
+ @cookies[cgi_cookie["name"]] = cgi_cookie["value"]
74
+ else
75
+ raise "Unknown object: '#{cgi_cookie.class.name}'."
76
+ end
74
77
  end
75
78
 
76
79
  def headers
77
80
  tha_headers = {"User-Agent" => @useragent}
78
81
  tha_headers["Referer"] = @lasturl if @lasturl
79
- tha_headers["Cookie"] = self.cookiestr if cookiestr != ""
82
+ tha_headers["Cookie"] = cookiestr if cookiestr != ""
80
83
  return tha_headers
81
84
  end
82
85
 
83
86
  def setcookie(set_data)
84
- if @opts["skip_webrick"]
85
- print "SetData: #{set_data}\n"
86
- else
87
- WEBrick::Cookie.parse_set_cookies(set_data.to_s).each do |cookie|
88
- @cookies[cookie.name] = cookie
87
+ return nil if !set_data
88
+
89
+ set_data.each do |cookie_str|
90
+ Knj::Web.parse_set_cookies(cookie_str.to_s).each do |cookie|
91
+ @cookies[cookie["name"]] = cookie["value"]
89
92
  end
90
93
  end
91
94
  end
92
95
 
96
+ #Shortcut to spawn a new Http-object and running get on the path.
97
+ def self.get(url)
98
+ data = URI.parse(url)
99
+
100
+ args = {"host" => data.host}
101
+ args["ssl"] = true if data.scheme == "https"
102
+ args["port"] = data.port if data.port
103
+
104
+ http = Knj::Http.new(args)
105
+ return http.get(data.path)
106
+ end
107
+
93
108
  def get(addr)
94
109
  check_connected
95
110
 
96
111
  @mutex.synchronize do
97
112
  resp, data = @http.get(addr, self.headers)
98
- self.setcookie(resp.response["set-cookie"])
99
-
100
- raise "Could not find that page: '#{addr}'." if resp.is_a?(Net::HTTPNotFound)
113
+ self.setcookie(resp.response.to_hash["set-cookie"])
114
+ raise Knj::Errors::NotFound, "Could not find that page: '#{addr}'." if resp.is_a?(Net::HTTPNotFound)
101
115
 
102
116
  #in some cases (like in IronRuby) the data is set like this.
103
117
  data = resp.body if !data
104
118
 
119
+ return Knj::Http.get(resp["location"]) if resp["location"]
120
+
105
121
  return {
106
122
  "response" => resp,
107
123
  "data" => data
@@ -113,7 +129,7 @@ class Knj::Http
113
129
  check_connected
114
130
  @mutex.synchronize do
115
131
  resp, data = @http.head(addr, self.headers)
116
- self.setcookie(resp.response["set-cookie"])
132
+ self.setcookie(resp.response.to_hash["set-cookie"])
117
133
 
118
134
  raise "Could not find that page: '#{addr}'." if resp.is_a?(Net::HTTPNotFound)
119
135
 
@@ -141,7 +157,7 @@ class Knj::Http
141
157
 
142
158
  @mutex.synchronize do
143
159
  resp, data = @http.post2(addr, postdata, self.headers)
144
- self.setcookie(resp.response["set-cookie"])
160
+ self.setcookie(resp.response.to_hash["set-cookie"])
145
161
 
146
162
  return {
147
163
  "response" => resp,
@@ -179,7 +195,7 @@ class Knj::Http
179
195
  request["Content-Type"] = "multipart/form-data, boundary=#{boundary}"
180
196
 
181
197
  resp, data = @http.request(request)
182
- self.setcookie(resp.response["set-cookie"])
198
+ self.setcookie(resp.response.to_hash["set-cookie"])
183
199
 
184
200
  return {
185
201
  "response" => resp,