IOWA 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (502) hide show
  1. checksums.yaml +7 -0
  2. data/CONTRIBUTORS +14 -0
  3. data/README.md +23 -0
  4. data/RELEASE_NOTES +77 -0
  5. data/ToDo +21 -0
  6. data/components/CRUDList/CRUDList.html +13 -0
  7. data/components/CRUDList/CRUDList.iwa +136 -0
  8. data/components/Content/Content.html +0 -0
  9. data/components/Content/Content.iwa +143 -0
  10. data/components/Content/example/README +9 -0
  11. data/components/Content/example/cgi/iowa.cgi +10 -0
  12. data/components/Content/example/demo.rb +30 -0
  13. data/components/Content/example/doc/index.html +7 -0
  14. data/components/Content/example/iowa/Content.html +1 -0
  15. data/components/Content/example/iowa/Content.iwa +1 -0
  16. data/components/Content/example/iowa/Main.html +6 -0
  17. data/components/Content/example/iowa/Main.iwa +3 -0
  18. data/components/Content/example/iowa/_content/body +7 -0
  19. data/components/Content/example/iowa/_content/body2 +3 -0
  20. data/components/Content/example/iowa/_content/title +2 -0
  21. data/components/Content/example/iowa/app.cnf +8 -0
  22. data/components/Content/example/iowa/app.rb +8 -0
  23. data/components/Content/example/webrick.rb +38 -0
  24. data/components/Include/Include.html +1 -0
  25. data/components/Include/Include.iwa +30 -0
  26. data/components/Include/readme +5 -0
  27. data/components/JumpTo/JumpTo.html +8 -0
  28. data/components/JumpTo/JumpTo.iwa +8 -0
  29. data/components/JumpTo/readme +6 -0
  30. data/doc/Architecture.txt +6 -0
  31. data/doc/History.txt +33 -0
  32. data/doc/StandardDispatcher.txt +19 -0
  33. data/examples/blog/README +1 -0
  34. data/examples/hello_world/README +17 -0
  35. data/examples/hello_world/htdocs/hello_world_html.html +24 -0
  36. data/examples/hello_world/htdocs/hello_world_ruby.html +41 -0
  37. data/examples/hello_world/iowa/HelloWorld.html +14 -0
  38. data/examples/hello_world/iowa/HelloWorld.iwa +31 -0
  39. data/examples/hello_world/iowa/Index.html +16 -0
  40. data/examples/hello_world/iowa/Index.iwa +5 -0
  41. data/examples/hello_world/iowa/iowa_hello_world.cnf +19 -0
  42. data/examples/hello_world/iowa/iowa_hello_world.rb +5 -0
  43. data/examples/hello_world/iowa/mapfile.cnf +6 -0
  44. data/examples/hw1/iowa/Main.html +1 -0
  45. data/examples/hw1/iowa/README +9 -0
  46. data/examples/hw1/iowa/hw.rb +4 -0
  47. data/examples/hw2/iowa/Main.html +10 -0
  48. data/examples/hw2/iowa/Main.iwa +7 -0
  49. data/examples/hw2/iowa/README +16 -0
  50. data/examples/hw2/iowa/hw.rb +4 -0
  51. data/examples/hw3/iowa/Main.html +11 -0
  52. data/examples/hw3/iowa/Main.iwa +7 -0
  53. data/examples/hw3/iowa/README +22 -0
  54. data/examples/hw3/iowa/hw.rb +4 -0
  55. data/examples/hw4/iowa/Greetings.html +10 -0
  56. data/examples/hw4/iowa/Greetings.iwa +9 -0
  57. data/examples/hw4/iowa/Main.html +12 -0
  58. data/examples/hw4/iowa/Main.iwa +10 -0
  59. data/examples/hw4/iowa/README +28 -0
  60. data/examples/hw4/iowa/hw.rb +4 -0
  61. data/examples/hw5/iowa/Footer.html +2 -0
  62. data/examples/hw5/iowa/Greetings.html +4 -0
  63. data/examples/hw5/iowa/Greetings.iwa +12 -0
  64. data/examples/hw5/iowa/Header.html +6 -0
  65. data/examples/hw5/iowa/Main.html +12 -0
  66. data/examples/hw5/iowa/Main.iwa +13 -0
  67. data/examples/hw5/iowa/README +16 -0
  68. data/examples/hw5/iowa/hw.rb +4 -0
  69. data/examples/template_server/iowa/Content.iwa +121 -0
  70. data/examples/template_server/iowa/Content.view +0 -0
  71. data/examples/template_server/iowa/DBContentDispatcher.rb +112 -0
  72. data/examples/template_server/iowa/DBContentPage.html +3 -0
  73. data/examples/template_server/iowa/DBContentPage.iwa +85 -0
  74. data/examples/template_server/iowa/app.cnf +13 -0
  75. data/examples/template_server/iowa/app.rb +5 -0
  76. data/ext/Classifier/classifier.c +256 -0
  77. data/ext/Classifier/ext_help.h +14 -0
  78. data/ext/Classifier/extconf.rb +5 -0
  79. data/ext/Classifier/tst.h +40 -0
  80. data/ext/Classifier/tst_cleanup.c +24 -0
  81. data/ext/Classifier/tst_delete.c +146 -0
  82. data/ext/Classifier/tst_grow_node_free_list.c +38 -0
  83. data/ext/Classifier/tst_init.c +41 -0
  84. data/ext/Classifier/tst_insert.c +192 -0
  85. data/ext/Classifier/tst_search.c +68 -0
  86. data/ext/http11/README +11 -0
  87. data/ext/http11/ext_help.h +15 -0
  88. data/ext/http11/extconf.rb +5 -0
  89. data/ext/http11/http11.c +534 -0
  90. data/ext/http11/http11.c.dif +422 -0
  91. data/ext/http11/http11_parser.c +1243 -0
  92. data/ext/http11/http11_parser.c.dif +193 -0
  93. data/ext/http11/http11_parser.h +49 -0
  94. data/ext/http11/http11_parser.h.dif +20 -0
  95. data/ext/http11/http11_parser.rl +192 -0
  96. data/ext/httpmachine/Makefile +149 -0
  97. data/ext/httpmachine/extconf.rb +33 -0
  98. data/ext/httpmachine/http.cpp +430 -0
  99. data/ext/httpmachine/http.h +156 -0
  100. data/ext/httpmachine/rubyhttp.cpp +165 -0
  101. data/external/mime-types/LICENCE +18 -0
  102. data/external/mime-types/README +46 -0
  103. data/external/mime-types/doc/classes/MIME.html +120 -0
  104. data/external/mime-types/doc/classes/MIME/InvalidContentType.html +119 -0
  105. data/external/mime-types/doc/classes/MIME/Type.html +866 -0
  106. data/external/mime-types/doc/classes/MIME/Type.src/M000010.html +22 -0
  107. data/external/mime-types/doc/classes/MIME/Type.src/M000011.html +18 -0
  108. data/external/mime-types/doc/classes/MIME/Type.src/M000012.html +19 -0
  109. data/external/mime-types/doc/classes/MIME/Type.src/M000013.html +18 -0
  110. data/external/mime-types/doc/classes/MIME/Type.src/M000014.html +26 -0
  111. data/external/mime-types/doc/classes/MIME/Type.src/M000015.html +33 -0
  112. data/external/mime-types/doc/classes/MIME/Type.src/M000016.html +27 -0
  113. data/external/mime-types/doc/classes/MIME/Type.src/M000017.html +35 -0
  114. data/external/mime-types/doc/classes/MIME/Type.src/M000018.html +34 -0
  115. data/external/mime-types/doc/classes/MIME/Type.src/M000019.html +24 -0
  116. data/external/mime-types/doc/classes/MIME/Type.src/M000020.html +38 -0
  117. data/external/mime-types/doc/classes/MIME/Type.src/M000021.html +22 -0
  118. data/external/mime-types/doc/classes/MIME/Type.src/M000022.html +18 -0
  119. data/external/mime-types/doc/classes/MIME/Type.src/M000023.html +18 -0
  120. data/external/mime-types/doc/classes/MIME/Type.src/M000024.html +18 -0
  121. data/external/mime-types/doc/classes/MIME/Type.src/M000025.html +18 -0
  122. data/external/mime-types/doc/classes/MIME/Type.src/M000026.html +18 -0
  123. data/external/mime-types/doc/classes/MIME/Type.src/M000027.html +18 -0
  124. data/external/mime-types/doc/classes/MIME/Type.src/M000028.html +18 -0
  125. data/external/mime-types/doc/classes/MIME/Type.src/M000029.html +18 -0
  126. data/external/mime-types/doc/classes/MIME/Type.src/M000030.html +19 -0
  127. data/external/mime-types/doc/classes/MIME/Type.src/M000031.html +26 -0
  128. data/external/mime-types/doc/classes/MIME/Types.html +459 -0
  129. data/external/mime-types/doc/classes/MIME/Types.src/M000001.html +19 -0
  130. data/external/mime-types/doc/classes/MIME/Types.src/M000002.html +32 -0
  131. data/external/mime-types/doc/classes/MIME/Types.src/M000003.html +21 -0
  132. data/external/mime-types/doc/classes/MIME/Types.src/M000004.html +18 -0
  133. data/external/mime-types/doc/classes/MIME/Types.src/M000005.html +26 -0
  134. data/external/mime-types/doc/classes/MIME/Types.src/M000006.html +18 -0
  135. data/external/mime-types/doc/classes/MIME/Types.src/M000007.html +18 -0
  136. data/external/mime-types/doc/classes/MIME/Types.src/M000008.html +18 -0
  137. data/external/mime-types/doc/classes/MIME/Types.src/M000009.html +18 -0
  138. data/external/mime-types/doc/created.rid +1 -0
  139. data/external/mime-types/doc/files/ChangeLog.html +320 -0
  140. data/external/mime-types/doc/files/README.html +145 -0
  141. data/external/mime-types/doc/files/lib/mime/types_rb.html +101 -0
  142. data/external/mime-types/doc/fr_class_index.html +30 -0
  143. data/external/mime-types/doc/fr_file_index.html +29 -0
  144. data/external/mime-types/doc/fr_method_index.html +57 -0
  145. data/external/mime-types/doc/index.html +24 -0
  146. data/external/mime-types/doc/rdoc-style.css +208 -0
  147. data/external/mime-types/lib/mime/types.rb +1558 -0
  148. data/external/package.rb +672 -0
  149. data/external/test_support.rb +95 -0
  150. data/external/tmail/README +7 -0
  151. data/external/tmail/tmail.rb +4 -0
  152. data/external/tmail/tmail/address.rb +222 -0
  153. data/external/tmail/tmail/base64.rb +52 -0
  154. data/external/tmail/tmail/compat.rb +39 -0
  155. data/external/tmail/tmail/config.rb +50 -0
  156. data/external/tmail/tmail/encode.rb +447 -0
  157. data/external/tmail/tmail/header.rb +895 -0
  158. data/external/tmail/tmail/info.rb +14 -0
  159. data/external/tmail/tmail/loader.rb +1 -0
  160. data/external/tmail/tmail/mail.rb +869 -0
  161. data/external/tmail/tmail/mailbox.rb +386 -0
  162. data/external/tmail/tmail/mbox.rb +1 -0
  163. data/external/tmail/tmail/net.rb +260 -0
  164. data/external/tmail/tmail/obsolete.rb +123 -0
  165. data/external/tmail/tmail/parser.rb +1475 -0
  166. data/external/tmail/tmail/parser.y +372 -0
  167. data/external/tmail/tmail/port.rb +356 -0
  168. data/external/tmail/tmail/scanner.rb +17 -0
  169. data/external/tmail/tmail/scanner_r.rb +243 -0
  170. data/external/tmail/tmail/stringio.rb +256 -0
  171. data/external/tmail/tmail/textutils.rb +197 -0
  172. data/external/tmail/tmail/tmail.rb +1 -0
  173. data/external/tmail/tmail/utils.rb +23 -0
  174. data/external/win32-process/README +133 -0
  175. data/external/win32-process/lib/win32/process.rb +561 -0
  176. data/external/windows-pr/README +145 -0
  177. data/external/windows-pr/doc/conversion_guide.txt +25 -0
  178. data/external/windows-pr/lib/windows/clipboard.rb +72 -0
  179. data/external/windows-pr/lib/windows/console.rb +323 -0
  180. data/external/windows-pr/lib/windows/device_io.rb +88 -0
  181. data/external/windows-pr/lib/windows/directory.rb +80 -0
  182. data/external/windows-pr/lib/windows/error.rb +313 -0
  183. data/external/windows-pr/lib/windows/eventlog.rb +120 -0
  184. data/external/windows-pr/lib/windows/file.rb +349 -0
  185. data/external/windows-pr/lib/windows/filesystem.rb +16 -0
  186. data/external/windows-pr/lib/windows/handle.rb +31 -0
  187. data/external/windows-pr/lib/windows/library.rb +76 -0
  188. data/external/windows-pr/lib/windows/limits.rb +13 -0
  189. data/external/windows-pr/lib/windows/memory.rb +117 -0
  190. data/external/windows-pr/lib/windows/msvcrt/buffer.rb +48 -0
  191. data/external/windows-pr/lib/windows/msvcrt/file.rb +18 -0
  192. data/external/windows-pr/lib/windows/msvcrt/string.rb +46 -0
  193. data/external/windows-pr/lib/windows/national.rb +557 -0
  194. data/external/windows-pr/lib/windows/path.rb +296 -0
  195. data/external/windows-pr/lib/windows/pipe.rb +77 -0
  196. data/external/windows-pr/lib/windows/process.rb +171 -0
  197. data/external/windows-pr/lib/windows/registry.rb +238 -0
  198. data/external/windows-pr/lib/windows/security.rb +89 -0
  199. data/external/windows-pr/lib/windows/service.rb +183 -0
  200. data/external/windows-pr/lib/windows/shell.rb +88 -0
  201. data/external/windows-pr/lib/windows/sound.rb +52 -0
  202. data/external/windows-pr/lib/windows/synchronize.rb +161 -0
  203. data/external/windows-pr/lib/windows/system_info.rb +70 -0
  204. data/external/windows-pr/lib/windows/unicode.rb +138 -0
  205. data/external/windows-pr/lib/windows/window.rb +22 -0
  206. data/iowa.gemspec +45 -0
  207. data/microprojects/DiskCache/LICENSE +28 -0
  208. data/microprojects/DiskCache/README +17 -0
  209. data/microprojects/DiskCache/external/package.rb +608 -0
  210. data/microprojects/DiskCache/external/test_support.rb +8 -0
  211. data/microprojects/DiskCache/setup.rb +22 -0
  212. data/microprojects/DiskCache/src/iowa/Association.rb +67 -0
  213. data/microprojects/DiskCache/src/iowa/Constants.rb +159 -0
  214. data/microprojects/DiskCache/src/iowa/DiskStore.rb +377 -0
  215. data/microprojects/DiskCache/src/iowa/Hash.rb +63 -0
  216. data/microprojects/DiskCache/src/iowa/Lockfile.rb +575 -0
  217. data/microprojects/DiskCache/src/iowa/Mutex.rb +142 -0
  218. data/microprojects/DiskCache/src/iowa/caches/DiskCache.rb +605 -0
  219. data/microprojects/DiskCache/src/iowa/caches/LRUCache.rb +287 -0
  220. data/microprojects/DiskCache/test/TC_DiskCache.rb +218 -0
  221. data/microprojects/LRUCache/LICENSE +28 -0
  222. data/microprojects/LRUCache/README +13 -0
  223. data/microprojects/LRUCache/external/package.rb +608 -0
  224. data/microprojects/LRUCache/external/test_support.rb +8 -0
  225. data/microprojects/LRUCache/setup.rb +22 -0
  226. data/microprojects/LRUCache/src/iowa/Association.rb +57 -0
  227. data/microprojects/LRUCache/src/iowa/Constants.rb +159 -0
  228. data/microprojects/LRUCache/src/iowa/Hash.rb +63 -0
  229. data/microprojects/LRUCache/src/iowa/Mutex.rb +129 -0
  230. data/microprojects/LRUCache/src/iowa/caches/LRUCache.rb +287 -0
  231. data/microprojects/LRUCache/test/TC_LRUCache.rb +65 -0
  232. data/microprojects/LinkedList/LICENSE +28 -0
  233. data/microprojects/LinkedList/README +13 -0
  234. data/microprojects/LinkedList/external/package.rb +608 -0
  235. data/microprojects/LinkedList/external/test_support.rb +8 -0
  236. data/microprojects/LinkedList/setup.rb +22 -0
  237. data/microprojects/LinkedList/src/iowa/LinkedList.rb +165 -0
  238. data/microprojects/LinkedList/test/TC_LinkedList.rb +42 -0
  239. data/microprojects/README +8 -0
  240. data/setup.rb +116 -0
  241. data/share/iowa/app_skeleton/Main.html +8 -0
  242. data/share/iowa/app_skeleton/Main.iwa +15 -0
  243. data/share/iowa/app_skeleton/app.cnf +48 -0
  244. data/share/iowa/app_skeleton/app.rb +58 -0
  245. data/share/iowa/app_skeleton/models/model.rb +49 -0
  246. data/src/ihc.rb +223 -0
  247. data/src/iowa.cgi +29 -0
  248. data/src/iowa.rb +637 -0
  249. data/src/iowa/AbstractCache.rb +96 -0
  250. data/src/iowa/AcceptLanguage.rb +76 -0
  251. data/src/iowa/Application.rb +928 -0
  252. data/src/iowa/ApplicationStats.rb +72 -0
  253. data/src/iowa/Association.rb +67 -0
  254. data/src/iowa/BindingsParser.rb +62 -0
  255. data/src/iowa/Breakpoint.rb +273 -0
  256. data/src/iowa/CSS.rb +564 -0
  257. data/src/iowa/Client.rb +192 -0
  258. data/src/iowa/Component.rb +405 -0
  259. data/src/iowa/ComponentProxy.rb +26 -0
  260. data/src/iowa/Config.rb +21 -0
  261. data/src/iowa/Constants.rb +226 -0
  262. data/src/iowa/Context.rb +218 -0
  263. data/src/iowa/ContextLogger.rb +16 -0
  264. data/src/iowa/DbPool.rb +222 -0
  265. data/src/iowa/DetachedComponent.rb +18 -0
  266. data/src/iowa/Dispatcher.rb +27 -0
  267. data/src/iowa/DynamicElements.rb +471 -0
  268. data/src/iowa/Element.rb +100 -0
  269. data/src/iowa/Email.rb +287 -0
  270. data/src/iowa/Extensions/AllExtensions.rb +4 -0
  271. data/src/iowa/Extensions/Class.rb +94 -0
  272. data/src/iowa/Extensions/Date.rb +88 -0
  273. data/src/iowa/Extensions/DateTime.rb +88 -0
  274. data/src/iowa/Extensions/Hash.rb +22 -0
  275. data/src/iowa/Extensions/Kernel.rb +6 -0
  276. data/src/iowa/Extensions/Numeric.rb +47 -0
  277. data/src/iowa/Extensions/Object.rb +11 -0
  278. data/src/iowa/Extensions/String.rb +60 -0
  279. data/src/iowa/Extensions/Time.rb +89 -0
  280. data/src/iowa/Extensions/TimeExtensions.rb +6 -0
  281. data/src/iowa/Form.rb +368 -0
  282. data/src/iowa/Hash.rb +85 -0
  283. data/src/iowa/ISAAC.rb +175 -0
  284. data/src/iowa/ImageSize.rb +279 -0
  285. data/src/iowa/IowaComponentMixins.rb +7 -0
  286. data/src/iowa/JSON-lexer.rb +296 -0
  287. data/src/iowa/JSON-objects.rb +201 -0
  288. data/src/iowa/KeyValueCoding.rb +91 -0
  289. data/src/iowa/LinkedList.rb +175 -0
  290. data/src/iowa/Loader.rb +22 -0
  291. data/src/iowa/Lockfile.rb +575 -0
  292. data/src/iowa/Logger.rb +74 -0
  293. data/src/iowa/Monkey.rb +20 -0
  294. data/src/iowa/Mutex.rb +142 -0
  295. data/src/iowa/Policy.rb +70 -0
  296. data/src/iowa/Pool.rb +243 -0
  297. data/src/iowa/PrettyException.rb +1091 -0
  298. data/src/iowa/Request.rb +244 -0
  299. data/src/iowa/Response.rb +133 -0
  300. data/src/iowa/Session.rb +354 -0
  301. data/src/iowa/SessionStats.rb +78 -0
  302. data/src/iowa/String.rb +65 -0
  303. data/src/iowa/Tag.rb +101 -0
  304. data/src/iowa/TemplateParser.rb +236 -0
  305. data/src/iowa/Util.rb +314 -0
  306. data/src/iowa/Webcache.rb +122 -0
  307. data/src/iowa/caches/BiLevelCache.rb +65 -0
  308. data/src/iowa/caches/ClassLimitedCache.rb +67 -0
  309. data/src/iowa/caches/DiskCache.rb +609 -0
  310. data/src/iowa/caches/DiskStore.rb +380 -0
  311. data/src/iowa/caches/LRUCache-alternative.rb +155 -0
  312. data/src/iowa/caches/LRUCache.rb +290 -0
  313. data/src/iowa/caches/SimpleLRUCache.rb +112 -0
  314. data/src/iowa/dispatchers/StandardDispatcher.rb +396 -0
  315. data/src/iowa/dispatchers/StandardDispatcherWithClassifier.rb +93 -0
  316. data/src/iowa/js/iowa_jsonrpc.js +381 -0
  317. data/src/iowa/js/jsonrpc.js +187 -0
  318. data/src/iowa/js/jsonrpc_async.js +261 -0
  319. data/src/iowa/loaders/DiskLoader.rb +50 -0
  320. data/src/iowa/loggers/Analogger.rb +54 -0
  321. data/src/iowa/loggers/AsyncLogger.rb +54 -0
  322. data/src/iowa/loggers/BitBucket.rb +38 -0
  323. data/src/iowa/loggers/Log4R.rb +13 -0
  324. data/src/iowa/loggers/Log4rLogger.rb +48 -0
  325. data/src/iowa/loggers/Logger.rb +29 -0
  326. data/src/iowa/loggers/RubyLogger.rb +9 -0
  327. data/src/iowa/pools/DBConnectionPool.rb +53 -0
  328. data/src/iowa/request/Apache.rb +90 -0
  329. data/src/iowa/request/EMHybrid.rb +59 -0
  330. data/src/iowa/request/ENV.rb +80 -0
  331. data/src/iowa/request/FCGI.rb +68 -0
  332. data/src/iowa/request/HTTPMachine.rb +75 -0
  333. data/src/iowa/request/Mongrel.rb +68 -0
  334. data/src/iowa/request/WEBrick.rb +48 -0
  335. data/src/iowa/version.rb +3 -0
  336. data/src/iowa/webrick/HTTPServer.rb +43 -0
  337. data/src/iowa/webrick/WEBrickServlet.rb +28 -0
  338. data/src/iowa_fcgi_handler.rb +101 -0
  339. data/src/iowa_httpmachine.rb +141 -0
  340. data/src/iowa_hybrid.rb +193 -0
  341. data/src/iowa_hybrid_cluster.rb +231 -0
  342. data/src/iowa_mongrel.rb +136 -0
  343. data/src/iowa_webrick.rb +194 -0
  344. data/src/iowa_webrick_legacy.rb +104 -0
  345. data/src/mod_iowa.rb +104 -0
  346. data/tcss.rb +61 -0
  347. data/test/README.windows +12 -0
  348. data/test/TC_AcceptLanguage.rb +61 -0
  349. data/test/TC_AppConfig.rb +43 -0
  350. data/test/TC_AppConfig/cgi/iowa.cgi +7 -0
  351. data/test/TC_AppConfig/doc/index.html +1 -0
  352. data/test/TC_AppConfig/iowa/Main.html +4 -0
  353. data/test/TC_AppConfig/iowa/Main.iwa +17 -0
  354. data/test/TC_AppConfig/iowa/README +1 -0
  355. data/test/TC_AppConfig/iowa/app.cnf +19 -0
  356. data/test/TC_AppConfig/iowa/app.rb +8 -0
  357. data/test/TC_AppConfig/webrick.rb +38 -0
  358. data/test/TC_Association.rb +29 -0
  359. data/test/TC_BiLevelCache.rb +71 -0
  360. data/test/TC_CGI_Adaptor.rb +55 -0
  361. data/test/TC_CGI_Adaptor/cgi/iowa.cgi +7 -0
  362. data/test/TC_CGI_Adaptor/doc/index.html +1 -0
  363. data/test/TC_CGI_Adaptor/iowa/Main.html +8 -0
  364. data/test/TC_CGI_Adaptor/iowa/Main.iwa +14 -0
  365. data/test/TC_CGI_Adaptor/iowa/README +1 -0
  366. data/test/TC_CGI_Adaptor/iowa/app.cnf +8 -0
  367. data/test/TC_CGI_Adaptor/iowa/app.rb +8 -0
  368. data/test/TC_CGI_Adaptor/webrick.rb +38 -0
  369. data/test/TC_CSS.rb +660 -0
  370. data/test/TC_ClassLimitedCache.rb +89 -0
  371. data/test/TC_Classifier.rb +80 -0
  372. data/test/TC_DbPool.rb +127 -0
  373. data/test/TC_DiskCache.rb +218 -0
  374. data/test/TC_Hybrid.rb +58 -0
  375. data/test/TC_Hybrid/doc/thing.txt +1 -0
  376. data/test/TC_Hybrid/iowa/Main.html +3 -0
  377. data/test/TC_Hybrid/iowa/Main.iwa +7 -0
  378. data/test/TC_Hybrid/iowa/NewPage.html +1 -0
  379. data/test/TC_Hybrid/iowa/NewPage.iwa +5 -0
  380. data/test/TC_Hybrid/iowa/app.cnf +10 -0
  381. data/test/TC_Hybrid/iowa/app.rb +5 -0
  382. data/test/TC_IOWAFunctions/doc/Ajax1.html +1 -0
  383. data/test/TC_IOWAFunctions/doc/Ajax1.iwa +1 -0
  384. data/test/TC_IOWAFunctions/doc/index.html +1 -0
  385. data/test/TC_IOWAFunctions/doc/js/dojo.js +9686 -0
  386. data/test/TC_IOWAFunctions/iowa/Ajax1.html +40 -0
  387. data/test/TC_IOWAFunctions/iowa/Ajax1.iwa +23 -0
  388. data/test/TC_IOWAFunctions/iowa/AjaxWidget.iwa +19 -0
  389. data/test/TC_IOWAFunctions/iowa/AjaxWidget.view +22 -0
  390. data/test/TC_IOWAFunctions/iowa/DanielTest.html +9 -0
  391. data/test/TC_IOWAFunctions/iowa/DanielTest.iwa +10 -0
  392. data/test/TC_IOWAFunctions/iowa/IntervalWidget.html +1 -0
  393. data/test/TC_IOWAFunctions/iowa/IntervalWidget.iwa +14 -0
  394. data/test/TC_IOWAFunctions/iowa/Main.html +1 -0
  395. data/test/TC_IOWAFunctions/iowa/NestedRepeat1.html +12 -0
  396. data/test/TC_IOWAFunctions/iowa/NestedRepeat1.iwa +24 -0
  397. data/test/TC_IOWAFunctions/iowa/RPCResponse.iwa +7 -0
  398. data/test/TC_IOWAFunctions/iowa/RPCResponse.view +1 -0
  399. data/test/TC_IOWAFunctions/iowa/Repeat1.iwa +31 -0
  400. data/test/TC_IOWAFunctions/iowa/Repeat1.view +9 -0
  401. data/test/TC_IOWAFunctions/iowa/Repeat2.iwa +32 -0
  402. data/test/TC_IOWAFunctions/iowa/Repeat2.view +11 -0
  403. data/test/TC_IOWAFunctions/iowa/Repeat3.iwa +44 -0
  404. data/test/TC_IOWAFunctions/iowa/Repeat3.view +18 -0
  405. data/test/TC_IOWAFunctions/iowa/TesCon.html +1 -0
  406. data/test/TC_IOWAFunctions/iowa/TesCon.iwa +5 -0
  407. data/test/TC_IOWAFunctions/iowa/app.cnf +19 -0
  408. data/test/TC_IOWAFunctions/iowa/app.rb +9 -0
  409. data/test/TC_IOWAFunctions/iowa/mapfile.cnf +8 -0
  410. data/test/TC_ISAAC.rb +52 -0
  411. data/test/TC_ImageSize.rb +84 -0
  412. data/test/TC_ImageSize/img.bmp +0 -0
  413. data/test/TC_ImageSize/img.gif +0 -0
  414. data/test/TC_ImageSize/img.jpg +0 -0
  415. data/test/TC_ImageSize/img.pcx +0 -0
  416. data/test/TC_ImageSize/img.pgm +7144 -0
  417. data/test/TC_ImageSize/img.png +0 -0
  418. data/test/TC_ImageSize/img.ppm +0 -0
  419. data/test/TC_ImageSize/img.psd +0 -0
  420. data/test/TC_ImageSize/img.tiff +0 -0
  421. data/test/TC_ImageSize/img.xbm +22 -0
  422. data/test/TC_KeyValueCoding.rb +35 -0
  423. data/test/TC_LRUCache.rb +296 -0
  424. data/test/TC_LinkedList.rb +46 -0
  425. data/test/TC_Lockfile.rb +106 -0
  426. data/test/TC_Minimal.rb +45 -0
  427. data/test/TC_Minimal/app.cnf +8 -0
  428. data/test/TC_Minimal/cgi-bin/iowa.cgi +11 -0
  429. data/test/TC_Minimal/doc/index.html +1 -0
  430. data/test/TC_Minimal/iowa/Main.html +1 -0
  431. data/test/TC_Minimal/iowa/README +1 -0
  432. data/test/TC_Minimal/iowa/app.rb +3 -0
  433. data/test/TC_Minimal/webrick.rb +38 -0
  434. data/test/TC_Mongrel.rb +58 -0
  435. data/test/TC_Mongrel/doc/thing.txt +1 -0
  436. data/test/TC_Mongrel/iowa/Main.html +3 -0
  437. data/test/TC_Mongrel/iowa/Main.iwa +7 -0
  438. data/test/TC_Mongrel/iowa/NewPage.html +1 -0
  439. data/test/TC_Mongrel/iowa/NewPage.iwa +5 -0
  440. data/test/TC_Mongrel/iowa/app.cnf +10 -0
  441. data/test/TC_Mongrel/iowa/app.rb +5 -0
  442. data/test/TC_NoSubclass.rb +56 -0
  443. data/test/TC_NoSubclass/cgi/iowa.cgi +7 -0
  444. data/test/TC_NoSubclass/doc/index.html +1 -0
  445. data/test/TC_NoSubclass/iowa/Main.html +8 -0
  446. data/test/TC_NoSubclass/iowa/Main.iwa +14 -0
  447. data/test/TC_NoSubclass/iowa/README +1 -0
  448. data/test/TC_NoSubclass/iowa/app.cnf +8 -0
  449. data/test/TC_NoSubclass/iowa/app.rb +5 -0
  450. data/test/TC_NoSubclass/webrick.rb +38 -0
  451. data/test/TC_Pool.rb +139 -0
  452. data/test/TC_RenderedCache/doc/thing.txt +1 -0
  453. data/test/TC_RenderedCache/iowa/BigPage.html +1 -0
  454. data/test/TC_RenderedCache/iowa/BigPage.iwa +12 -0
  455. data/test/TC_RenderedCache/iowa/Main.html +3 -0
  456. data/test/TC_RenderedCache/iowa/Main.iwa +7 -0
  457. data/test/TC_RenderedCache/iowa/NewPage.html +1 -0
  458. data/test/TC_RenderedCache/iowa/NewPage.iwa +11 -0
  459. data/test/TC_RenderedCache/iowa/app.cnf +13 -0
  460. data/test/TC_RenderedCache/iowa/app.rb +5 -0
  461. data/test/TC_RenderedCache/iowa/mapfile.map +4 -0
  462. data/test/TC_ResourceURL.rb +73 -0
  463. data/test/TC_ResourceURL/iowa/Main.html +2 -0
  464. data/test/TC_ResourceURL/iowa/Main.iwa +10 -0
  465. data/test/TC_ResourceURL/iowa/app.cnf +10 -0
  466. data/test/TC_ResourceURL/iowa/app.rb +5 -0
  467. data/test/TC_SimpleDetached.rb +41 -0
  468. data/test/TC_StandardDispatcher.rb +362 -0
  469. data/test/TC_StandardDispatcherWithClassifier.rb +358 -0
  470. data/test/TC_String.rb +24 -0
  471. data/test/TC_Tag.rb +41 -0
  472. data/test/TC_Webrick.rb +56 -0
  473. data/test/TC_Webrick/doc/thing.txt +1 -0
  474. data/test/TC_Webrick/iowa/Main.html +3 -0
  475. data/test/TC_Webrick/iowa/Main.iwa +7 -0
  476. data/test/TC_Webrick/iowa/NewPage.html +1 -0
  477. data/test/TC_Webrick/iowa/NewPage.iwa +5 -0
  478. data/test/TC_Webrick/iowa/app.cnf +10 -0
  479. data/test/TC_Webrick/iowa/app.rb +5 -0
  480. data/test/tc_template.rb +15 -0
  481. data/test/tests.conf +19 -0
  482. data/utils/CVS/Entries +3 -0
  483. data/utils/CVS/Repository +1 -0
  484. data/utils/CVS/Root +1 -0
  485. data/utils/QuickCert-1.0.2.tar.gz +0 -0
  486. data/utils/QuickCert-1.0.2/InstalledFiles +7 -0
  487. data/utils/QuickCert-1.0.2/MANIFEST +10 -0
  488. data/utils/QuickCert-1.0.2/Makefile +15 -0
  489. data/utils/QuickCert-1.0.2/README +56 -0
  490. data/utils/QuickCert-1.0.2/bin/QuickCert +355 -0
  491. data/utils/QuickCert-1.0.2/config.save +12 -0
  492. data/utils/QuickCert-1.0.2/data/examples/ruby/QuickCert/README +60 -0
  493. data/utils/QuickCert-1.0.2/data/examples/ruby/QuickCert/drbssl_c.rb +26 -0
  494. data/utils/QuickCert-1.0.2/data/examples/ruby/QuickCert/drbssl_s.rb +35 -0
  495. data/utils/QuickCert-1.0.2/data/examples/ruby/QuickCert/qc_config +21 -0
  496. data/utils/QuickCert-1.0.2/lib/QuickCert/defaults.rb +28 -0
  497. data/utils/QuickCert-1.0.2/setup.rb +1312 -0
  498. data/utils/iowa_apps +422 -0
  499. data/utils/smtp_sink.rb +9 -0
  500. data/utils/startup_template.cnf +27 -0
  501. data/utils/startup_template.rb +73 -0
  502. metadata +551 -0
@@ -0,0 +1,244 @@
1
+ require 'iowa/Util'
2
+
3
+ module Iowa
4
+
5
+ # A DispatchDestination is a simple container for information on
6
+ # where a request is being dispatched to.
7
+
8
+ class DispatchDestination
9
+ attr_accessor :component, :method, :args
10
+
11
+ def initialize(c=nil, m=nil, a=[])
12
+ @component = c
13
+ @method = m
14
+ @args = a
15
+ end
16
+ end
17
+
18
+ # Class to encapsulate the data received from a file upload.
19
+
20
+ class FileData < Array
21
+
22
+ attr_accessor :name, :content_type
23
+
24
+ def initialize(name,content_type,*content)
25
+ @name = name
26
+ @content_type = content_type
27
+ self.concat(content)
28
+ end
29
+
30
+ def to_s
31
+ self.join
32
+ end
33
+
34
+ # Create a file with a path/name as in @name, and write the current
35
+ # data to it. Convenience method.
36
+ # After an Iowa app received an uploaded file and it checks/sets
37
+ # @name as appropriate, a single call to store() will write the file.
38
+ # If @name is blank or nil, the content will instead be written to
39
+ # an instance of Tempfile.
40
+
41
+ def store
42
+ handle = nil
43
+
44
+ # Make sure you know what is in @name before calling this!
45
+ @name = @name.to_s
46
+
47
+ if @name == ''
48
+ require 'tempfile'
49
+ handle = Tempfile.new('IowaFile','/tmp')
50
+ else
51
+ handle = File.new(@name,'w+')
52
+ end
53
+
54
+ if handle
55
+ handle.write self.join
56
+ handle.rewind
57
+ end
58
+
59
+ handle
60
+ end
61
+
62
+ end
63
+
64
+ # A serializeable class that represents (most of) the contents of
65
+ # an Apache::Request object.
66
+
67
+ class Request
68
+
69
+ MIMERegexp = %r|\Amultipart/form-data.*boundary=\"?([^\";,]+)\"?|n
70
+ CR = "\015"
71
+ LF = "\012"
72
+ EOL = CR + LF
73
+
74
+ attr_accessor :hostname, :port, :unparsed_uri, :uri, :filename, :request_time,
75
+ :request_method, :header_only, :args, :params,
76
+ :status_line, :headers_out, :content_type, :content_encoding
77
+ attr_accessor :content, :auth_type, :auth_name, :remote_host,
78
+ :cache_resp, :content_encoding, :content_languages, :remote_addr,
79
+ :calculate_runtime, :headers_in, :context
80
+
81
+ def Request.Type
82
+ @request_type
83
+ end
84
+
85
+ def Request.Type=(val)
86
+ @request_type = val
87
+ end
88
+
89
+ def read_multipart(boundary, content_length,instream,user_agent)
90
+ content_length = content_length.to_i
91
+ params = Hash.new([])
92
+ boundary = "--" + boundary
93
+ buf = ""
94
+ bufsize = 10 * 1024
95
+
96
+ # start multipart/form-data
97
+ instream.binmode if defined? instream.binmode
98
+ boundary_size = boundary.size + EOL.size
99
+ content_length -= boundary_size
100
+ status = instream.read(boundary_size)
101
+
102
+ loop do
103
+ head = nil
104
+ body = ''
105
+
106
+ until head and /#{boundary}(?:#{EOL}|--)/n.match(buf)
107
+ if (not head) and /#{EOL}#{EOL}/n.match(buf)
108
+ buf = buf.sub(/\A((?:.|\n)*?#{EOL})#{EOL}/n) do
109
+ head = $1.dup
110
+ ""
111
+ end
112
+ next
113
+ end
114
+
115
+ if head and ( (EOL + boundary + EOL).size < buf.size )
116
+ body << buf[0 ... (buf.size - (EOL + boundary + EOL).size)]
117
+ buf[0 ... (buf.size - (EOL + boundary + EOL).size)] = ""
118
+ end
119
+
120
+ c = if bufsize < content_length
121
+ instream.read(bufsize) or ''
122
+ else
123
+ instream.read(content_length) or ''
124
+ end
125
+ if c.nil? || c.empty?
126
+ raise EOFError, "bad content body"
127
+ end
128
+ buf.concat(c)
129
+ content_length -= c.size
130
+ end
131
+
132
+ buf = buf.sub(/\A((?:.|\n)*?)(?:#{EOL})?#{boundary}(#{EOL}|--)/n) do
133
+ body << $1
134
+ if "--" == $2
135
+ content_length = -1
136
+ end
137
+ ""
138
+ end
139
+
140
+ /Content-Disposition:.* filename="?([^\";]*)"?/ni.match(head)
141
+ filename = ($1 or "")
142
+ if /Mac/ni.match(user_agent) and
143
+ /Mozilla/ni.match(user_agent) and
144
+ (not /MSIE/ni.match(user_agent))
145
+ filename = Iowa::Util.unescape(filename)
146
+ end
147
+
148
+ /Content-type: (.*)/ni.match(head)
149
+ content_type = ($1 or "")
150
+
151
+ /Content-Disposition:.* name="?([^\";]*)"?/ni.match(head)
152
+ name = $1.dup
153
+
154
+ data = nil
155
+ if content_type.to_s != ''
156
+ data = Iowa::FileData.new(filename,content_type,body)
157
+ else
158
+ data = body
159
+ end
160
+ if params.has_key?(name)
161
+ if params[name].respond_to?(:push)
162
+ params[name].push data
163
+ else
164
+ params[name] = [params[name]] << data
165
+ end
166
+ else
167
+ params[name] = data
168
+ end
169
+ break if buf.size == 0
170
+ break if content_length === -1
171
+ end
172
+
173
+ params
174
+ end
175
+
176
+ def parse_params(line)
177
+ line.split(/&|;/).each do |pairs|
178
+ key, value = pairs.split(Iowa::CR_equal,2).collect{|v| Iowa::Util.unescape(v) }
179
+ if @params.has_key?(key)
180
+ if @params[key].respond_to?(:push)
181
+ @params[key] << value || Iowa::C_empty
182
+ else
183
+ @params[key] = [@params[key], value || Iowa::C_empty]
184
+ end
185
+ else
186
+ @params[key] = value || Iowa::C_empty
187
+ end
188
+ end
189
+ end
190
+
191
+ # If there is a prefered Type set, return an instance of that type.
192
+ # Otherwise, guess at a prefered Type, set it, then return an instance.
193
+
194
+ def Request.new_request(request=nil)
195
+ unless Iowa::Request.Type
196
+ if ENV['MOD_RUBY']
197
+ unless request
198
+ request = Apache.request if ENV['MOD_RUBY']
199
+ end
200
+ require 'iowa/request/Apache'
201
+ Iowa::Request.Type = Iowa::Request::Apache
202
+ elsif request.class.name.index('FCGI') == 0
203
+ require 'iowa/request/FCGI'
204
+ Iowa::Request.Type = Iowa::Request::FCGI
205
+ elsif Object.const_defined?(:Mongrel)
206
+ require 'iowa/request/Mongrel'
207
+ Iowa::Request.Type = Iowa::Request::Mongrel
208
+ elsif Object.const_defined?(:WEBrick)
209
+ require 'iowa/request/WEBrick'
210
+ Iowa::Request.Type = Iowa::Request::WEBrick
211
+ else
212
+ require 'iowa/request/ENV'
213
+ Iowa::Request.Type = Iowa::Request::ENV
214
+ end
215
+ end
216
+
217
+ Iowa::Request.Type.new(request)
218
+ end
219
+
220
+ def headers
221
+ @headers_in
222
+ end
223
+
224
+ def headers=(val)
225
+ @headers_in = val
226
+ end
227
+
228
+ def header_only?
229
+ return @header_only
230
+ end
231
+
232
+ def [](k)
233
+ @params[k]
234
+ end
235
+
236
+ def []=(k,v)
237
+ @params[k] = v
238
+ end
239
+
240
+ end
241
+
242
+ end
243
+
244
+ #Iowa::Request.Type = Iowa::Request
@@ -0,0 +1,133 @@
1
+ require 'mime/types'
2
+ require 'iowa/Util'
3
+ require 'iowa/String'
4
+
5
+ module Iowa
6
+
7
+ class Response
8
+ BINARY_TYPE = MIME::Types.type_for('bin') unless const_defined?(:BINARY_TYPE)
9
+
10
+ # Based on info at http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
11
+ unless const_defined?(:RESPONSE_CODES)
12
+ RESPONSE_CODES = {
13
+ 100 => 'Continue',
14
+ 101 => 'Switching Protocols',
15
+ 200 => 'OK',
16
+ 201 => 'Created',
17
+ 202 => 'Accepted',
18
+ 203 => 'Non-Authoritative Information',
19
+ 204 => 'No Content',
20
+ 205 => 'Reset Content',
21
+ 206 => 'Partial Content',
22
+ 300 => 'Multiple Choices',
23
+ 301 => 'Moved Permanently',
24
+ 302 => 'Moved Temporarily',
25
+ 303 => 'See Other',
26
+ 304 => 'Not Modified',
27
+ 305 => 'Use Proxy',
28
+ 307 => 'Temporary Redirect',
29
+ 400 => 'Bad Request',
30
+ 401 => 'Unauthorized',
31
+ 402 => 'Payment Required',
32
+ 403 => 'Forbidden',
33
+ 404 => 'Not Found',
34
+ 405 => 'Method Not Allowed',
35
+ 406 => 'Not Acceptable',
36
+ 407 => 'Proxy Authentication Required',
37
+ 408 => 'Request Timeout',
38
+ 409 => 'Conflict',
39
+ 410 => 'Gone',
40
+ 411 => 'Length Required',
41
+ 412 => 'Precondition Failed',
42
+ 413 => 'Request Entity Too Large',
43
+ 414 => 'Request-URI Too Long',
44
+ 415 => 'Unsupported Media Type',
45
+ 416 => 'Requested Range Not Satisfiable',
46
+ 417 => 'Expectation Failed',
47
+ 500 => 'Internal Server Error',
48
+ 501 => 'Not Implemented',
49
+ 502 => 'Bad Gateway',
50
+ 503 => 'Service Unavailable',
51
+ 504 => 'Gateway Timeout',
52
+ 505 => 'HTTP Version Not Supported'}
53
+ RESPONSE_CODES.each {|k,v| const_set(Iowa::String.new(v.gsub('-','_')).constant_case,k)}
54
+ end
55
+
56
+ attr_accessor :body, :calculate_runtime
57
+ alias :content :body
58
+ alias :content= :body=
59
+
60
+ def initialize(code=200, out = '')
61
+ self.status = code
62
+ @content_type = Ctext_html
63
+ @body = out
64
+ @headers = Iowa::DataTable.new
65
+ @headers.set('Cache-Control','private, max-age=0, no-store')
66
+ @calculate_runtime = false
67
+ end
68
+
69
+ def headers
70
+ @headers
71
+ end
72
+
73
+ def headers_out
74
+ @headers
75
+ end
76
+
77
+ def content_type
78
+ @content_type
79
+ end
80
+
81
+ # If given a complete type, such as 'text/csv', the type will be set as it
82
+ # was given. If given an incomplete type, such as 'gif' or 'csv', the type
83
+ # will be deduced or, if it can't be deduced, set to application/octet-stream.
84
+
85
+ def content_type=(type)
86
+ if type.index(C_slash)
87
+ @content_type = type
88
+ else
89
+ @content_type = MIME::Types.type_for(type).first || BINARY_TYPE
90
+ end
91
+ end
92
+
93
+ def status
94
+ @status
95
+ end
96
+
97
+ def status=(code)
98
+ if (rc = RESPONSE_CODES[code])
99
+ @status_line = "#{code} #{rc}"
100
+ @status = code
101
+ else
102
+ @status = 200
103
+ @status_line = '200 OK'
104
+ end
105
+ end
106
+
107
+ def status_line
108
+ @status_line
109
+ end
110
+
111
+ def status_line=(s)
112
+ s.gsub(/^\s*(\d+)\s+/) {self.status = $1.to_i; ''}
113
+ end
114
+
115
+ def <<(val)
116
+ @body << val
117
+ end
118
+
119
+ def cookie(name, val, args = {:path => C_slash})
120
+ parts = ["#{name}=#{val}"]
121
+ args.each {|k,v| parts << ["#{k}=#{v}"]}
122
+ self['Set-Cookie'] = parts.join(C_semicolon)
123
+ end
124
+
125
+ def [](val)
126
+ @headers.get(val)
127
+ end
128
+
129
+ def []=(k,v)
130
+ @headers.set(k,v)
131
+ end
132
+ end
133
+ end
@@ -0,0 +1,354 @@
1
+ require 'thread'
2
+ #require 'log4r'
3
+ #include Log4r
4
+ require 'iowa/SessionStats'
5
+
6
+ module Iowa
7
+
8
+ # Container for an inline generated resource.
9
+
10
+ class Resource
11
+
12
+ attr_accessor :body, :content_type, :headers
13
+
14
+ def initialize(body,content_type=Capplication_data,headers=nil)
15
+ @body = body
16
+ @content_type = content_type
17
+ @headers = headers
18
+ end
19
+ end
20
+
21
+ # Custom exception which is thrown if a request does not have a request ID.
22
+
23
+ class IgnoreRequest < Exception; end
24
+
25
+ class NoAction < Exception; end
26
+
27
+ # Custom exception which is thrown if a request asks for a page which has
28
+ # expired from the cache.
29
+
30
+ class PageExpired < Exception; end
31
+
32
+ # Represents a session between the application and the user.
33
+
34
+ class Session
35
+
36
+ # Default delay between the presentation of the page expired message
37
+ # (see this below) and the redirect to the top of the application.
38
+
39
+
40
+ # Class variable which holds the class of a session.
41
+
42
+
43
+ # Define an accessor to make the context object accessible to the
44
+ # application's code.
45
+
46
+ attr_accessor :context, :application, :currentPage, :requestCount, :pages,
47
+ :resourceCount, :notes, :access_time, :lock
48
+
49
+ @sessionClass = self
50
+
51
+ def Session.cachedPages
52
+ @cachedPages
53
+ end
54
+
55
+ def Session.cachedPages=(val)
56
+ @cachedPages = val
57
+ end
58
+
59
+ def Session.cacheTTL
60
+ @cacheTTL
61
+ end
62
+
63
+ def Session.cacheTTL=(val)
64
+ @cacheTTL = val
65
+ end
66
+
67
+ # Constructor to return a new instance of @sessionClass.
68
+
69
+ def Session.newSession(*args)
70
+ @sessionClass.new(*args)
71
+ end
72
+
73
+ def Session.inherited(subclass)
74
+ @sessionClass = subclass
75
+ end
76
+
77
+ def self.PageCache
78
+ @page_cache_class ? @page_cache_class.new(@page_class_args) : nil
79
+ end
80
+
81
+ def self.PageCache=(args)
82
+ @page_cache_class, @page_class_args = Util.get_cache(args,nil,Iowa.config[Csession],Cpagecache,true)
83
+ end
84
+
85
+ FCM = Iowa::Component.methods.inject({}) {|h,k| h[k] = true; h} unless const_defined?(:FCM)
86
+
87
+ # Initialize the state of the session.
88
+
89
+ def initialize
90
+ @cachedPages ||= 10
91
+ @cacheTTL ||= nil
92
+ @expiryDelay ||= 1
93
+ reset
94
+ #@lock = Iowa::Mutex.new
95
+ @lock = Mutex.new
96
+ @creation_time = Time.now
97
+ #@statistics = Iowa::SessionStats.new(@pages)
98
+ end
99
+
100
+ def statistics
101
+ @statistics
102
+ end
103
+
104
+ # Handles the current request from the browser. Essentially all that
105
+ # is happening is thread synchronizations along with some tests to make
106
+ # sure that all the data necessary to handle the request exists.
107
+ # Then the call to handleRequest gets passed on to the object representing
108
+ # the current page.
109
+
110
+ def handleRequest(context,dispatch_destination = nil)
111
+ dispatch_destination = Iowa::DispatchDestination.new(dispatch_destination) if dispatch_destination.is_a?(::String)
112
+ @fragment = nil
113
+ #@statistics.hit
114
+ @access_time = Time.now
115
+ mylog = Logger[Ciowa_log]
116
+ if @lock.locked?
117
+ mylog.info("Session collision. Waiting.")
118
+ end
119
+ #mylog.debug("Handle Session for #{dispatch_destination.inspect}")
120
+ # @lock.synchronize do
121
+ @lock.lock
122
+ # begin
123
+ context.session = self
124
+ requestPage = @currentPage
125
+ @context = context
126
+ unless !context.requestID || dispatch_destination
127
+ #begin
128
+ # If the request is for a resource, handle that.
129
+ return handle_resource(context) if @resources.has_key?("#{context.requestID}.#{context.actionID}")
130
+ # Bail out if that page is not in the cache. Remember that a request
131
+ # runs on the current page; it's the response that generates a new page.
132
+ raise PageExpired unless @pages.include?(context.requestID)
133
+ requestPage = @pages[context.requestID]
134
+
135
+ if @requestCount != context.requestID and !requestPage.replaceable?
136
+ requestPage.handleBacktrack
137
+ end
138
+
139
+ @currentPage = requestPage.replaceable? ? requestPage : requestPage.dup
140
+
141
+ # TODO: Make it a runtime option to reload modified or not.
142
+ @application.reloadModified(@currentPage.class.name)
143
+
144
+ context.phase = :handleRequest
145
+ @currentPage.session = self
146
+ @currentPage.handleRequest(context)
147
+ nextPage = context.invokeAction
148
+ if nextPage and nextPage.fragment
149
+ @fragment = nextPage
150
+ else
151
+ @currentPage = nextPage if nextPage
152
+ end
153
+
154
+ @requestCount = @requestCount.next
155
+ #end
156
+ else
157
+ @currentPage = requestPage
158
+ end
159
+ handleResponse(context, dispatch_destination)
160
+ rescue PageExpired => e
161
+ expired(@pages.queue.last,context)
162
+ rescue NoAction => e
163
+ mylog.info "Render last page seen because there is no action -- something is probably not right, here."
164
+ #expired(@pages.queue.last,context)
165
+ @currentPage = @pages[@pages.queue.last]
166
+ @currentPage.session = self
167
+ handleResponse(context)
168
+ ensure
169
+ @lock.unlock
170
+ # end
171
+ # end
172
+ end
173
+
174
+ # Specify a starting page name.
175
+ def startingPageName; 'Main'; end
176
+
177
+ # Return a component for the starting page; should use startingPageName.
178
+ def startingPage
179
+ Component.pageNamed(startingPageName,self)
180
+ rescue Exception => e
181
+ Logger[Ciowa_log].error "Starting page selection failed with #{e}\n#{e.backtrace.join("\n")}"
182
+ raise e
183
+ end
184
+
185
+ # Invokes the handleResponse() method on the object representing the page
186
+ # and updates the page cache.
187
+
188
+ def handleResponse(context, dispatch_destination = nil)
189
+ context.phase = :handleResponse
190
+ return if context.do_not_render
191
+ @currentPage = Component.pageNamed(dispatch_destination.component,self,nil,nil,nil) if dispatch_destination and dispatch_destination.component
192
+ @currentPage = startingPage unless @currentPage
193
+ if !dispatch_destination.nil? and (ddm = dispatch_destination.method) and !FCM.has_key?(ddm)
194
+ context.phase = :handleRequest
195
+ verb_specific_method = "#{ddm}_#{context.request.request_method.upcase}"
196
+ ddm = verb_specific_method if @currentPage.respond_to?(verb_specific_method)
197
+ if @currentPage.respond_to?(ddm)
198
+ @application.reloadModified(@currentPage.class.name)
199
+ @currentPage = context.invokeAction(@currentPage,ddm,dispatch_destination.args) || @currentPage
200
+ else
201
+ @currentPage = startingPage
202
+ end
203
+ context.phase = :handleResponse
204
+ end
205
+
206
+ fp = @currentPage.fingerprint
207
+ if fp and @application.rendered_content.has_key?(fp)
208
+ rc = @application.rendered_content[fp]
209
+ context.response_buffer << rc[0]
210
+ context.response.content_type = rc[1]
211
+ rc[2].each do |k,v|
212
+ context.response.headers[k] = v
213
+ end
214
+ else
215
+ context.requestID = @requestCount unless @currentPage.replaceable? or (@fragment and @fragment.replaceable?)
216
+ unless @fragment
217
+ @currentPage.handleResponse(context)
218
+ else
219
+ @fragment.handleResponse(context)
220
+ end
221
+
222
+ # The Session delays creating the pagecache until it is needed.
223
+ # This is a performance boost for the most common case, which is
224
+ # a page with some dynamic content, but no form elements or
225
+ # dynamic urls that depend on a cached page for meaning.
226
+
227
+ context[:allow_docroot_caching] = @currentPage.allow_docroot_caching?
228
+
229
+ unless context[:skip_pagecache]
230
+ initialize_pagecache if !@pages
231
+ @pages[context.requestID] = @currentPage if @currentPage.cacheable?
232
+ @pages[context.requestID].session = nil if @pages[context.requestID].respond_to?(:session) and @currentPage.cacheable?
233
+ else
234
+ @application.rendered_content[fp] = [context.response_buffer,context.response.content_type,context.response.headers] if fp
235
+ end
236
+ end
237
+ rescue Exception => e
238
+ Logger[Ciowa_log].error "Application#handleResponse exception: #{e}\n#{e.backtrace.join("\n")}"
239
+ raise e
240
+ end
241
+
242
+ # If one passes into resource_url content of some sort plus an optional
243
+ # content type (default is application/data if not specified), it will
244
+ # return a URL that can be used to access that content. If, on the
245
+ # other hand, one passes an arbitrary set of arguments and a block,
246
+ # a url will be returned that, when accesed, will cause the block to
247
+ # be executed. If the block returns an instance of Iowa::Resource,
248
+ # the content in the resource will be returned as a result of calling
249
+ # that URL, with the content type specified in the resource object.
250
+ # Any other return value will have that value returned as the result
251
+ # of calling the URL, with a content type of 'application/data'.
252
+ # The resources are tied to the page that created them, so they are
253
+ # available until the page expires. Once the page expires, the
254
+ # resource is deleted as well.
255
+ def resource_url(*args,&block)
256
+ if block_given?
257
+ resource = [block,args]
258
+ else
259
+ resource = Iowa::Resource.new(args[0], args[1], args[2])
260
+ end
261
+ resourceID = "r_#{@requestCount}.#{@resourceCount}"
262
+ @resources[resourceID] = resource
263
+ @resources_by_component[@context.requestID] ||= []
264
+ @resources_by_component[@context.requestID].push resourceID
265
+ @resourceCount = @resourceCount.next
266
+ return "#{@context.sessionURL}.#{resourceID}#{@context.locationFlag}"
267
+ end
268
+ alias :resourceUrl :resource_url
269
+
270
+ def handle_resource(context)
271
+ r = @resources["#{context.requestID}.#{context.actionID}"]
272
+ resource = r.kind_of?(Array) ? r[0].call(*r[1]) : r
273
+ if resource.kind_of? Iowa::Resource
274
+ context.response_buffer << resource.body
275
+ context.response.content_type = resource.content_type
276
+ if resource.headers
277
+ resource.headers.each do |k,v|
278
+ context.response.headers[k] = v
279
+ end
280
+ end
281
+ else
282
+ context.response << resource.to_s
283
+ context.response.content_type = Capplication_data
284
+ end
285
+ end
286
+
287
+ # Redirects the browser to the given URL. Second optional param is a true/false
288
+ # flag to indicate whether the redirect should be presented as permanent (301) or
289
+ # not (302).
290
+ def redirect(url,permanent = false)
291
+ context.response.headers[CLocation] = url
292
+ context.response.status = permanent ? 301 : 302
293
+ end
294
+
295
+ # Resets the session. Useful as part of logging someone out of an application.
296
+ # Once the page cache is cleared, they can not backtrack.
297
+
298
+ def reset
299
+ @currentPage = nil
300
+ @requestCount = 'a'
301
+ @resourceCount = 'a'
302
+ @resources = {}
303
+ @resources_by_component = {}
304
+ @notes = {C__keystack => []}
305
+ unless Iowa.config[Csession][Cpagecache][Cclass]
306
+ Iowa.config[Csession][Cpagecache][Cclass] = 'iowa/caches/LRUCache'
307
+ Iowa.config[Csession][Cpagecache][Cmaxsize] = @cachedPages
308
+ Iowa.config[Csession][Cpagecache][Cttl] = @cacheTTL
309
+ end
310
+ self.class.PageCache = nil unless self.class.PageCache
311
+ end
312
+
313
+ # Clears the page cache. Takes one optional argument. The
314
+ # first optional argument specifies how many entries to leave in the
315
+ # page cache; it defaults to 0.
316
+ def clear_history(leave = 0)
317
+ ps = @pages.size
318
+ @pages.size = leave
319
+ @pages.size = ps
320
+ GC.start
321
+ end
322
+
323
+ def [](v)
324
+ @notes[v]
325
+ end
326
+
327
+ def []=(k,v)
328
+ @notes[k] = v
329
+ end
330
+
331
+ private
332
+
333
+ def initialize_pagecache
334
+ @pages = self.class.PageCache
335
+ @pages.add_finalizer(@resources,@resources_by_component) do |key,obj,resources,resources_by_component|
336
+ if resources_by_component.has_key? key
337
+ resources_by_component[key].each do |res_id|
338
+ resources.delete res_id
339
+ end
340
+ resources_by_component.delete key
341
+ end
342
+ end
343
+ end
344
+
345
+ # Returns an explanation that the page being requested has expired, then
346
+ # issues a redirect to the head of the app. It'd be neat if there were
347
+ # some easy way to configure the contents of this page for an app.
348
+
349
+ def expired(most_recent_page,context)
350
+ context.response << "<html><head><meta http-equiv=REFRESH content='#{@expiryDelay}; URL=#{context.sessionURL}.#{most_recent_page}.0#{context.locationFlag}'></head><body><b>That page has expired.<p>You are being forwarded to your <a href='#{context.sessionURL}.#{most_recent_page}.0#{context.locationFlag}'>current point</a> in the session. Please continue from there.</b></body></html>"
351
+ end
352
+ end
353
+
354
+ end