knjrbfw 0.0.8 → 0.0.9

Sign up to get free protection for your applications and to get access to all the features.
Files changed (211) hide show
  1. data/VERSION +1 -1
  2. data/knjrbfw.gemspec +29 -8
  3. data/lib/knj/arrayext.rb +206 -153
  4. data/lib/knj/autoload/backups/ping.rb +2 -2
  5. data/lib/knj/autoload/erubis.rb +3 -3
  6. data/lib/knj/autoload/facets_dictionary.rb +2 -2
  7. data/lib/knj/autoload/gettext.rb +3 -3
  8. data/lib/knj/autoload/gtk2.rb +1 -1
  9. data/lib/knj/autoload/json.rb +14 -0
  10. data/lib/knj/autoload/magick.rb +3 -3
  11. data/lib/knj/autoload/mysql.rb +3 -3
  12. data/lib/knj/autoload/parsedate.rb +1 -1
  13. data/lib/knj/autoload/ping.rb +2 -2
  14. data/lib/knj/autoload/rexml.rb +5 -5
  15. data/lib/knj/autoload/soap.rb +1 -1
  16. data/lib/knj/autoload/sqlite3.rb +3 -3
  17. data/lib/knj/autoload/tmail.rb +3 -3
  18. data/lib/knj/autoload/xmlsimple.rb +3 -3
  19. data/lib/knj/autoload/zip.rb +3 -3
  20. data/lib/knj/autoload.rb +87 -81
  21. data/lib/knj/cmd_gen.rb +19 -19
  22. data/lib/knj/cmd_parser.rb +59 -0
  23. data/lib/knj/compiler.rb +34 -34
  24. data/lib/knj/cpufreq.rb +37 -37
  25. data/lib/knj/csv.rb +20 -0
  26. data/lib/knj/datarow.rb +406 -239
  27. data/lib/knj/datarow_custom.rb +124 -0
  28. data/lib/knj/datestamp.rb +89 -89
  29. data/lib/knj/datet.rb +550 -454
  30. data/lib/knj/db.rb +1 -0
  31. data/lib/knj/degulesider.rb +42 -44
  32. data/lib/knj/erb/erb.rb +5 -5
  33. data/lib/knj/erb/erb_cache_clean.rb +10 -10
  34. data/lib/knj/erb/erb_fcgi.rb +32 -32
  35. data/lib/knj/erb/erb_fcgi_1.9.rb +32 -32
  36. data/lib/knj/erb/erb_fcgi_jruby.rb +2 -2
  37. data/lib/knj/erb/erb_jruby.rb +5 -5
  38. data/lib/knj/erb/include.rb +243 -243
  39. data/lib/knj/errors.rb +19 -18
  40. data/lib/knj/eruby.rb +12 -10
  41. data/lib/knj/event_filemod.rb +31 -31
  42. data/lib/knj/event_handler.rb +73 -67
  43. data/lib/knj/exchangerates.rb +37 -37
  44. data/lib/knj/facebook_connect.rb +95 -18
  45. data/lib/knj/filesystem.rb +6 -6
  46. data/lib/knj/fs/drivers/filesystem.rb +12 -12
  47. data/lib/knj/fs/drivers/ftp.rb +31 -31
  48. data/lib/knj/fs/drivers/ssh.rb +26 -26
  49. data/lib/knj/fs/fs.rb +31 -31
  50. data/lib/knj/gettext_fallback.rb +15 -15
  51. data/lib/knj/gettext_threadded.rb +75 -75
  52. data/lib/knj/google_sitemap.rb +53 -53
  53. data/lib/knj/gtk2.rb +272 -272
  54. data/lib/knj/gtk2_cb.rb +80 -80
  55. data/lib/knj/gtk2_menu.rb +55 -55
  56. data/lib/knj/gtk2_statuswindow.rb +62 -62
  57. data/lib/knj/gtk2_tv.rb +58 -58
  58. data/lib/knj/hash_methods.rb +27 -36
  59. data/lib/knj/http.rb +189 -167
  60. data/lib/knj/http2.rb +259 -53
  61. data/lib/knj/image.rb +2 -2
  62. data/lib/knj/includes/appserver_cli.rb +18 -18
  63. data/lib/knj/includes/require_info.rb +15 -0
  64. data/lib/knj/ip2location.rb +20 -20
  65. data/lib/knj/ironruby-gtk2/button.rb +14 -14
  66. data/lib/knj/ironruby-gtk2/dialog.rb +42 -42
  67. data/lib/knj/ironruby-gtk2/entry.rb +4 -4
  68. data/lib/knj/ironruby-gtk2/gdk_event.rb +1 -1
  69. data/lib/knj/ironruby-gtk2/gdk_eventbutton.rb +11 -11
  70. data/lib/knj/ironruby-gtk2/gdk_pixbuf.rb +9 -9
  71. data/lib/knj/ironruby-gtk2/gladexml.rb +102 -102
  72. data/lib/knj/ironruby-gtk2/glib.rb +13 -13
  73. data/lib/knj/ironruby-gtk2/gtk2.rb +121 -121
  74. data/lib/knj/ironruby-gtk2/gtk_builder.rb +29 -29
  75. data/lib/knj/ironruby-gtk2/gtk_cellrenderertext.rb +3 -3
  76. data/lib/knj/ironruby-gtk2/gtk_combobox.rb +17 -17
  77. data/lib/knj/ironruby-gtk2/gtk_filechooserbutton.rb +3 -3
  78. data/lib/knj/ironruby-gtk2/gtk_liststore.rb +16 -16
  79. data/lib/knj/ironruby-gtk2/gtk_menu.rb +3 -3
  80. data/lib/knj/ironruby-gtk2/gtk_menuitem.rb +2 -2
  81. data/lib/knj/ironruby-gtk2/gtk_statusicon.rb +3 -3
  82. data/lib/knj/ironruby-gtk2/gtk_treeiter.rb +22 -22
  83. data/lib/knj/ironruby-gtk2/gtk_treeselection.rb +11 -11
  84. data/lib/knj/ironruby-gtk2/gtk_treeview.rb +17 -17
  85. data/lib/knj/ironruby-gtk2/gtk_treeviewcolumn.rb +30 -30
  86. data/lib/knj/ironruby-gtk2/iconsize.rb +1 -1
  87. data/lib/knj/ironruby-gtk2/image.rb +13 -13
  88. data/lib/knj/ironruby-gtk2/label.rb +17 -17
  89. data/lib/knj/ironruby-gtk2/stock.rb +2 -2
  90. data/lib/knj/ironruby-gtk2/tests/test_2.rb +14 -14
  91. data/lib/knj/ironruby-gtk2/tests/test_ironruby_window.rb +37 -37
  92. data/lib/knj/ironruby-gtk2/vbox.rb +3 -3
  93. data/lib/knj/ironruby-gtk2/window.rb +18 -18
  94. data/lib/knj/jruby-gtk2/builder/test_builder.rb +11 -11
  95. data/lib/knj/jruby-gtk2/builder.rb +25 -25
  96. data/lib/knj/jruby-gtk2/cellrenderertext.rb +10 -10
  97. data/lib/knj/jruby-gtk2/checkbutton.rb +1 -1
  98. data/lib/knj/jruby-gtk2/combobox.rb +27 -27
  99. data/lib/knj/jruby-gtk2/dialog.rb +40 -40
  100. data/lib/knj/jruby-gtk2/eventbutton.rb +19 -19
  101. data/lib/knj/jruby-gtk2/gladexml.rb +97 -97
  102. data/lib/knj/jruby-gtk2/gtk2.rb +203 -203
  103. data/lib/knj/jruby-gtk2/hbox.rb +8 -8
  104. data/lib/knj/jruby-gtk2/iconsize.rb +3 -3
  105. data/lib/knj/jruby-gtk2/image.rb +8 -8
  106. data/lib/knj/jruby-gtk2/liststore.rb +54 -54
  107. data/lib/knj/jruby-gtk2/menu.rb +35 -35
  108. data/lib/knj/jruby-gtk2/progressbar.rb +10 -10
  109. data/lib/knj/jruby-gtk2/statusicon.rb +3 -3
  110. data/lib/knj/jruby-gtk2/stock.rb +6 -6
  111. data/lib/knj/jruby-gtk2/tests/test_glade_window.rb +36 -36
  112. data/lib/knj/jruby-gtk2/tests/test_normal_window.rb +3 -3
  113. data/lib/knj/jruby-gtk2/tests/test_trayicon.rb +2 -2
  114. data/lib/knj/jruby-gtk2/treeview.rb +88 -88
  115. data/lib/knj/jruby-gtk2/vbox.rb +10 -10
  116. data/lib/knj/jruby-gtk2/window.rb +7 -7
  117. data/lib/knj/jruby_compiler.rb +12 -12
  118. data/lib/knj/knj.rb +12 -11
  119. data/lib/knj/knj_controller.rb +13 -8
  120. data/lib/knj/knjdb/drivers/mysql/knjdb_mysql.rb +499 -316
  121. data/lib/knj/knjdb/drivers/mysql/knjdb_mysql_columns.rb +127 -125
  122. data/lib/knj/knjdb/drivers/mysql/knjdb_mysql_indexes.rb +43 -25
  123. data/lib/knj/knjdb/drivers/mysql/knjdb_mysql_tables.rb +316 -241
  124. data/lib/knj/knjdb/drivers/sqlite3/knjdb_sqlite3.rb +12 -0
  125. data/lib/knj/knjdb/drivers/sqlite3/knjdb_sqlite3_columns.rb +146 -146
  126. data/lib/knj/knjdb/drivers/sqlite3/knjdb_sqlite3_indexes.rb +24 -24
  127. data/lib/knj/knjdb/drivers/sqlite3/knjdb_sqlite3_tables.rb +283 -283
  128. data/lib/knj/knjdb/libknjdb.rb +96 -52
  129. data/lib/knj/knjdb/libknjdb_java_sqlite3.rb +78 -78
  130. data/lib/knj/knjdb/libknjdb_row.rb +147 -147
  131. data/lib/knj/knjdb/libknjdb_sqlite3_ironruby.rb +61 -61
  132. data/lib/knj/knjdb/revision.rb +262 -0
  133. data/lib/knj/libqt.rb +69 -69
  134. data/lib/knj/libqt_window.rb +8 -8
  135. data/lib/knj/locales.rb +62 -52
  136. data/lib/knj/maemo/fremantle-calendar/fremantle-calendar.rb +54 -54
  137. data/lib/knj/mail.rb +73 -73
  138. data/lib/knj/mailobj.rb +82 -80
  139. data/lib/knj/mount.rb +113 -113
  140. data/lib/knj/notify.rb +11 -11
  141. data/lib/knj/nvidia_settings.rb +43 -43
  142. data/lib/knj/objects/objects_sqlhelper.rb +474 -0
  143. data/lib/knj/objects.rb +569 -793
  144. data/lib/knj/opts.rb +38 -38
  145. data/lib/knj/os.rb +176 -158
  146. data/lib/knj/php.rb +853 -683
  147. data/lib/knj/php_parser/arguments.rb +3 -3
  148. data/lib/knj/php_parser/functions.rb +95 -95
  149. data/lib/knj/php_parser/php_parser.rb +16 -16
  150. data/lib/knj/php_parser/tests/test.rb +6 -6
  151. data/lib/knj/php_parser/tests/test_function_run.rb +6 -6
  152. data/lib/knj/power_manager.rb +29 -29
  153. data/lib/knj/process.rb +457 -0
  154. data/lib/knj/process_meta.rb +400 -0
  155. data/lib/knj/rand.rb +8 -8
  156. data/lib/knj/retry.rb +69 -69
  157. data/lib/knj/rhodes/delegate.rb +414 -0
  158. data/lib/knj/rhodes/rhodes.rb +114 -40
  159. data/lib/knj/rhodes/weakref.rb +80 -0
  160. data/lib/knj/rsvgbin.rb +18 -18
  161. data/lib/knj/scripts/degulesider.rb +2 -2
  162. data/lib/knj/scripts/filesearch.rb +35 -35
  163. data/lib/knj/scripts/ip2location.rb +2 -2
  164. data/lib/knj/scripts/keepalive.rb +2 -2
  165. data/lib/knj/scripts/php_to_rb_helper.rb +376 -0
  166. data/lib/knj/scripts/process_meta_exec.rb +104 -0
  167. data/lib/knj/scripts/svn_merge.rb +21 -21
  168. data/lib/knj/scripts/upgrade_knjrbfw_checker.rb +26 -26
  169. data/lib/knj/sms.rb +52 -52
  170. data/lib/knj/sshrobot/sshrobot.rb +90 -88
  171. data/lib/knj/sshrobot.rb +1 -0
  172. data/lib/knj/strings.rb +186 -74
  173. data/lib/knj/sysuser.rb +25 -25
  174. data/lib/knj/table_writer.rb +97 -0
  175. data/lib/knj/tests/compiler/compiler_test.rb +2 -2
  176. data/lib/knj/tests/test_degulesider.rb +1 -1
  177. data/lib/knj/tests/test_http2_proxy.rb +26 -0
  178. data/lib/knj/tests/test_mount.rb +9 -9
  179. data/lib/knj/tests/test_retry.rb +17 -17
  180. data/lib/knj/thread.rb +23 -24
  181. data/lib/knj/thread2.rb +45 -45
  182. data/lib/knj/threadhandler.rb +135 -102
  183. data/lib/knj/threadpool.rb +195 -145
  184. data/lib/knj/translations.rb +128 -119
  185. data/lib/knj/unix_proc.rb +80 -80
  186. data/lib/knj/web.rb +947 -881
  187. data/lib/knj/webscripts/image.rhtml +142 -67
  188. data/lib/knj/win.rb +2 -2
  189. data/lib/knj/win_registry.rb +58 -58
  190. data/lib/knj/win_tightvnc.rb +125 -125
  191. data/lib/knj/wref.rb +104 -0
  192. data/lib/knj/x11vnc.rb +46 -46
  193. data/lib/knj/youtube.rb +33 -36
  194. data/lib/knjrbfw.rb +1 -0
  195. data/spec/cmd_parser_spec.rb +25 -0
  196. data/spec/db_spec.rb +40 -0
  197. data/spec/db_spec_encoding_test_file.txt +1 -0
  198. data/spec/http2_spec.rb +37 -0
  199. data/spec/knjrbfw_spec.rb +17 -15
  200. data/spec/php_spec.rb +69 -0
  201. data/spec/process_meta_spec.rb +150 -0
  202. data/spec/process_spec.rb +107 -0
  203. data/spec/strings_spec.rb +21 -0
  204. data/spec/web_spec.rb +16 -0
  205. metadata +42 -21
  206. data/lib/knj/autoload/json_autoload.rb +0 -7
  207. data/lib/knj/autoload/twitter.rb +0 -2
  208. data/lib/knj/ext/webrick.rb +0 -31
  209. data/lib/knj/jruby-gtk2/gtk-4.0.jar +0 -0
  210. data/lib/knj/knjdb/mysql-connector-java-5.1.13-bin.jar +0 -0
  211. data/lib/knj/knjdb/sqlitejdbc-v056.jar +0 -0
data/lib/knj/http2.rb CHANGED
@@ -1,10 +1,15 @@
1
1
  class Knj::Http2
2
2
  attr_reader :cookies
3
3
 
4
- def initialize(args)
4
+ def initialize(args = {})
5
+ args = {:host => args} if args.is_a?(String)
6
+ raise "Arguments wasnt a hash." if !args.is_a?(Hash)
7
+ require "#{$knjpath}web"
8
+
5
9
  @args = args
6
10
  @cookies = {}
7
11
  @debug = @args[:debug]
12
+ @mutex = Mutex.new
8
13
 
9
14
  if !@args[:port]
10
15
  if @args[:ssl]
@@ -27,15 +32,68 @@ class Knj::Http2
27
32
  end
28
33
 
29
34
  raise "No host was given." if !@args[:host]
35
+ self.reconnect
36
+ end
37
+
38
+ def socket_working?
39
+ return false if !@sock or @sock.closed?
40
+
41
+ if @keepalive_timeout and @request_last
42
+ between = Time.now.to_i - @request_last.to_i
43
+ if between >= @keepalive_timeout
44
+ print "Http2: We are over the keepalive-wait - returning false for socket_working?.\n" if @debug
45
+ return false
46
+ end
47
+ end
48
+
49
+ return true
50
+ end
51
+
52
+ #Reconnects to the host.
53
+ def reconnect
54
+ print "Http2: Reconnect.\n" if @debug
55
+
56
+ #Reset variables.
57
+ @keepalive_max = nil
58
+ @keepalive_timeout = nil
59
+ @connection = nil
60
+ @contenttype = nil
61
+ @charset = nil
30
62
 
31
- @sock_plain = TCPSocket.new(@args[:host], @args[:port])
63
+ #Open connection.
64
+ if @args[:proxy]
65
+ print "Http2: Initializing proxy stuff.\n" if @debug
66
+ @sock_plain = TCPSocket.new(@args[:proxy][:host], @args[:proxy][:port])
67
+ @sock = @sock_plain
68
+
69
+ @sock.write("CONNECT #{@args[:host]}:#{@args[:port]} HTTP/1.0#{@nl}")
70
+ @sock.write("User-Agent: #{@uagent}#{@nl}")
71
+
72
+ if @args[:proxy][:user] and @args[:proxy][:passwd]
73
+ credential = ["#{@args[:proxy][:user]}:#{@args[:proxy][:passwd]}"].pack("m")
74
+ credential.delete!("\r\n")
75
+ @sock.write("Proxy-Authorization: Basic #{credential}#{@nl}")
76
+ end
77
+
78
+ @sock.write(@nl)
79
+
80
+ res = @sock.gets
81
+ if res.to_s.downcase != "http/1.0 200 connection established#{@nl}"
82
+ raise res
83
+ end
84
+
85
+ res_empty = @sock.gets
86
+ raise "Empty res wasnt empty." if res_empty != @nl
87
+ else
88
+ @sock_plain = TCPSocket.new(@args[:host], @args[:port])
89
+ end
32
90
 
33
91
  if @args[:ssl]
92
+ print "Http2: Initializing SSL.\n" if @debug
34
93
  require "openssl"
35
94
 
36
95
  ssl_context = OpenSSL::SSL::SSLContext.new
37
96
  #ssl_context.verify_mode = OpenSSL::SSL::VERIFY_PEER
38
- #ssl_context.ca_file = CA_FILE
39
97
 
40
98
  @sock_ssl = OpenSSL::SSL::SSLSocket.new(@sock_plain, ssl_context)
41
99
  @sock_ssl.sync_close = true
@@ -47,94 +105,207 @@ class Knj::Http2
47
105
  end
48
106
  end
49
107
 
50
- def get(addr)
51
- header_str = "GET /#{addr} HTTP/1.1#{@nl}"
52
- header_str += self.header_str(
53
- "Host" => @args[:host],
54
- "Connection" => "Keep-Alive",
55
- "User-Agent" => @uagent
56
- )
57
- header_str += "#{@nl}"
58
-
59
- @sock.puts(header_str)
60
- return self.read_response
108
+ def get(addr, args = {})
109
+ @mutex.synchronize do
110
+ header_str = "GET /#{addr} HTTP/1.1#{@nl}"
111
+ header_str << self.header_str(self.default_headers(args), args)
112
+ header_str << "#{@nl}"
113
+
114
+ print "Http2: Writing headers.\n" if @debug
115
+ self.write(header_str)
116
+
117
+ print "Http2: Reading response.\n" if @debug
118
+ resp = self.read_response(args)
119
+
120
+ print "Http2: Done with get request.\n" if @debug
121
+ return resp
122
+ end
61
123
  end
62
124
 
63
- def post(addr, pdata = {})
64
- praw = ""
65
- pdata.each do |key, val|
66
- praw += "&" if praw != ""
67
- praw += "#{Knj::Web.urlenc(key)}=#{Knj::Web.urlenc(val)}"
125
+ #Tries to write a string to the socket. If it fails it reconnects and tries again.
126
+ def write(str)
127
+ #Reset variables.
128
+ @length = nil
129
+ @encoding = nil
130
+ self.reconnect if !self.socket_working?
131
+
132
+ begin
133
+ raise Errno::EPIPE, "The socket is closed." if !@sock or @sock.closed?
134
+ @sock.puts(str)
135
+ rescue Errno::EPIPE #this can also be thrown by puts.
136
+ self.reconnect
137
+ @sock.puts(str)
68
138
  end
69
139
 
70
- header_str = "POST /#{addr} HTTP/1.1#{@nl}"
71
- header_str += self.header_str(
140
+ @request_last = Time.now
141
+ end
142
+
143
+ def default_headers(args = {})
144
+ return args[:default_headers] if args[:default_headers]
145
+
146
+ headers = {
72
147
  "Host" => @args[:host],
73
148
  "Connection" => "Keep-Alive",
74
- "User-Agent" => @uagent,
75
- "Content-Length" => praw.length
76
- )
77
- header_str += "#{@nl}"
78
- header_str += praw
149
+ "User-Agent" => @uagent
150
+ }
151
+
152
+ if !@args.key?(:encoding_gzip) or @args[:encoding_gzip]
153
+ headers["Accept-Encoding"] = "gzip"
154
+ else
155
+ headers["Accept-Encoding"] = "none"
156
+ end
79
157
 
80
- @sock.puts(header_str)
81
- return self.read_response
158
+ return headers
82
159
  end
83
160
 
84
- def header_str(headers_hash)
85
- if @cookies.length > 0
161
+ def post(addr, pdata = {}, args = {})
162
+ @mutex.synchronize do
163
+ praw = ""
164
+ pdata.each do |key, val|
165
+ praw << "&" if praw != ""
166
+ praw << "#{Knj::Web.urlenc(key)}=#{Knj::Web.urlenc(val)}"
167
+ end
168
+
169
+ header_str = "POST /#{addr} HTTP/1.1#{@nl}"
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)
176
+ end
177
+ end
178
+
179
+ def post_multipart(addr, pdata, args = {})
180
+ @mutex.synchronize do
181
+ boundary = Digest::MD5.hexdigest(Time.now.to_f.to_s)
182
+
183
+ praw = ""
184
+ pdata.each do |key, val|
185
+ praw << "--#{boundary}#{@nl}"
186
+
187
+ if val.class.name == "Tempfile" and val.respond_to?("original_filename")
188
+ praw << "Content-Disposition: form-data; name=\"#{key}\"; filename=\"#{val.original_filename}\";#{@nl}"
189
+ else
190
+ praw << "Content-Disposition: form-data; name=\"#{key}\";#{@nl}"
191
+ end
192
+
193
+ praw << "Content-Type: text/plain#{@nl}"
194
+ praw << "Content-Length: #{val.length}#{@nl}"
195
+ praw << @nl
196
+
197
+ if val.is_a?(StringIO)
198
+ praw << val.read
199
+ else
200
+ praw << val.to_s
201
+ end
202
+
203
+ praw << @nl
204
+ end
205
+
206
+ header_str = "POST /#{addr} HTTP/1.1#{@nl}"
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)
215
+ end
216
+ end
217
+
218
+ def header_str(headers_hash, args = {})
219
+ if @cookies.length > 0 and (!args.key?(:cookies) or args[:cookies])
86
220
  cstr = ""
87
221
 
88
222
  first = true
89
223
  @cookies.each do |cookie_name, cookie_data|
90
- cstr += "; " if !first
224
+ cstr << "; " if !first
91
225
  first = false if first
92
226
 
93
- cstr += "#{Knj::Web.urlenc(cookie_data["name"])}=#{Knj::Web.urlenc(cookie_data["value"])}"
227
+ cstr << "#{Knj::Web.urlenc(cookie_data["name"])}=#{Knj::Web.urlenc(cookie_data["value"])}"
94
228
  end
95
229
 
96
230
  headers_hash["Cookie"] = cstr
97
231
  end
98
232
 
99
233
  headers_str = ""
100
-
101
234
  headers_hash.each do |key, val|
102
- headers_str += "#{key}: #{val}#{@nl}"
235
+ headers_str << "#{key}: #{val}#{@nl}"
103
236
  end
104
237
 
105
238
  return headers_str
106
239
  end
107
240
 
108
- def read_response
241
+ def on_content_call(args, line)
242
+ args[:on_content].call(line) if args.key?(:on_content)
243
+ end
244
+
245
+ def read_response(args = {})
109
246
  @mode = "headers"
110
247
  @resp = Knj::Http2::Response.new
111
248
 
112
249
  loop do
113
- print "Reading next line.\n" if @debug
114
- line = @sock.gets
250
+ begin
251
+ if @length and @length > 0 and @mode == "body"
252
+ line = @sock.read(@length)
253
+ else
254
+ line = @sock.gets
255
+ end
256
+ rescue Errno::ECONNRESET
257
+ print "Http2: The connection was reset while reading - breaking gently...\n" if @debug
258
+ line = ""
259
+ @sock = nil
260
+ end
261
+
115
262
  break if line.to_s == ""
116
263
 
117
264
  if @mode == "headers" and line == @nl
118
- break if @resp.header("content-length") == "0"
265
+ break if @length == 0
119
266
  @mode = "body"
120
267
  next
121
268
  end
122
269
 
123
270
  if @mode == "headers"
124
- self.parse_header(line)
271
+ self.parse_header(line, args)
125
272
  elsif @mode == "body"
126
- stat = self.parse_body(line)
273
+ self.on_content_call(args, "\r\n")
274
+ stat = self.parse_body(line, args)
127
275
  break if stat == "break"
128
276
  next if stat == "next"
129
277
  end
130
278
  end
131
279
 
280
+
281
+ #Check if we should reconnect based on keep-alive-max.
282
+ if @keepalive_max == 1 or @connection == "close"
283
+ @sock.close if !@sock.closed?
284
+ @sock = nil
285
+ end
286
+
287
+
288
+ #Check if the content is gzip-encoded - if so: decode it!
289
+ if @encoding == "gzip"
290
+ require "zlib"
291
+ require "iconv"
292
+ io = StringIO.new(@resp.args[:body])
293
+ gz = Zlib::GzipReader.new(io)
294
+ untrusted_str = gz.read
295
+ ic = Iconv.new("UTF-8//IGNORE", "UTF-8")
296
+ valid_string = ic.iconv(untrusted_str + " ")[0..-2]
297
+ @resp.args[:body] = valid_string
298
+ end
299
+
300
+
132
301
  #Release variables.
133
302
  resp = @resp
134
303
  @resp = nil
135
304
  @mode = nil
136
305
 
137
- if resp.args[:code] == "302" and resp.header?("location")
306
+ raise "No status-code was received from the server.\n\nHeaders:\n#{Knj::Php.print_r(resp.headers)}\n\nBody:\n#{resp.args[:body]}" if !resp.args[:code]
307
+
308
+ if resp.args[:code].to_s == "302" and resp.header?("location") and (!@args.key?(:follow_redirects) or @args[:follow_redirects])
138
309
  uri = URI.parse(resp.header("location"))
139
310
 
140
311
  args = {:host => uri.host}
@@ -147,12 +318,14 @@ class Knj::Http2
147
318
  http = Knj::Http2.new(args)
148
319
  return http.get(uri.path)
149
320
  end
321
+ elsif resp.args[:code].to_s == "500"
322
+ raise "500 - Internal server error."
150
323
  else
151
324
  return resp
152
325
  end
153
326
  end
154
327
 
155
- def parse_header(line)
328
+ def parse_header(line, args)
156
329
  if match = line.match(/^(.+?):\s*(.+)#{@nl}$/)
157
330
  key = match[1].to_s.downcase
158
331
 
@@ -160,6 +333,36 @@ class Knj::Http2
160
333
  Knj::Web.parse_set_cookies(match[2]).each do |cookie_data|
161
334
  @cookies[cookie_data["name"]] = cookie_data
162
335
  end
336
+ elsif key == "keep-alive"
337
+ if ka_max = match[2].to_s.match(/max=(\d+)/)
338
+ @keepalive_max = ka_max[1].to_i
339
+ print "Http2: Keepalive-max set to: '#{@keepalive_max}'.\n" if @debug
340
+ end
341
+
342
+ if ka_timeout = match[2].to_s.match(/timeout=(\d+)/)
343
+ @keepalive_timeout = ka_timeout[1].to_i
344
+ print "Http2: Keepalive-timeout set to: '#{@keepalive_timeout}'.\n" if @debug
345
+ end
346
+ elsif key == "connection"
347
+ @connection = match[2].to_s.downcase
348
+ elsif key == "content-encoding"
349
+ @encoding = match[2].to_s.downcase
350
+ elsif key == "content-length"
351
+ @length = match[2].to_i
352
+ elsif key == "content-type"
353
+ ctype = match[2].to_s
354
+ if match_charset = ctype.match(/\s*;\s*charset=(.+)/i)
355
+ @charset = match_charset[1].downcase
356
+ @resp.args[:charset] = @charset
357
+ ctype.gsub!(match_charset[0], "")
358
+ end
359
+
360
+ @ctype = ctype
361
+ @resp.args[:contenttype] = @ctype
362
+ end
363
+
364
+ if key != "transfer-encoding" and key != "content-length" and key != "connection" and key != "keep-alive"
365
+ self.on_content_call(args, line)
163
366
  end
164
367
 
165
368
  @resp.headers[key] = [] if !@resp.headers.key?(key)
@@ -172,25 +375,20 @@ class Knj::Http2
172
375
  end
173
376
  end
174
377
 
175
- def parse_body(line)
378
+ def parse_body(line, args)
176
379
  if @resp.args[:http_version] = "1.1"
177
- return "break" if @resp.header("content-length") == "0"
380
+ return "break" if @length == 0
178
381
 
179
382
  if @resp.header("transfer-encoding").to_s.downcase == "chunked"
180
383
  len = line.strip.hex
181
384
 
182
- print "Content-Length: #{@resp.header("content-length")}\n" if @debug
183
- print "Current body length: #{@resp.args[:body].length}\n" if @debug
184
- print "Chunk length: #{len}\n" if @debug
185
-
186
- print "Reading chunked.\n" if @debug
187
385
  if len > 0
188
386
  read = @sock.read(len)
189
387
  return "break" if read == "" or read == @nl
190
- @resp.args[:body] += read
388
+ @resp.args[:body] << read
389
+ self.on_content_call(args, read)
191
390
  end
192
391
 
193
- print "Reading trailing NL.\n" if @debug
194
392
  nl = @sock.gets
195
393
  if len == 0
196
394
  if nl == @nl
@@ -200,10 +398,10 @@ class Knj::Http2
200
398
  end
201
399
  end
202
400
 
203
- #print "Test: '#{nl}'\n"
204
401
  raise "Should have read newline but didnt: '#{nl}'." if nl != @nl
205
402
  else
206
- @resp.args[:body] += line.to_s
403
+ @resp.args[:body] << line.to_s
404
+ self.on_content_call(args, line)
207
405
  return "break" if @resp.header?("content-length") and @resp.args[:body].length >= @resp.header("content-length").to_i
208
406
  end
209
407
  else
@@ -246,4 +444,12 @@ class Knj::Http2::Response
246
444
  def body
247
445
  return @args[:body]
248
446
  end
447
+
448
+ def charset
449
+ return @args[:charset]
450
+ end
451
+
452
+ def contenttype
453
+ return @args[:contenttype]
454
+ end
249
455
  end
data/lib/knj/image.rb CHANGED
@@ -1,8 +1,8 @@
1
1
  class Knj::Image
2
2
  #This function can make rounded transparent corners on an image with a given radius. Further more it can also draw borders around the entire image in a given color and take the border into account.
3
3
  def self.rounded_corners(args)
4
- raise "No or invalid ':img' given." if !args[:img]
5
- raise "No or invalid ':radius' given." if args[:radius].to_i <= 0
4
+ raise "No or invalid ':img' given: '#{args}'." if !args[:img]
5
+ raise "No or invalid ':radius' given: '#{args}'." if !args[:radius].respond_to?("to_i") or args[:radius].to_i <= 0
6
6
 
7
7
  pic = args[:img]
8
8
 
@@ -1,30 +1,30 @@
1
1
  require "knj/autoload"
2
- require "knj/web"
2
+ require "#{$knjpath}web"
3
3
 
4
4
  class Appserver_cli
5
- def self.loadfile(filepath)
6
- require filepath
7
- end
8
-
9
- def self._(str)
10
- return str
11
- end
12
-
13
- def self.gettext
14
- return self
15
- end
16
-
17
- def self.lang_opts
18
- return []
19
- end
5
+ def self.loadfile(filepath)
6
+ require filepath
7
+ end
8
+
9
+ def self._(str)
10
+ return str
11
+ end
12
+
13
+ def self.gettext
14
+ return self
15
+ end
16
+
17
+ def self.lang_opts
18
+ return []
19
+ end
20
20
  end
21
21
 
22
22
  def _kas
23
- return Appserver_cli
23
+ return Appserver_cli
24
24
  end
25
25
 
26
26
  def _db
27
- return $db
27
+ return $db
28
28
  end
29
29
 
30
30
  def _ob
@@ -0,0 +1,15 @@
1
+ $knj_require_info = {}
2
+
3
+ class Object
4
+ alias_method :require_knj, :require
5
+
6
+ def require(path)
7
+ stat = require_knj(path)
8
+
9
+ if stat and !$knj_require_info.key?(path)
10
+ $knj_require_info[path] = {:caller => caller}
11
+ end
12
+
13
+ return stat
14
+ end
15
+ end
@@ -1,22 +1,22 @@
1
1
  class Knj::Ip2location
2
- def initialize(args = {})
3
- @args = args
4
- @http = Knj::Http.new(
5
- "host" => "www.ip2location.com",
6
- "port" => 80
7
- )
8
- end
9
-
10
- def lookup(ip)
11
- raise "Invalid IP: #{ip}." if !ip.to_s.match(/^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/)
12
-
13
- html = @http.get("/#{ip}")["data"]
14
- ret = {}
15
-
16
- html.scan(/<span id="dgLookup__ctl2_lblI(.+?)">(.+?)<\/span>/) do |match|
17
- ret[match[0]] = match[1]
18
- end
19
-
20
- return ret
21
- end
2
+ def initialize(args = {})
3
+ @args = args
4
+ @http = Knj::Http.new(
5
+ "host" => "www.ip2location.com",
6
+ "port" => 80
7
+ )
8
+ end
9
+
10
+ def lookup(ip)
11
+ raise "Invalid IP: #{ip}." if !ip.to_s.match(/^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/)
12
+
13
+ html = @http.get("/#{ip}")["data"]
14
+ ret = {}
15
+
16
+ html.scan(/<span id="dgLookup__ctl2_lblI(.+?)">(.+?)<\/span>/) do |match|
17
+ ret[match[0]] = match[1]
18
+ end
19
+
20
+ return ret
21
+ end
22
22
  end
@@ -1,19 +1,19 @@
1
1
  Gtk.events["Gtk"]["Button"] = {
2
- "clicked" => "clicked"
2
+ "clicked" => "clicked"
3
3
  }
4
4
 
5
5
  class Gtk::Button
6
- def initialize(title = "")
7
- if Gtk.takeob
8
- @ob = Gtk.takeob
9
- Gtk.takeob = nil
10
- else
11
- splitted = self.class.to_s.split("::")
12
- @ob = RealGtk.const_get(splitted.last).new(title)
13
- end
14
-
15
- if !@ob
16
- raise "Object was not spawned: #{self.class.to_s}"
17
- end
18
- end
6
+ def initialize(title = "")
7
+ if Gtk.takeob
8
+ @ob = Gtk.takeob
9
+ Gtk.takeob = nil
10
+ else
11
+ splitted = self.class.to_s.split("::")
12
+ @ob = RealGtk.const_get(splitted.last).new(title)
13
+ end
14
+
15
+ if !@ob
16
+ raise "Object was not spawned: #{self.class.to_s}"
17
+ end
18
+ end
19
19
  end
@@ -1,44 +1,44 @@
1
1
  class Gtk::Dialog
2
- RESPONSE_OK = RealGtk::ResponseType.Ok
3
- RESPONSE_YES = RealGtk::ResponseType.Yes
4
- RESPONSE_NO = RealGtk::ResponseType.No
5
- RESPONSE_CANCEL = RealGtk::ResponseType.Cancel
6
- RESPONSE_CLOSE = RealGtk::ResponseType.Close
7
- RESPONSE_DELETE_EVENT = RealGtk::ResponseType.DeleteEvent
8
- MODAL = 0
9
-
10
- def initialize(*paras)
11
- if Gtk.takeob
12
- @ob = Gtk.takeob
13
- Gtk.takeob = nil
14
- else
15
- splitted = self.class.to_s.split("::")
16
- @ob = RealGtk.const_get(splitted.last).new(*paras)
17
- end
18
-
19
- if paras.length > 3
20
- 3.upto(paras.length) do |count|
21
- data = paras[count]
22
-
23
- if data.is_a?(Array)
24
- @ob.method(:add_button).overload(System::String, RealGtk::ResponseType).call(data[0], data[1])
25
- elsif data.is_a?(NilClass)
26
- #do nothing.
27
- else
28
- #raise "Unhandeled data: #{data.class.to_s}"
29
- end
30
- end
31
- end
32
-
33
- if !@ob
34
- raise "Object was not spawned: #{self.class.to_s}"
35
- end
36
- end
37
-
38
- def vbox
39
- Gtk.takeob = @ob.VBox
40
- conv_widget = Gtk::VBox.new
41
-
42
- return conv_widget
43
- end
2
+ RESPONSE_OK = RealGtk::ResponseType.Ok
3
+ RESPONSE_YES = RealGtk::ResponseType.Yes
4
+ RESPONSE_NO = RealGtk::ResponseType.No
5
+ RESPONSE_CANCEL = RealGtk::ResponseType.Cancel
6
+ RESPONSE_CLOSE = RealGtk::ResponseType.Close
7
+ RESPONSE_DELETE_EVENT = RealGtk::ResponseType.DeleteEvent
8
+ MODAL = 0
9
+
10
+ def initialize(*paras)
11
+ if Gtk.takeob
12
+ @ob = Gtk.takeob
13
+ Gtk.takeob = nil
14
+ else
15
+ splitted = self.class.to_s.split("::")
16
+ @ob = RealGtk.const_get(splitted.last).new(*paras)
17
+ end
18
+
19
+ if paras.length > 3
20
+ 3.upto(paras.length) do |count|
21
+ data = paras[count]
22
+
23
+ if data.is_a?(Array)
24
+ @ob.method(:add_button).overload(System::String, RealGtk::ResponseType).call(data[0], data[1])
25
+ elsif data.is_a?(NilClass)
26
+ #do nothing.
27
+ else
28
+ #raise "Unhandeled data: #{data.class.to_s}"
29
+ end
30
+ end
31
+ end
32
+
33
+ if !@ob
34
+ raise "Object was not spawned: #{self.class.to_s}"
35
+ end
36
+ end
37
+
38
+ def vbox
39
+ Gtk.takeob = @ob.VBox
40
+ conv_widget = Gtk::VBox.new
41
+
42
+ return conv_widget
43
+ end
44
44
  end