rwdlanguage 0.01

Sign up to get free protection for your applications and to get access to all the features.
Files changed (187) hide show
  1. data/Readme.txt +475 -0
  2. data/bin/rwdlanguage +19 -0
  3. data/code/01rwdcore/01rwdcore.rb +29 -0
  4. data/code/01rwdcore/02helptexthashbegin.rb +16 -0
  5. data/code/01rwdcore/03helptexthash.rb +21 -0
  6. data/code/01rwdcore/jumplinkcommand.rb +36 -0
  7. data/code/01rwdcore/openhelpwindow.rb +38 -0
  8. data/code/01rwdcore/returntomain.rb +10 -0
  9. data/code/01rwdcore/rundocuments.rb +10 -0
  10. data/code/01rwdcore/runeditconfiguration.rb +10 -0
  11. data/code/01rwdcore/runhelpabout.rb +15 -0
  12. data/code/01rwdcore/runopentinkerdocument.rb +7 -0
  13. data/code/01rwdcore/runtab.rb +15 -0
  14. data/code/01rwdcore/rwdtinkerversion.rb +22 -0
  15. data/code/01rwdcore/rwdwindowreturn.rb +9 -0
  16. data/code/01rwdcore/selectiontab.rb +11 -0
  17. data/code/01rwdcore/setuphelpaboutoptions.rb +15 -0
  18. data/code/01rwdcore/setuptinkerdocuments.rb +7 -0
  19. data/code/01rwdcore/test_cases.rb +158 -0
  20. data/code/01rwdcore/test_harness.rb +20 -0
  21. data/code/01rwdcore/uploadreturns.rb +65 -0
  22. data/code/dd0viewphoto/dd0viewphoto.rb +5 -0
  23. data/code/superant.com.language/0uninstallapplet.rb +22 -0
  24. data/code/superant.com.language/googlelang.rb +25 -0
  25. data/code/superant.com.language/helptexthashload.rb +22 -0
  26. data/code/superant.com.language/loadconfigurationrecord.rb +22 -0
  27. data/code/superant.com.language/loadconfigurationvariables.rb +14 -0
  28. data/code/superant.com.language/openhelpwindow.rb +24 -0
  29. data/code/superant.com.language/rubySteak.rb +40 -0
  30. data/code/superant.com.language/runappletwindow.rb +12 -0
  31. data/code/superant.com.language/runrwdshellwindow.rb +12 -0
  32. data/code/superant.com.language/runrwdwordsbackwindow.rb +10 -0
  33. data/code/superant.com.language/rwdtinkerversion.rb +10 -0
  34. data/code/superant.com.language/saveconfigurationrecord.rb +20 -0
  35. data/code/superant.com.language/test_cases.rb +20 -0
  36. data/code/superant.com.rwdtinkerbackwindow/changelocale.rb +84 -0
  37. data/code/superant.com.rwdtinkerbackwindow/diagnostictab.rb +19 -0
  38. data/code/superant.com.rwdtinkerbackwindow/initiateapplets.rb +169 -0
  39. data/code/superant.com.rwdtinkerbackwindow/installgemapplet.rb +38 -0
  40. data/code/superant.com.rwdtinkerbackwindow/installremotegem.rb +20 -0
  41. data/code/superant.com.rwdtinkerbackwindow/listgemdirs.rb +12 -0
  42. data/code/superant.com.rwdtinkerbackwindow/listgemzips.rb +55 -0
  43. data/code/superant.com.rwdtinkerbackwindow/listinstalledfiles.rb +14 -0
  44. data/code/superant.com.rwdtinkerbackwindow/listzips.rb +37 -0
  45. data/code/superant.com.rwdtinkerbackwindow/loadconfigurationrecord.rb +24 -0
  46. data/code/superant.com.rwdtinkerbackwindow/loadconfigurationvariables.rb +14 -0
  47. data/code/superant.com.rwdtinkerbackwindow/network.rb +87 -0
  48. data/code/superant.com.rwdtinkerbackwindow/openappletname.rb +19 -0
  49. data/code/superant.com.rwdtinkerbackwindow/openhelpwindowtinkerwin2.rb +40 -0
  50. data/code/superant.com.rwdtinkerbackwindow/remotegemlist.rb +24 -0
  51. data/code/superant.com.rwdtinkerbackwindow/removeapplet.rb +46 -0
  52. data/code/superant.com.rwdtinkerbackwindow/removeappletvariables.rb +52 -0
  53. data/code/superant.com.rwdtinkerbackwindow/runremoteinstall.rb +11 -0
  54. data/code/superant.com.rwdtinkerbackwindow/runrwdtinkerbackwindow.rb +15 -0
  55. data/code/superant.com.rwdtinkerbackwindow/rwdtinkerwin2version.rb +13 -0
  56. data/code/superant.com.rwdtinkerbackwindow/saveconfigurationrecord.rb +19 -0
  57. data/code/superant.com.rwdtinkerbackwindow/showlocaleoptions.rb +9 -0
  58. data/code/superant.com.rwdtinkerbackwindow/viewappletcontents.rb +23 -0
  59. data/code/superant.com.rwdtinkerbackwindow/viewgemappletcontents.rb +24 -0
  60. data/code/superant.com.rwdtinkerbackwindow/viewlogfile.rb +16 -0
  61. data/code/superant.com.thesaurus/clearhttpview3.rb +9 -0
  62. data/code/superant.com.thesaurus/listwordlookup.rb +37 -0
  63. data/code/superant.com.thesaurus/runappletwindow.rb +12 -0
  64. data/code/superant.com.words/dictlookup.rb +20 -0
  65. data/code/superant.com.words/runrwdwordsbackwindow.rb +10 -0
  66. data/code/superant.com.words/rwdtinkerversion.rb +10 -0
  67. data/code/zz0applicationend/zz0end.rb +5 -0
  68. data/configuration/rwdtinker.dist +15 -0
  69. data/configuration/rwdwlanguage.dist +21 -0
  70. data/configuration/tinkerwin2variables.dist +23 -0
  71. data/gui/00coreguibegin/applicationguitop.rwd +9 -0
  72. data/gui/frontwindow0/cc0openphoto.rwd +22 -0
  73. data/gui/frontwindowselections/00selectiontabbegin.rwd +11 -0
  74. data/gui/frontwindowselections/jumplinkcommands.rwd +15 -0
  75. data/gui/frontwindowselections/wwselectionend.rwd +3 -0
  76. data/gui/frontwindowtdocuments/00documentbegin.rwd +6 -0
  77. data/gui/frontwindowtdocuments/tinkerdocuments.rwd +14 -0
  78. data/gui/frontwindowtdocuments/zzdocumentend.rwd +8 -0
  79. data/gui/helpaboutbegin/zzzrwdlasttab.rwd +6 -0
  80. data/gui/helpaboutbegin/zzzzhelpscreenstart.rwd +3 -0
  81. data/gui/helpaboutbegin/zzzzzzhelpabouttab.rwd +15 -0
  82. data/gui/helpaboutzend/helpscreenend.rwd +3 -0
  83. data/gui/helpaboutzend/zhelpscreenstart2.rwd +3 -0
  84. data/gui/helpaboutzend/zzzzhelpabout2.rwd +15 -0
  85. data/gui/helpaboutzend/zzzzhelpscreen2end.rwd +3 -0
  86. data/gui/tinkerbackwindows/superant.com.language/1appname.rwd +4 -0
  87. data/gui/tinkerbackwindows/superant.com.language/22google.rwd +38 -0
  88. data/gui/tinkerbackwindows/superant.com.language/44germany.rwd +19 -0
  89. data/gui/tinkerbackwindows/superant.com.language/67viewconfiguration.rwd +27 -0
  90. data/gui/tinkerbackwindows/superant.com.language/77jumplinkcommands.rwd +17 -0
  91. data/gui/tinkerbackwindows/superant.com.language/z9end.rwd +6 -0
  92. data/gui/tinkerbackwindows/superant.com.tinkerbackwindow/1appname.rwd +5 -0
  93. data/gui/tinkerbackwindows/superant.com.tinkerbackwindow/40rwdlistzips.rwd +41 -0
  94. data/gui/tinkerbackwindows/superant.com.tinkerbackwindow/45installremotezip.rwd +44 -0
  95. data/gui/tinkerbackwindows/superant.com.tinkerbackwindow/50rwdlistapplets.rwd +44 -0
  96. data/gui/tinkerbackwindows/superant.com.tinkerbackwindow/60editconfiguration.rwd +30 -0
  97. data/gui/tinkerbackwindows/superant.com.tinkerbackwindow/70rwddiagnostics.rwd +29 -0
  98. data/gui/tinkerbackwindows/superant.com.tinkerbackwindow/75rwdlogfile.rwd +20 -0
  99. data/gui/tinkerbackwindows/superant.com.tinkerbackwindow/80localechanger.rwd +17 -0
  100. data/gui/tinkerbackwindows/superant.com.tinkerbackwindow/81jumplinkcommands.rwd +17 -0
  101. data/gui/tinkerbackwindows/superant.com.tinkerbackwindow/9backend.rwd +6 -0
  102. data/gui/tinkerbackwindows/superant.com.tinkerhelpwindow/1appname.rwd +31 -0
  103. data/gui/tinkerbackwindows/superant.com.tinkerhelpwindow/9end.rwd +4 -0
  104. data/gui/tinkerbackwindows/superant.com.versionwindow/1appname.rwd +19 -0
  105. data/gui/tinkerbackwindows/superant.com.versionwindow/helpaboutwindow.rwd +17 -0
  106. data/gui/tinkerbackwindows/superant.com.words/1appname.rwd +4 -0
  107. data/gui/tinkerbackwindows/superant.com.words/1dictionary.rwd +19 -0
  108. data/gui/tinkerbackwindows/superant.com.words/4thesaurus.rwd +36 -0
  109. data/gui/tinkerbackwindows/superant.com.words/77jumplinkcommands.rwd +17 -0
  110. data/gui/tinkerbackwindows/superant.com.words/z9end.rwd +6 -0
  111. data/gui/zzcoreguiend/yy9rwdend.rwd +4 -0
  112. data/init.rb +179 -0
  113. data/installed/rwdwlanguage.inf +24 -0
  114. data/installed/temp.rb +1 -0
  115. data/lang/en/rwdcore/en.po +197 -0
  116. data/lang/en/rwdlanguage/en.po +32 -0
  117. data/lang/es/rwdcore/es.po +184 -0
  118. data/lang/es/rwdlanguage/en.po +32 -0
  119. data/lang/fr/rwdcore/fr.po +169 -0
  120. data/lang/fr/rwdlanguage/en.po +32 -0
  121. data/lang/hi/rwdcore/hi.po +173 -0
  122. data/lang/hi/rwdlanguage/en.po +32 -0
  123. data/lang/ja/rwdcore/ja.po +171 -0
  124. data/lang/ja/rwdlanguage/en.po +32 -0
  125. data/lang/nl/rwdcore/nl.po +169 -0
  126. data/lang/nl/rwdlanguage/en.po +32 -0
  127. data/lib/dict.rb +438 -0
  128. data/lib/g_translate.rb +43 -0
  129. data/lib/g_translate/client.rb +84 -0
  130. data/lib/g_translate/translator.rb +57 -0
  131. data/lib/ger-eng.txt +111283 -0
  132. data/lib/oothesaurus.rb +76 -0
  133. data/lib/rconftool.rb +387 -0
  134. data/lib/rwd/browser.rb +123 -0
  135. data/lib/rwd/ftools.rb +174 -0
  136. data/lib/rwd/mime.rb +328 -0
  137. data/lib/rwd/net.rb +877 -0
  138. data/lib/rwd/ruby.rb +889 -0
  139. data/lib/rwd/rwd.rb +1425 -0
  140. data/lib/rwd/sgml.rb +236 -0
  141. data/lib/rwd/thread.rb +63 -0
  142. data/lib/rwd/tree.rb +371 -0
  143. data/lib/rwd/xml.rb +101 -0
  144. data/lib/rwdthemes/default.rwd +317 -0
  145. data/lib/rwdthemes/pda.rwd +72 -0
  146. data/lib/rwdthemes/windowslike.rwd +171 -0
  147. data/lib/rwdtinker/rwdcodedir.rb +56 -0
  148. data/lib/rwdtinker/rwdguidir.rb +57 -0
  149. data/lib/rwdtinker/rwdlangdir.rb +60 -0
  150. data/lib/rwdtinker/rwdtinkertools.rb +25 -0
  151. data/lib/zip/ioextras.rb +155 -0
  152. data/lib/zip/stdrubyext.rb +111 -0
  153. data/lib/zip/tempfile_bugfixed.rb +195 -0
  154. data/lib/zip/zip.rb +1847 -0
  155. data/lib/zip/zipfilesystem.rb +609 -0
  156. data/lib/zip/ziprequire.rb +90 -0
  157. data/rwd_files/HowTo_Language.txt +179 -0
  158. data/rwd_files/HowTo_Tinker.txt +515 -0
  159. data/rwd_files/HowTo_TinkerWin2.txt +202 -0
  160. data/rwd_files/Readme.txt +57 -0
  161. data/rwd_files/RubyWebDialogs.html +6 -0
  162. data/rwd_files/Tinkerhelptexthash.txt +84 -0
  163. data/rwd_files/favicon.ico +0 -0
  164. data/rwd_files/log/rwdtinker.log +726 -0
  165. data/rwd_files/rdoc-style.css +175 -0
  166. data/rwd_files/rwdapplications.html +76 -0
  167. data/rwd_files/rwdlanguagehelpfiles.txt +34 -0
  168. data/rwd_files/tinker.png +0 -0
  169. data/rwdconfig.dist +24 -0
  170. data/rwdlanguage.rb +1 -0
  171. data/tests/RubyGauge.rb +179 -0
  172. data/tests/checkdepends.sh +4 -0
  173. data/tests/cleancnf.sh +6 -0
  174. data/tests/makedist-rwdwlanguage.rb +56 -0
  175. data/tests/makedist.rb +66 -0
  176. data/tests/rdep.rb +354 -0
  177. data/tests/totranslate.lang +93 -0
  178. data/zips/rwdwcalc-0.63.zip +0 -0
  179. data/zips/rwdwfoldeditor-0.08.zip +0 -0
  180. data/zips/rwdwhypernote-0.16.zip +0 -0
  181. data/zips/rwdwlanguage-0.01.zip +0 -0
  182. data/zips/rwdwmovies-0.98.zip +0 -0
  183. data/zips/rwdwruby-1.08.zip +0 -0
  184. data/zips/temp.rb +1 -0
  185. data/zips/tinkerbellw-0.04.zip +0 -0
  186. data/zips/wrubyslippers-1.08.zip +0 -0
  187. metadata +246 -0
data/lib/rwd/net.rb ADDED
@@ -0,0 +1,877 @@
1
+ require "lib/rwd/ruby"
2
+ require "lib/rwd/ftools"
3
+ require "lib/rwd/mime"
4
+ require "net/http"
5
+ require "socket"
6
+ require "uri"
7
+ require "cgi"
8
+ require "md5"
9
+ require "thread"
10
+
11
+ $proxy = ENV["PROXY"] if $proxy.nil?
12
+
13
+ file = "#{home}/.evnet"
14
+ if File.file?(file)
15
+ Hash.file(file).each do |k, v|
16
+ eval "$#{k} = '#{v}'" unless k=~ /^\#/
17
+ end
18
+ end
19
+
20
+ def uri2txt(s)
21
+ # ??? Werkt niet goed
22
+ i = s.index(/%[[:digit:]]{2}/)
23
+ while not i.nil?
24
+ s = s[0..(i-1)] + s[(i+1)..(i+2)].unpack('H2').shift.to_i.chr + s[(i+3)..-1]
25
+ i = s.index(/%[[:digit:]]{2}/)
26
+ end
27
+ s
28
+ end
29
+
30
+ class TCPServer
31
+ def self.freeport(from, to, remote=false)
32
+ if windows? or cygwin?
33
+ TCPServer.freeport_windows(from, to, remote)
34
+ else
35
+ TCPServer.freeport_linux(from, to, remote)
36
+ end
37
+ end
38
+
39
+ def self.freeport_linux(from, to, remote)
40
+ ports = (from..to).to_a
41
+ port = nil
42
+ res = nil
43
+
44
+ while res.nil? and not ports.empty?
45
+ begin
46
+ port = ports[0]
47
+ ports.delete(port)
48
+
49
+ io = TCPServer.new(remote ? "0.0.0.0" : "localhost", port)
50
+
51
+ res = [port, io]
52
+ rescue
53
+ end
54
+ end
55
+
56
+ res = [nil, nil] if res.nil?
57
+
58
+ port, io = res
59
+
60
+ return port, io
61
+ end
62
+
63
+ def self.freeport_windows(from, to, remote)
64
+ ports = (from..to).to_a
65
+ port = nil
66
+ res = nil
67
+
68
+ while res.nil? and not ports.empty?
69
+ begin
70
+ port = ports.any
71
+ ports.delete(port)
72
+
73
+ io = TCPSocket.new("localhost", port)
74
+ io.close
75
+ rescue
76
+ res = port
77
+ end
78
+ end
79
+
80
+ port, io = res
81
+
82
+ return port, io
83
+ end
84
+
85
+ def self.freeport_windows2(from, to, remote)
86
+ res = nil
87
+ port = from
88
+
89
+ while res.nil? and port <= to
90
+ begin
91
+ io = TCPSocket.new("localhost", port)
92
+ io.close
93
+
94
+ port += 1
95
+ rescue
96
+ res = port
97
+ end
98
+ end
99
+
100
+ return res
101
+ end
102
+
103
+ def self.usedports(from, to)
104
+ threads = []
105
+ res = []
106
+
107
+ from.upto(to) do |port|
108
+ threads << Thread.new do
109
+ begin
110
+ io = TCPSocket.new("localhost", port)
111
+ io.close
112
+
113
+ port
114
+ rescue
115
+ nil
116
+ end
117
+ end
118
+ end
119
+
120
+ threads.each do |thread|
121
+ port = thread.value
122
+ res << port unless port.nil?
123
+ end
124
+
125
+ return res
126
+ end
127
+ end
128
+
129
+ class EVURI
130
+ attr_reader :protocol
131
+ attr_writer :protocol
132
+ attr_reader :userpass
133
+ attr_writer :userpass
134
+ attr_reader :host
135
+ attr_writer :host
136
+ attr_reader :port
137
+ attr_writer :port
138
+ attr_reader :path
139
+ attr_writer :path
140
+ attr_reader :vars
141
+ attr_writer :vars
142
+ attr_reader :anchor
143
+ attr_writer :anchor
144
+
145
+ def initialize(url)
146
+ begin
147
+ @protocol, @userpass, @host, @port, d1, @path, d2, @vars, @anchor = URI.split(url.to_s)
148
+ rescue
149
+ end
150
+
151
+ @path = "/" if (not @path.nil? and @path.empty? and @protocol == "http")
152
+
153
+ @protocol = "" if @protocol.nil?
154
+ @userpass = "" if @userpass.nil?
155
+ @host = "" if @host.nil?
156
+ @port = 0 if @port.nil?
157
+ @path = "" if @path.nil?
158
+ @vars = "" if @vars.nil?
159
+ @anchor = "" if @anchor.nil?
160
+
161
+ res = {}
162
+ @varsvolgorde = []
163
+ @vars.split(/&/).each{|var| k, v = var.split(/=/) ; res[k] = v ; @varsvolgorde << k}
164
+ @vars = res
165
+
166
+ @port = @port.to_i
167
+ end
168
+
169
+ def +(url2)
170
+ url1 = self.to_s
171
+ url2 = url2.to_s if url2.kind_of?(self.class)
172
+
173
+ return EVURI.new((URI::Generic.new(*URI.split(url1)) + URI::Generic.new(*URI.split(url2))).to_s) rescue nil
174
+ end
175
+
176
+ def to_s
177
+ protocol = @protocol
178
+ userpass = @userpass
179
+ host = @host
180
+ port = @port
181
+ path = @path
182
+ vars = varstring
183
+ anchor = @anchor
184
+
185
+ protocol = nil if @protocol.empty?
186
+ userpass = nil if @userpass.empty?
187
+ host = nil if @host.empty?
188
+ port = nil if @port.zero?
189
+ path = nil if @path.empty?
190
+ vars = nil if @vars.empty?
191
+ anchor = nil if @anchor.empty?
192
+
193
+ res = URI::HTTP.new(@protocol, @userpass, @host, port, nil, @path, nil, vars, @anchor).to_s.from_html
194
+
195
+ res.gsub!(/@/, "") if (@userpass.nil? or @userpass.empty?)
196
+
197
+ res.gsub!(/\#$/, "")
198
+
199
+ return res
200
+ end
201
+
202
+ def localname
203
+ protocol = @protocol
204
+ userpass = @userpass
205
+ host = @host
206
+ port = @port
207
+ path = @path
208
+ vars = varstring
209
+ anchor = @anchor
210
+
211
+ protocol = nil if @protocol.empty?
212
+ userpass = nil if @userpass.empty?
213
+ host = nil if @host.empty?
214
+ port = nil if @port.zero?
215
+ path = nil if @path.empty?
216
+ vars = nil if @vars.empty?
217
+ anchor = nil if @anchor.empty?
218
+
219
+ path = "#{path}." if path =~ /[\/\\]$/
220
+
221
+ f = MD5.new(protocol.to_s + userpass.to_s + host.to_s + port.to_s + File.dirname(path.to_s) + vars.to_s).to_s
222
+ e = File.basename(path.to_s).gsub(/[^\w\.\-]/, "_").gsub(/_+/, "_")
223
+ res = f + "." + e
224
+ res.gsub!(/[^\w]+$/, "")
225
+
226
+ return res
227
+ end
228
+
229
+ def varstring
230
+ res = []
231
+ vars = @vars.dup
232
+
233
+ @varsvolgorde.each do |k|
234
+ if vars.include?(k)
235
+ v = vars[k]
236
+ vars.delete(k)
237
+
238
+ res << (v.nil? ? k : "#{k}=#{v}")
239
+ end
240
+ end
241
+
242
+ res.concat(vars.collect{|k, v| v.nil? ? k : "#{k}=#{v}"})
243
+
244
+ return res.join("&")
245
+ end
246
+ end
247
+
248
+ class HTTPClient
249
+ @@versie = 1
250
+ @@mutex = Mutex.new
251
+ @@hosts = {}
252
+
253
+ class Header
254
+ attr_reader :header
255
+ attr_reader :protocol
256
+ attr_reader :code
257
+ attr_reader :text
258
+
259
+ def initialize(header)
260
+ @header = {}
261
+
262
+ if not header.nil?
263
+ firstline, rest = header.split(/\r*\n/, 2)
264
+
265
+ @protocol, @code, @text = firstline.split(/ */, 3)
266
+
267
+ @code = @code.to_i
268
+
269
+ if not rest.nil?
270
+ rest.split(/\r*\n/).each do |line|
271
+ key, value = line.split(/ /, 2)
272
+ @header[key.sub(/:$/, "").downcase] = value
273
+ end
274
+ end
275
+ end
276
+ end
277
+
278
+ def to_s
279
+ res = ""
280
+
281
+ res << "%s %s %s\n" % [@protocol, @code, @text]
282
+
283
+ @header.each do |k, v|
284
+ res << "%s=%s\n" % [k, v]
285
+ end
286
+
287
+ return res
288
+ end
289
+ end
290
+
291
+ class Chunk
292
+ def initialize(data)
293
+ @data = ""
294
+ line, data = data.split(/\r*\n/, 2)
295
+ size, ext = line.split(/;/, 2)
296
+ size = size.hex
297
+ while not size.zero? and not data.nil?
298
+ @data += data[0..(size-1)]
299
+ data = data[size..-1]
300
+ if not data.nil?
301
+ data.gsub!(/^\r*\n/, "")
302
+ line, data = data.split(/\r*\n/, 2)
303
+ size, ext = line.split(/;/, 2)
304
+ size = size.hex
305
+ end
306
+ end
307
+ end
308
+
309
+ def to_s
310
+ @data
311
+ end
312
+ end
313
+
314
+ class NoAddressException < StandardError
315
+ end
316
+
317
+ def self.getaddress(host)
318
+ if not @@hosts.include?(host)
319
+ @@hosts[host] = ""
320
+ evtimeout(5) do # ??? Doet 'ut niet?...
321
+ @@hosts[host] = IPSocket.getaddress(host)
322
+ end
323
+ end
324
+
325
+ raise NoAddressException, host if @@hosts[host].empty?
326
+
327
+ @@hosts[host]
328
+ end
329
+
330
+ def self.head(uri, form={}, recursive=true)
331
+ header = Header.new(nil)
332
+
333
+ begin
334
+ while not uri.nil?
335
+ uri = EVURI.new(uri) if uri.kind_of? String
336
+ host = uri.host
337
+ port = uri.port
338
+
339
+ if $proxy.nil? or $proxy.empty? or host == "localhost"
340
+ io = nil
341
+
342
+ @@mutex.synchronize do
343
+ io = TCPSocket.new(getaddress(host), port.zero? ? 80 : port)
344
+ end
345
+
346
+ io.write("HEAD #{uri.path or '/'}#{uri.varstring.empty? ? '' : '?' + uri.varstring} HTTP/1.0\r\nHost: #{host}\r\n\r\n")
347
+ else
348
+ proxy = EVURI.new($proxy)
349
+ io = TCPSocket.new(proxy.host, proxy.port.zero? ? 8080 : proxy.port)
350
+
351
+ io.write("HEAD #{uri} HTTP/1.0\r\n#{"Proxy-Authorization: Basic "+$proxy_auth+"\r\n" if not $proxy_auth.nil?}\r\n\r\n")
352
+ end
353
+
354
+ io.close_write
355
+
356
+ res = io.read
357
+
358
+ io.close_read
359
+
360
+ header, data = nil, nil
361
+ header, data = res.split(/\r*\n\r*\n/, 2) if not res.nil?
362
+ header = Header.new(header)
363
+
364
+ if recursive and header.header["location"] != uri.to_s
365
+ uri = EVURI.new(uri) + header.header["location"]
366
+ else
367
+ uri = nil
368
+ end
369
+ end
370
+ rescue Errno::ECONNRESET, Errno::EHOSTUNREACH => e
371
+ $stderr.puts e.message
372
+ sleep 1
373
+ retry
374
+ rescue Errno::ECONNREFUSED => e
375
+ data = nil
376
+ rescue NoAddressException => e
377
+ $stderr.puts e.message
378
+ header = Header.new(nil)
379
+ end
380
+
381
+ GC.start
382
+
383
+ return header
384
+ end
385
+
386
+ def self.get(uri, httpheader={}, form={})
387
+ post = Array.new
388
+ form.each_pair do |var, value|
389
+ post << "#{var.to_html}=#{value.to_html}"
390
+ end
391
+ post = post.join("?")
392
+
393
+ data = nil
394
+
395
+ begin
396
+ while not uri.nil?
397
+ uri = EVURI.new(uri) if uri.kind_of? String
398
+ host = uri.host
399
+ port = uri.port
400
+
401
+ if $proxy.nil? or $proxy.empty? or host == "localhost"
402
+ io = nil
403
+ @@mutex.synchronize do
404
+ io = TCPSocket.new(getaddress(host), port.zero? ? 80 : port)
405
+ end
406
+
407
+ if post.empty?
408
+ io.write "GET %s%s HTTP/1.0\r\n" % [(uri.path or '/'), (uri.varstring.empty? ? '' : '?' + uri.varstring)]
409
+ else
410
+ io.write "POST %s%s HTTP/1.0\r\n" % [(uri.path or '/'), (uri.varstring.empty? ? '' : '?' + uri.varstring)]
411
+ end
412
+ else
413
+ proxy = EVURI.new($proxy)
414
+ io = TCPSocket.new(proxy.host, proxy.port.zero? ? 8080 : proxy.port)
415
+
416
+ if post.empty?
417
+ io.write "GET %s HTTP/1.0\r\n" % uri
418
+ else
419
+ io.write "POST %s HTTP/1.0\r\n" % uri
420
+ end
421
+ end
422
+
423
+ io.write "Host: %s\r\n" % host
424
+ io.write "User-Agent: xyz\r\n"
425
+ io.write "Proxy-Authorization: Basic %s\r\n" % $proxy_auth unless $proxy_auth.nil?
426
+ #io.write "Accept-Encoding: deflate\r\n"
427
+ #io.write "Accept-Charset: ISO-8859-1\r\n"
428
+ io.write "Connection: close\r\n"
429
+ io.write "Content-Type: application/x-www-form-urlencoded\r\n" unless post.empty?
430
+ io.write "Content-Length: %s\r\n" % post.length unless post.empty?
431
+ httpheader.each do |k, v|
432
+ $stderr.puts "%s: %s\r\n" % [k, v]
433
+ io.write "%s: %s\r\n" % [k, v]
434
+ end
435
+ io.write "\r\n"
436
+ io.write post unless post.empty?
437
+
438
+ io.close_write
439
+
440
+ res = io.read
441
+
442
+ io.close_read
443
+
444
+ header, data = nil, nil
445
+ header, data = res.split(/\r*\n\r*\n/, 2) if not res.nil?
446
+
447
+ header = Header.new(header)
448
+ length = header.header["content-length"]
449
+ data = "" if length == "0"
450
+
451
+ if header.header["location"] != uri.to_s
452
+ uri = EVURI.new(uri) + header.header["location"]
453
+ else
454
+ uri = nil
455
+ end
456
+
457
+ if header.header["transfer-encoding"] == "chunked"
458
+ data = Chunk.new(data).to_s if not data.nil?
459
+ end
460
+
461
+ #if header.header["content-encoding"] == "gzip"
462
+ #data = "gzip -d".exec(data) if not data.nil?
463
+ #end
464
+
465
+ data = nil unless header.code == 200
466
+ end
467
+ rescue Errno::ECONNRESET, Errno::EHOSTUNREACH => e
468
+ $stderr.puts e.message
469
+ sleep 1
470
+ retry
471
+ rescue Errno::ECONNREFUSED => e
472
+ data = nil
473
+ rescue NoAddressException, Errno::ECONNREFUSED => e
474
+ $stderr.puts e.message
475
+ data = nil
476
+ end
477
+
478
+ GC.start
479
+
480
+ return data
481
+ end
482
+
483
+ def self.head_from_cache(uri, form={})
484
+ from_cache("head", uri, form)
485
+ end
486
+
487
+ def self.get_from_cache(uri, form={})
488
+ from_cache("get", uri, form)
489
+ end
490
+
491
+ def self.from_cache(action, uri, form)
492
+ loc = uri.to_s + form.sort.inspect
493
+ hash = MD5.new("#{@@versie} #{loc}")
494
+
495
+ dir = "#{temp}/evcache.#{user}/httpclient.#{action}"
496
+ file = "#{dir}/#{hash}"
497
+ data = nil
498
+
499
+ File.mkpath(dir)
500
+
501
+ expire = 356*24*60*60
502
+
503
+ if File.file?(file) and (Time.new.to_f - File.stat(file).mtime.to_f < expire)
504
+ @@mutex.synchronize do
505
+ File.open(file, "rb") {|f| data = f.read}
506
+ end
507
+ else
508
+ data = method(action).call(uri, form)
509
+
510
+ if not data.nil?
511
+ @@mutex.synchronize do
512
+ File.open(file, "wb") {|f| f.write data}
513
+ end
514
+ end
515
+ end
516
+
517
+ return data
518
+ end
519
+ end
520
+
521
+ class RequestGet < Hash
522
+ def initialize(data)
523
+ CGI.parse(data).each do |k, v|
524
+ self[k] = v
525
+ end
526
+ end
527
+ end
528
+
529
+ class RequestPost < Hash
530
+ def initialize(data)
531
+ CGI.parse(data).each do |k, v|
532
+ self[k] = v
533
+ end
534
+ end
535
+ end
536
+
537
+ class RequestRequest
538
+ attr_reader :method
539
+ attr_reader :uri
540
+ attr_reader :path
541
+ attr_reader :data
542
+ attr_reader :protocol
543
+
544
+ def initialize(firstline)
545
+ @method, @uri, @protocol = firstline.split(/ /)
546
+ @path, @data = @uri.split(/\?/)
547
+ @data = "" if @data.nil? # TODO
548
+
549
+ # i = @path.index(/%[[:digit:]]{2}/)
550
+ # while not i.nil?
551
+ # @path = @path[0..(i-1)] + @path[(i+1)..(i+2)].unpack('H2').shift.to_i.chr + @path[(i+3)..-1]
552
+ # i = @path.index(/%[[:digit:]]{2}/)
553
+ # end
554
+ end
555
+
556
+ def to_s
557
+ "#{@method} #{@uri} #{@protocol}\r\n"
558
+ end
559
+
560
+ def inspect
561
+ "(RequestRequest: %s)" % [@method, @path, @data, @protocol].join(", ")
562
+ end
563
+ end
564
+
565
+ def url_unescape(string)
566
+ string.tr('+', ' ').gsub(/((?:%[0-9a-fA-F]{2})+)/n) do
567
+ [$1.delete('%')].pack('H*')
568
+ end
569
+ end
570
+
571
+ class Request < Hash
572
+ attr_reader :peeraddr
573
+ attr_reader :request
574
+ attr_reader :cookies
575
+ attr_reader :vars
576
+ attr_reader :user
577
+ attr_writer :user
578
+
579
+ def initialize(io)
580
+ @io = io
581
+
582
+ firstline = @io.gets
583
+
584
+ return if firstline.nil?
585
+
586
+ @request = RequestRequest.new(firstline.strip)
587
+
588
+ line = @io.gets
589
+ line = line.strip unless line.nil?
590
+ while not line.nil? and not line.empty?
591
+ key, value = line.split(" ", 2)
592
+ self[key.sub(/:$/, "").downcase] = value
593
+
594
+ line = @io.gets
595
+ line = line.strip unless line.nil?
596
+ end
597
+
598
+ cookie = self["cookie"]
599
+ cookie = "" if cookie.nil?
600
+ @cookies = {}
601
+ cookie.split(/;/).each do |s|
602
+ k, v = s.strip.split(/=/, 2)
603
+ @cookies[k] = v
604
+ end
605
+
606
+ if not @request.method.nil?
607
+ case @request.method.upcase
608
+ when "HEAD"
609
+ when "GET"
610
+ @vars = RequestGet.new(@request.data.nil? ? "" : @request.data)
611
+ when "POST"
612
+ data = (@io.read(self["content-length"].to_i) or "")
613
+ # data = url_unescape(data)
614
+ @vars = RequestPost.new((self["content-type"] == "application/x-www-form-urlencoded") ? data : "")
615
+ else
616
+ $stderr.puts "Unknown request ('#{firstline}')."
617
+ end
618
+
619
+ $rwdtinkerlog.debug data
620
+
621
+ end
622
+
623
+ @peeraddr = @io.peeraddr
624
+
625
+ @pda = false
626
+ @pda = true if (self.include?("user-agent") and self["user-agent"].downcase.include?("windows ce"))
627
+ @pda = true if (self.include?("user-agent") and self["user-agent"].downcase.include?("handhttp"))
628
+
629
+ @io.close_read
630
+ end
631
+
632
+ def pda?
633
+ @pda
634
+ end
635
+
636
+ def to_s
637
+ res = @request.to_s
638
+ self.each do |k, v|
639
+ res << "#{k}: #{v}\r\n"
640
+ end
641
+ res
642
+ end
643
+
644
+ def inspect
645
+ "(Request: %s)" % [@peeraddr, @request.inspect, @vars.inspect, @cookies.inspect, super].join(", ")
646
+ end
647
+ end
648
+
649
+ class Response < Hash
650
+ attr_writer :response
651
+ attr_writer :file
652
+ attr_reader :cookies
653
+ attr_reader :stop
654
+ attr_reader :at_stop
655
+
656
+ def initialize(io)
657
+ @io = io
658
+ @response = "HTTP/1.0 200 OK"
659
+ @cookies = {}
660
+ @data = ""
661
+ @syncd = false
662
+ @stop = false
663
+ @at_stop = lambda{}
664
+ @file = nil
665
+ end
666
+
667
+ def flush
668
+ sync
669
+
670
+ if @file
671
+ File.open(@file, "rb") do |f|
672
+ while data = f.read(10_000)
673
+ @io.write data
674
+ end
675
+ end
676
+ end
677
+
678
+ @io.close
679
+ end
680
+
681
+ def to_s
682
+ res = "#{@response}\r\n"
683
+ self.each do |k, v|
684
+ res << "#{k}: #{v}\r\n"
685
+ end
686
+
687
+ @cookies.each do |k, v|
688
+ res << "Set-Cookie: %s=%s;\r\n" % [k, v]
689
+ end
690
+
691
+ res
692
+ end
693
+
694
+ def sync
695
+ size = (@data or "").length
696
+
697
+ if @file
698
+ ext = @file.scan(/\.[^\.]*$/)
699
+ ext = ext.shift
700
+ ext = ext[1..-1] unless ext.nil?
701
+ mimetype = EVMime::MimeType[ext]
702
+
703
+ self["Content-Type"] = mimetype unless mimetype.nil?
704
+
705
+ size += File.size(@file) if File.file?(@file)
706
+ end
707
+
708
+ self["Content-Length"] = size
709
+
710
+ @io.write("#{to_s}\r\n") unless @syncd
711
+ @io.write(@data)
712
+ @data = ""
713
+ @syncd = true
714
+ end
715
+
716
+ def << (s)
717
+ @data << s
718
+ end
719
+
720
+ def clean
721
+ @data = ""
722
+ end
723
+
724
+ def inspect
725
+ "(Response: %s)" % [@response, @data].join(", ")
726
+ end
727
+
728
+ def stop(&block)
729
+ @stop = true
730
+ @at_stop = block unless block.nil?
731
+ end
732
+
733
+ def stop?
734
+ @stop
735
+ end
736
+ end
737
+
738
+ class HTTPServerException < Exception
739
+ end
740
+
741
+ class HTTPServer
742
+ def self.serve(portio=80, remote=false, auth=nil, realm="rwd/net")
743
+ port, server = portio
744
+
745
+ begin
746
+ server = TCPServer.new(remote ? "0.0.0.0" : "localhost", port) if server.nil?
747
+ if $DEBUG
748
+ $stderr.puts "Just point your browser to http://localhost:#{port}/ ..."
749
+ end
750
+ rescue
751
+ server = nil
752
+
753
+ $stderr.puts "Port #{port} is in use."
754
+ end
755
+
756
+ if not server.nil?
757
+ count = 0
758
+
759
+ at_exit do
760
+ #$stderr.puts "Received #{count} requests"
761
+ end
762
+
763
+ serverthread =
764
+ Thread.new do
765
+ mutex = Mutex.new
766
+
767
+ Thread.current["threads"] = []
768
+
769
+ every(1, Thread.current) do |thread|
770
+ mutex.synchronize do
771
+ thread["threads"].delete_if{|t| (not t.alive?)}
772
+ end
773
+ end
774
+
775
+ loop do
776
+ io = server.accept
777
+ count += 1
778
+
779
+ thread =
780
+ Thread.new(Thread.current, count) do |parentthread, count2|
781
+ stop = false
782
+
783
+ begin
784
+ begin
785
+ req = Request.new(io)
786
+ resp = Response.new(io)
787
+ rescue
788
+ raise HTTPServerException
789
+ end
790
+
791
+ begin
792
+ ip = req.peeraddr[3]
793
+ rescue NameError
794
+ raise HTTPServerException
795
+ end
796
+
797
+ if (not remote) or (remote and (auth.nil? or auth.empty? or authenticate(auth, realm, req, resp)))
798
+ # $stderr.puts "#{count2} #{Time.new.strftime("%Y-%m-%d %H:%M:%S")} #{ip} #{req.user} #{req.request.to_s.strip}"
799
+ 1 == 1
800
+ begin
801
+ yield(req, resp)
802
+ rescue Exception => e
803
+ mutex.synchronize do
804
+ $stderr.puts e.class.to_s + ": " + e.message
805
+ $stderr.puts e.backtrace.collect{|s| "\t"+s}.join("\n")
806
+ end
807
+ resp["Content-Type"] = "text/plain"
808
+ resp.response = "HTTP/1.0 200 ???"
809
+ resp.clean
810
+ resp << e.class.to_s + ": " + e.message
811
+ resp << "\n"
812
+ resp << "\n"
813
+ resp << e.backtrace.collect{|s| "\t"+s}.join("\n")
814
+ resp << "\n"
815
+ resp << "\n"
816
+ resp << "(You can use the back button and stop the application properly, if appropriate.)"
817
+ end
818
+
819
+ stop = true if resp.stop?
820
+ end
821
+
822
+ begin
823
+ resp.flush
824
+ rescue
825
+ raise HTTPServerException
826
+ end
827
+ rescue HTTPServerException
828
+ end
829
+
830
+ parentthread["stop"] = resp if stop
831
+ end
832
+
833
+ mutex.synchronize do
834
+ Thread.current["threads"] << thread
835
+ end
836
+ end
837
+ end
838
+
839
+ sleep 0.1 while not serverthread["stop"]
840
+
841
+ serverthread["threads"].each {|t| t.join}
842
+
843
+ serverthread["stop"].at_stop.call
844
+
845
+ serverthread.kill
846
+ end
847
+ end
848
+
849
+ def self.authenticate(auth, realm, req, resp)
850
+ if auth.kind_of? String
851
+ file = "#{home}/#{auth}"
852
+ auths = {}
853
+ auths = Hash.file(file) if File.file?(file)
854
+ else
855
+ auths = auth
856
+ end
857
+
858
+ authuserpassword = req["authorization"]
859
+ if not authuserpassword.nil?
860
+ authtype, userpassword = authuserpassword.split(/ /)
861
+ if authtype == "Basic" and not userpassword.nil?
862
+ u, p = userpassword.unpack("m").shift.split(/:/)
863
+ end
864
+ end
865
+
866
+ ok = (auths.include?(u) and auths[u] == p)
867
+
868
+ unless ok
869
+ resp["WWW-Authenticate"] = "Basic realm=\"#{realm}\""
870
+ resp.response = "HTTP/1.0 401 Unauthorized"
871
+ end
872
+
873
+ req.user = u
874
+
875
+ return ok
876
+ end
877
+ end