rwdeliza 0.03

Sign up to get free protection for your applications and to get access to all the features.
Files changed (222) hide show
  1. data/ElizaData/database/db.1 +7015 -0
  2. data/ElizaData/database/db.10 +7001 -0
  3. data/ElizaData/database/db.11 +7001 -0
  4. data/ElizaData/database/db.12 +7003 -0
  5. data/ElizaData/database/db.13 +7003 -0
  6. data/ElizaData/database/db.14 +7008 -0
  7. data/ElizaData/database/db.15 +7001 -0
  8. data/ElizaData/database/db.16 +7001 -0
  9. data/ElizaData/database/db.17 +7001 -0
  10. data/ElizaData/database/db.18 +7001 -0
  11. data/ElizaData/database/db.19 +7001 -0
  12. data/ElizaData/database/db.2 +7001 -0
  13. data/ElizaData/database/db.20 +5467 -0
  14. data/ElizaData/database/db.3 +7001 -0
  15. data/ElizaData/database/db.4 +7001 -0
  16. data/ElizaData/database/db.5 +7001 -0
  17. data/ElizaData/database/db.6 +7001 -0
  18. data/ElizaData/database/db.7 +7001 -0
  19. data/ElizaData/database/db.8 +7001 -0
  20. data/ElizaData/database/db.9 +7001 -0
  21. data/ElizaData/responses/hello.res +1 -0
  22. data/ElizaData/responses/i_agree.res +1 -0
  23. data/ElizaData/responses/i_am_listening_to_you.res +1 -0
  24. data/ElizaData/responses/please_explain.res +1 -0
  25. data/ElizaData/responses/thank_you.res +1 -0
  26. data/ElizaData/tiny.dict +211 -0
  27. data/ElizaData/words/adjectives1.words +906 -0
  28. data/ElizaData/words/adjectives2w.words +1 -0
  29. data/ElizaData/words/noun0.words +15 -0
  30. data/ElizaData/words/noun1.words +1391 -0
  31. data/ElizaData/words/noun2.words +1924 -0
  32. data/ElizaData/words/noun4.words +330 -0
  33. data/ElizaData/words/pronoun1.words +6 -0
  34. data/ElizaData/words/verb4.words +350 -0
  35. data/ElizaData/words/verb42.words +391 -0
  36. data/ElizaData/words/verb42w.words +1 -0
  37. data/ElizaData/words/verb43.words +402 -0
  38. data/ElizaData/words/verb43w.words +1 -0
  39. data/ElizaData/words/verb45.words +452 -0
  40. data/ElizaData/words/verb4w.words +1 -0
  41. data/ElizaData/words/verb5.words +13 -0
  42. data/ElizaData/words/verb61.words +35 -0
  43. data/ElizaData/words/verb62.words +41 -0
  44. data/ElizaData/words/verb83.words +17 -0
  45. data/Readme.txt +462 -0
  46. data/bin/rwdeliza +19 -0
  47. data/code/01rwdcore/01rwdcore.rb +29 -0
  48. data/code/01rwdcore/02helptexthashbegin.rb +4 -0
  49. data/code/01rwdcore/03helptexthash.rb +23 -0
  50. data/code/01rwdcore/04helptextend.rb +6 -0
  51. data/code/01rwdcore/jumplinkcommand.rb +26 -0
  52. data/code/01rwdcore/openhelpwindow.rb +31 -0
  53. data/code/01rwdcore/returntomain.rb +10 -0
  54. data/code/01rwdcore/rundocuments.rb +10 -0
  55. data/code/01rwdcore/runeditconfiguration.rb +10 -0
  56. data/code/01rwdcore/runhelpabout.rb +10 -0
  57. data/code/01rwdcore/runopentinkerdocument.rb +7 -0
  58. data/code/01rwdcore/rwdtinkerversion.rb +22 -0
  59. data/code/01rwdcore/rwdwindowreturn.rb +9 -0
  60. data/code/01rwdcore/selectiontab.rb +9 -0
  61. data/code/01rwdcore/setuphelpaboutoptions.rb +13 -0
  62. data/code/01rwdcore/setuptinkerdocuments.rb +6 -0
  63. data/code/01rwdcore/test_cases.rb +109 -0
  64. data/code/01rwdcore/test_harness.rb +13 -0
  65. data/code/01rwdcore/uploadreturns.rb +62 -0
  66. data/code/dd0viewphoto/dd0viewphoto.rb +3 -0
  67. data/code/superant.com.rwdeliza/0uninstallapplet.rb +10 -0
  68. data/code/superant.com.rwdeliza/eliza01.rb +45 -0
  69. data/code/superant.com.rwdeliza/helptexthashrwdeliza.rb +39 -0
  70. data/code/superant.com.rwdeliza/openhelpwindowrwdeliza.rb +23 -0
  71. data/code/superant.com.rwdeliza/runrwdshellwindow.rb +12 -0
  72. data/code/superant.com.rwdeliza/rwdtinkerversion.rb +10 -0
  73. data/code/superant.com.rwdeliza/tagsentence.rb +39 -0
  74. data/code/superant.com.rwdtinkerbackwindow/diagnostictab.rb +19 -0
  75. data/code/superant.com.rwdtinkerbackwindow/helptexthashtinkerwin2.rb +61 -0
  76. data/code/superant.com.rwdtinkerbackwindow/initiateapplets.rb +240 -0
  77. data/code/superant.com.rwdtinkerbackwindow/installgemapplet.rb +34 -0
  78. data/code/superant.com.rwdtinkerbackwindow/installremotegem.rb +20 -0
  79. data/code/superant.com.rwdtinkerbackwindow/listgemdirs.rb +12 -0
  80. data/code/superant.com.rwdtinkerbackwindow/listgemzips.rb +53 -0
  81. data/code/superant.com.rwdtinkerbackwindow/listinstalledfiles.rb +12 -0
  82. data/code/superant.com.rwdtinkerbackwindow/listzips.rb +27 -0
  83. data/code/superant.com.rwdtinkerbackwindow/loadconfigurationrecord.rb +22 -0
  84. data/code/superant.com.rwdtinkerbackwindow/loadconfigurationvariables.rb +14 -0
  85. data/code/superant.com.rwdtinkerbackwindow/network.rb +87 -0
  86. data/code/superant.com.rwdtinkerbackwindow/openappletname.rb +19 -0
  87. data/code/superant.com.rwdtinkerbackwindow/openhelpwindowtinkerwin2.rb +38 -0
  88. data/code/superant.com.rwdtinkerbackwindow/remotegemlist.rb +24 -0
  89. data/code/superant.com.rwdtinkerbackwindow/removeapplet.rb +46 -0
  90. data/code/superant.com.rwdtinkerbackwindow/removeappletvariables.rb +52 -0
  91. data/code/superant.com.rwdtinkerbackwindow/runremoteinstall.rb +11 -0
  92. data/code/superant.com.rwdtinkerbackwindow/runrwdtinkerbackwindow.rb +15 -0
  93. data/code/superant.com.rwdtinkerbackwindow/rwdtinkerwin2version.rb +13 -0
  94. data/code/superant.com.rwdtinkerbackwindow/saveconfigurationrecord.rb +19 -0
  95. data/code/superant.com.rwdtinkerbackwindow/viewappletcontents.rb +22 -0
  96. data/code/superant.com.rwdtinkerbackwindow/viewgemappletcontents.rb +24 -0
  97. data/code/superant.com.words/dictlookup.rb +20 -0
  98. data/code/superant.com.words/runfortunewindow.rb +14 -0
  99. data/code/superant.com.words/runrwdwordsbackwindow.rb +10 -0
  100. data/code/superant.com.words/runrwdwordsversion.rb +14 -0
  101. data/code/superant.com.words/rwdtinkerversion.rb +10 -0
  102. data/code/zz0applicationend/zz0end.rb +4 -0
  103. data/configuration/language.dist +8 -0
  104. data/configuration/rwdapplicationidentity.dist +3 -0
  105. data/configuration/rwdtinker.dist +18 -0
  106. data/configuration/rwdweliza-0.03.dist +31 -0
  107. data/configuration/tinkerwin2variables.dist +17 -0
  108. data/gui/00coreguibegin/applicationguitop.rwd +4 -0
  109. data/gui/frontwindow0/cc0openphoto.rwd +22 -0
  110. data/gui/frontwindowselections/00selectiontabbegin.rwd +11 -0
  111. data/gui/frontwindowselections/jumplinkcommands.rwd +15 -0
  112. data/gui/frontwindowselections/wwselectionend.rwd +3 -0
  113. data/gui/frontwindowtdocuments/00documentbegin.rwd +6 -0
  114. data/gui/frontwindowtdocuments/tinkerdocuments.rwd +14 -0
  115. data/gui/frontwindowtdocuments/zzdocumentend.rwd +8 -0
  116. data/gui/helpaboutbegin/zzzrwdlasttab.rwd +6 -0
  117. data/gui/helpaboutbegin/zzzzhelpscreenstart.rwd +3 -0
  118. data/gui/helpaboutbegin/zzzzzzhelpabouttab.rwd +15 -0
  119. data/gui/helpaboutzend/helpscreenend.rwd +3 -0
  120. data/gui/helpaboutzend/zhelpscreenstart2.rwd +3 -0
  121. data/gui/helpaboutzend/zzzzhelpabout2.rwd +15 -0
  122. data/gui/helpaboutzend/zzzzhelpscreen2end.rwd +3 -0
  123. data/gui/tinkerbackwindows/superant.com.refreshwindow/fortunerefreshwindowtwo.rwd +9 -0
  124. data/gui/tinkerbackwindows/superant.com.rwdeliza/1appname.rwd +5 -0
  125. data/gui/tinkerbackwindows/superant.com.rwdeliza/1eliza.rwd +21 -0
  126. data/gui/tinkerbackwindows/superant.com.rwdeliza/4sentance.rwd +21 -0
  127. data/gui/tinkerbackwindows/superant.com.rwdeliza/98jumplinkcommands.rwd +17 -0
  128. data/gui/tinkerbackwindows/superant.com.rwdeliza/zbackend.rwd +6 -0
  129. data/gui/tinkerbackwindows/superant.com.rwdschedulebackwindow/1appname.rwd +5 -0
  130. data/gui/tinkerbackwindows/superant.com.rwdschedulebackwindow/20downloadftp.rwd +45 -0
  131. data/gui/tinkerbackwindows/superant.com.rwdschedulebackwindow/67viewconfiguration.rwd +29 -0
  132. data/gui/tinkerbackwindows/superant.com.rwdschedulebackwindow/70rwddiagnostics.rwd +16 -0
  133. data/gui/tinkerbackwindows/superant.com.rwdschedulebackwindow/m01menubegin.rwd +18 -0
  134. data/gui/tinkerbackwindows/superant.com.rwdschedulebackwindow/zvbackend.rwd +6 -0
  135. data/gui/tinkerbackwindows/superant.com.tinkerbackwindow/1appname.rwd +5 -0
  136. data/gui/tinkerbackwindows/superant.com.tinkerbackwindow/40rwdlistzips.rwd +41 -0
  137. data/gui/tinkerbackwindows/superant.com.tinkerbackwindow/45installremotezip.rwd +44 -0
  138. data/gui/tinkerbackwindows/superant.com.tinkerbackwindow/50rwdlistapplets.rwd +44 -0
  139. data/gui/tinkerbackwindows/superant.com.tinkerbackwindow/60editconfiguration.rwd +30 -0
  140. data/gui/tinkerbackwindows/superant.com.tinkerbackwindow/70rwddiagnostics.rwd +29 -0
  141. data/gui/tinkerbackwindows/superant.com.tinkerbackwindow/81jumplinkcommands.rwd +17 -0
  142. data/gui/tinkerbackwindows/superant.com.tinkerbackwindow/9backend.rwd +6 -0
  143. data/gui/tinkerbackwindows/superant.com.tinkerhelpwindow/1appname.rwd +31 -0
  144. data/gui/tinkerbackwindows/superant.com.tinkerhelpwindow/9end.rwd +4 -0
  145. data/gui/tinkerbackwindows/superant.com.versionwindow/1appname.rwd +19 -0
  146. data/gui/tinkerbackwindows/superant.com.versionwindow/helpaboutwindow.rwd +17 -0
  147. data/gui/tinkerbackwindows/superant.com.words/1appname.rwd +4 -0
  148. data/gui/tinkerbackwindows/superant.com.words/1dictionary.rwd +19 -0
  149. data/gui/tinkerbackwindows/superant.com.words/3rwdfortune.rwd +14 -0
  150. data/gui/tinkerbackwindows/superant.com.words/77jumplinkcommands.rwd +17 -0
  151. data/gui/tinkerbackwindows/superant.com.words/z9end.rwd +6 -0
  152. data/gui/zzcoreguiend/yy9rwdend.rwd +4 -0
  153. data/init.rb +277 -0
  154. data/installed/rwdweliza-0.03.inf +24 -0
  155. data/installed/temp.rb +1 -0
  156. data/lang/en/rwdcore/languagefile.rb +58 -0
  157. data/lang/es/rwdcore/languagefile-es.rb +62 -0
  158. data/lang/fr/rwdcore/languagefile.rb +64 -0
  159. data/lang/jp/rwdcore/languagefile.rb +72 -0
  160. data/lang/nl/rwdcore/languagefile.rb +75 -0
  161. data/lib/dict.rb +438 -0
  162. data/lib/druida.rb +499 -0
  163. data/lib/hashslice.rb +71 -0
  164. data/lib/linguistics.rb +360 -0
  165. data/lib/linguistics/en.rb +1601 -0
  166. data/lib/linguistics/en/infinitive.rb +1148 -0
  167. data/lib/linguistics/en/linkparser.rb +142 -0
  168. data/lib/linguistics/en/wordnet.rb +253 -0
  169. data/lib/linguistics/iso639.rb +456 -0
  170. data/lib/linkparser.rb +461 -0
  171. data/lib/linkparser/connection.rb +81 -0
  172. data/lib/linkparser/connector.rb +201 -0
  173. data/lib/linkparser/definition.rb +225 -0
  174. data/lib/linkparser/dictionary.rb +208 -0
  175. data/lib/linkparser/linkage.rb +185 -0
  176. data/lib/linkparser/log.rb +39 -0
  177. data/lib/linkparser/sentence.rb +79 -0
  178. data/lib/linkparser/utils.rb +540 -0
  179. data/lib/linkparser/word.rb +92 -0
  180. data/lib/rconftool.rb +380 -0
  181. data/lib/rwd/browser.rb +123 -0
  182. data/lib/rwd/ftools.rb +174 -0
  183. data/lib/rwd/mime.rb +328 -0
  184. data/lib/rwd/net.rb +866 -0
  185. data/lib/rwd/ruby.rb +889 -0
  186. data/lib/rwd/rwd.rb +1942 -0
  187. data/lib/rwd/sgml.rb +236 -0
  188. data/lib/rwd/thread.rb +63 -0
  189. data/lib/rwd/tree.rb +371 -0
  190. data/lib/rwd/xml.rb +101 -0
  191. data/lib/zip/ioextras.rb +114 -0
  192. data/lib/zip/stdrubyext.rb +111 -0
  193. data/lib/zip/tempfile_bugfixed.rb +195 -0
  194. data/lib/zip/zip.rb +1378 -0
  195. data/lib/zip/zipfilesystem.rb +558 -0
  196. data/lib/zip/ziprequire.rb +61 -0
  197. data/rwd_files/HowTo_Eliza.txt +195 -0
  198. data/rwd_files/HowTo_Tinker.txt +471 -0
  199. data/rwd_files/HowTo_TinkerWin2.txt +202 -0
  200. data/rwd_files/Readme.txt +57 -0
  201. data/rwd_files/RubyWebDialogs.html +6 -0
  202. data/rwd_files/favicon.ico +0 -0
  203. data/rwd_files/rdoc-style.css +175 -0
  204. data/rwd_files/rwdapplications.html +54 -0
  205. data/rwd_files/tinker.png +0 -0
  206. data/rwdconfig.dist +21 -0
  207. data/rwdeliza.rb +1 -0
  208. data/tests/RubyGauge.rb +179 -0
  209. data/tests/checkdepends.sh +4 -0
  210. data/tests/cleancnf.sh +6 -0
  211. data/tests/makedist-rwdweliza.rb +56 -0
  212. data/tests/makedist.rb +66 -0
  213. data/tests/rdep.rb +354 -0
  214. data/tests/totranslate.lang +93 -0
  215. data/zips/rwdwaddresses-1.05.zip +0 -0
  216. data/zips/rwdwcalc-0.61.zip +0 -0
  217. data/zips/rwdwgutenberg-0.09.zip +0 -0
  218. data/zips/rwdwschedule-1.04.zip +0 -0
  219. data/zips/rwdwshell-1.04.zip +0 -0
  220. data/zips/temp.rb +1 -0
  221. data/zips/wrubyslippers-1.06.zip +0 -0
  222. metadata +282 -0
@@ -0,0 +1,866 @@
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
+ class Request < Hash
566
+ attr_reader :peeraddr
567
+ attr_reader :request
568
+ attr_reader :cookies
569
+ attr_reader :vars
570
+ attr_reader :user
571
+ attr_writer :user
572
+
573
+ def initialize(io)
574
+ @io = io
575
+
576
+ firstline = @io.gets
577
+
578
+ return if firstline.nil?
579
+
580
+ @request = RequestRequest.new(firstline.strip)
581
+
582
+ line = @io.gets
583
+ line = line.strip unless line.nil?
584
+ while not line.nil? and not line.empty?
585
+ key, value = line.split(" ", 2)
586
+ self[key.sub(/:$/, "").downcase] = value
587
+
588
+ line = @io.gets
589
+ line = line.strip unless line.nil?
590
+ end
591
+
592
+ cookie = self["cookie"]
593
+ cookie = "" if cookie.nil?
594
+ @cookies = {}
595
+ cookie.split(/;/).each do |s|
596
+ k, v = s.strip.split(/=/, 2)
597
+ @cookies[k] = v
598
+ end
599
+
600
+ if not @request.method.nil?
601
+ case @request.method.upcase
602
+ when "HEAD"
603
+ when "GET"
604
+ @vars = RequestGet.new(@request.data.nil? ? "" : @request.data)
605
+ when "POST"
606
+ data = (@io.read(self["content-length"].to_i) or "")
607
+ @vars = RequestPost.new((self["content-type"] == "application/x-www-form-urlencoded") ? data : "")
608
+ else
609
+ $stderr.puts "Unknown request ('#{firstline}')."
610
+ end
611
+ end
612
+
613
+ @peeraddr = @io.peeraddr
614
+
615
+ @pda = false
616
+ @pda = true if (self.include?("user-agent") and self["user-agent"].downcase.include?("windows ce"))
617
+ @pda = true if (self.include?("user-agent") and self["user-agent"].downcase.include?("handhttp"))
618
+
619
+ @io.close_read
620
+ end
621
+
622
+ def pda?
623
+ @pda
624
+ end
625
+
626
+ def to_s
627
+ res = @request.to_s
628
+ self.each do |k, v|
629
+ res << "#{k}: #{v}\r\n"
630
+ end
631
+ res
632
+ end
633
+
634
+ def inspect
635
+ "(Request: %s)" % [@peeraddr, @request.inspect, @vars.inspect, @cookies.inspect, super].join(", ")
636
+ end
637
+ end
638
+
639
+ class Response < Hash
640
+ attr_writer :response
641
+ attr_writer :file
642
+ attr_reader :cookies
643
+ attr_reader :stop
644
+ attr_reader :at_stop
645
+
646
+ def initialize(io)
647
+ @io = io
648
+ @response = "HTTP/1.0 200 OK"
649
+ @cookies = {}
650
+ @data = ""
651
+ @syncd = false
652
+ @stop = false
653
+ @at_stop = lambda{}
654
+ @file = nil
655
+ end
656
+
657
+ def flush
658
+ sync
659
+
660
+ if @file
661
+ File.open(@file, "rb") do |f|
662
+ while data = f.read(10_000)
663
+ @io.write data
664
+ end
665
+ end
666
+ end
667
+
668
+ @io.close
669
+ end
670
+
671
+ def to_s
672
+ res = "#{@response}\r\n"
673
+ self.each do |k, v|
674
+ res << "#{k}: #{v}\r\n"
675
+ end
676
+
677
+ @cookies.each do |k, v|
678
+ res << "Set-Cookie: %s=%s;\r\n" % [k, v]
679
+ end
680
+
681
+ res
682
+ end
683
+
684
+ def sync
685
+ size = (@data or "").length
686
+
687
+ if @file
688
+ ext = @file.scan(/\.[^\.]*$/)
689
+ ext = ext.shift
690
+ ext = ext[1..-1] unless ext.nil?
691
+ mimetype = EVMime::MimeType[ext]
692
+
693
+ self["Content-Type"] = mimetype unless mimetype.nil?
694
+
695
+ size += File.size(@file) if File.file?(@file)
696
+ end
697
+
698
+ self["Content-Length"] = size
699
+
700
+ @io.write("#{to_s}\r\n") unless @syncd
701
+ @io.write(@data)
702
+ @data = ""
703
+ @syncd = true
704
+ end
705
+
706
+ def << (s)
707
+ @data << s
708
+ end
709
+
710
+ def clean
711
+ @data = ""
712
+ end
713
+
714
+ def inspect
715
+ "(Response: %s)" % [@response, @data].join(", ")
716
+ end
717
+
718
+ def stop(&block)
719
+ @stop = true
720
+ @at_stop = block unless block.nil?
721
+ end
722
+
723
+ def stop?
724
+ @stop
725
+ end
726
+ end
727
+
728
+ class HTTPServerException < Exception
729
+ end
730
+
731
+ class HTTPServer
732
+ def self.serve(portio=80, remote=false, auth=nil, realm="ev/net")
733
+ port, server = portio
734
+
735
+ begin
736
+ server = TCPServer.new(remote ? "0.0.0.0" : "localhost", port) if server.nil?
737
+
738
+ $stderr.puts "Just point your browser to http://localhost:#{port}/ ..."
739
+ rescue
740
+ server = nil
741
+
742
+ $stderr.puts "Port #{port} is in use."
743
+ end
744
+
745
+ if not server.nil?
746
+ count = 0
747
+
748
+ at_exit do
749
+ #$stderr.puts "Received #{count} requests"
750
+ end
751
+
752
+ serverthread =
753
+ Thread.new do
754
+ mutex = Mutex.new
755
+
756
+ Thread.current["threads"] = []
757
+
758
+ every(1, Thread.current) do |thread|
759
+ mutex.synchronize do
760
+ thread["threads"].delete_if{|t| (not t.alive?)}
761
+ end
762
+ end
763
+
764
+ loop do
765
+ io = server.accept
766
+ count += 1
767
+
768
+ thread =
769
+ Thread.new(Thread.current, count) do |parentthread, count2|
770
+ stop = false
771
+
772
+ begin
773
+ begin
774
+ req = Request.new(io)
775
+ resp = Response.new(io)
776
+ rescue
777
+ raise HTTPServerException
778
+ end
779
+
780
+ begin
781
+ ip = req.peeraddr[3]
782
+ rescue NameError
783
+ raise HTTPServerException
784
+ end
785
+
786
+ if (not remote) or (remote and (auth.nil? or auth.empty? or authenticate(auth, realm, req, resp)))
787
+ # $stderr.puts "#{count2} #{Time.new.strftime("%Y-%m-%d %H:%M:%S")} #{ip} #{req.user} #{req.request.to_s.strip}"
788
+ 1 == 1
789
+ begin
790
+ yield(req, resp)
791
+ rescue Exception => e
792
+ mutex.synchronize do
793
+ $stderr.puts e.class.to_s + ": " + e.message
794
+ $stderr.puts e.backtrace.collect{|s| "\t"+s}.join("\n")
795
+ end
796
+ resp["Content-Type"] = "text/plain"
797
+ resp.response = "HTTP/1.0 200 ???"
798
+ resp.clean
799
+ resp << e.class.to_s + ": " + e.message
800
+ resp << "\n"
801
+ resp << "\n"
802
+ resp << e.backtrace.collect{|s| "\t"+s}.join("\n")
803
+ resp << "\n"
804
+ resp << "\n"
805
+ resp << "(You can use the back button and stop the application properly, if appropriate.)"
806
+ end
807
+
808
+ stop = true if resp.stop?
809
+ end
810
+
811
+ begin
812
+ resp.flush
813
+ rescue
814
+ raise HTTPServerException
815
+ end
816
+ rescue HTTPServerException
817
+ end
818
+
819
+ parentthread["stop"] = resp if stop
820
+ end
821
+
822
+ mutex.synchronize do
823
+ Thread.current["threads"] << thread
824
+ end
825
+ end
826
+ end
827
+
828
+ sleep 0.1 while not serverthread["stop"]
829
+
830
+ serverthread["threads"].each {|t| t.join}
831
+
832
+ serverthread["stop"].at_stop.call
833
+
834
+ serverthread.kill
835
+ end
836
+ end
837
+
838
+ def self.authenticate(auth, realm, req, resp)
839
+ if auth.kind_of? String
840
+ file = "#{home}/#{auth}"
841
+ auths = {}
842
+ auths = Hash.file(file) if File.file?(file)
843
+ else
844
+ auths = auth
845
+ end
846
+
847
+ authuserpassword = req["authorization"]
848
+ if not authuserpassword.nil?
849
+ authtype, userpassword = authuserpassword.split(/ /)
850
+ if authtype == "Basic" and not userpassword.nil?
851
+ u, p = userpassword.unpack("m").shift.split(/:/)
852
+ end
853
+ end
854
+
855
+ ok = (auths.include?(u) and auths[u] == p)
856
+
857
+ unless ok
858
+ resp["WWW-Authenticate"] = "Basic realm=\"#{realm}\""
859
+ resp.response = "HTTP/1.0 401 Unauthorized"
860
+ end
861
+
862
+ req.user = u
863
+
864
+ return ok
865
+ end
866
+ end