mongrel_esi 0.5.0 → 0.5.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (202) hide show
  1. data/Rakefile +14 -6
  2. data/doc/rdoc/classes/ESI/CParser.html +122 -0
  3. data/doc/rdoc/classes/ESI/Cache.html +178 -0
  4. data/doc/rdoc/classes/ESI/Cache.src/M000085.html +17 -0
  5. data/doc/rdoc/classes/ESI/Cache.src/M000086.html +20 -0
  6. data/doc/rdoc/classes/ESI/Config.html +333 -0
  7. data/doc/rdoc/classes/ESI/Config.src/M000052.html +18 -0
  8. data/doc/rdoc/classes/ESI/Config.src/M000053.html +18 -0
  9. data/doc/rdoc/classes/ESI/Config.src/M000054.html +35 -0
  10. data/doc/rdoc/classes/ESI/Config.src/M000055.html +38 -0
  11. data/doc/rdoc/classes/ESI/Config.src/M000056.html +23 -0
  12. data/doc/rdoc/classes/ESI/Config.src/M000057.html +18 -0
  13. data/doc/rdoc/classes/ESI/Config.src/M000058.html +20 -0
  14. data/doc/rdoc/classes/ESI/Config.src/M000059.html +18 -0
  15. data/doc/rdoc/classes/ESI/Config.src/M000060.html +24 -0
  16. data/doc/rdoc/classes/ESI/Config/CacheConfig.html +212 -0
  17. data/doc/rdoc/classes/ESI/Config/CacheConfig.src/M000064.html +19 -0
  18. data/doc/rdoc/classes/ESI/Config/CacheConfig.src/M000065.html +19 -0
  19. data/doc/rdoc/classes/ESI/Config/CacheConfig.src/M000066.html +18 -0
  20. data/doc/rdoc/classes/ESI/Config/CacheConfig.src/M000067.html +18 -0
  21. data/doc/rdoc/classes/ESI/Config/CacheConfig.src/M000068.html +18 -0
  22. data/doc/rdoc/classes/ESI/Config/ConfigRouter.html +187 -0
  23. data/doc/rdoc/classes/ESI/Config/ConfigRouter.src/M000061.html +19 -0
  24. data/doc/rdoc/classes/ESI/Config/ConfigRouter.src/M000062.html +21 -0
  25. data/doc/rdoc/classes/ESI/Config/ConfigRouter.src/M000063.html +21 -0
  26. data/doc/rdoc/classes/ESI/Dispatcher.html +172 -0
  27. data/doc/rdoc/classes/ESI/Dispatcher.src/M000087.html +22 -0
  28. data/doc/rdoc/classes/ESI/Dispatcher.src/M000088.html +18 -0
  29. data/doc/rdoc/classes/ESI/Fragment.html +218 -0
  30. data/doc/rdoc/classes/ESI/Fragment.src/M000100.html +20 -0
  31. data/doc/rdoc/classes/ESI/Fragment.src/M000101.html +18 -0
  32. data/doc/rdoc/classes/ESI/Fragment.src/M000102.html +18 -0
  33. data/doc/rdoc/classes/ESI/Invalidator.html +131 -0
  34. data/doc/rdoc/classes/ESI/Invalidator.src/M000004.html +41 -0
  35. data/doc/rdoc/classes/ESI/Log.html +221 -0
  36. data/doc/rdoc/classes/ESI/Log.src/M000030.html +18 -0
  37. data/doc/rdoc/classes/ESI/Log.src/M000031.html +18 -0
  38. data/doc/rdoc/classes/ESI/Log.src/M000032.html +18 -0
  39. data/doc/rdoc/classes/ESI/Log.src/M000033.html +18 -0
  40. data/doc/rdoc/classes/ESI/Log.src/M000034.html +18 -0
  41. data/doc/rdoc/classes/ESI/Log.src/M000035.html +18 -0
  42. data/doc/rdoc/classes/ESI/Log.src/M000036.html +18 -0
  43. data/doc/rdoc/classes/ESI/MemcachedCache.html +314 -0
  44. data/doc/rdoc/classes/ESI/MemcachedCache.src/M000040.html +24 -0
  45. data/doc/rdoc/classes/ESI/MemcachedCache.src/M000041.html +22 -0
  46. data/doc/rdoc/classes/ESI/MemcachedCache.src/M000042.html +19 -0
  47. data/doc/rdoc/classes/ESI/MemcachedCache.src/M000043.html +23 -0
  48. data/doc/rdoc/classes/ESI/MemcachedCache.src/M000044.html +18 -0
  49. data/doc/rdoc/classes/ESI/MemcachedCache.src/M000045.html +19 -0
  50. data/doc/rdoc/classes/ESI/MemcachedCache.src/M000046.html +18 -0
  51. data/doc/rdoc/classes/ESI/MemcachedCache.src/M000047.html +18 -0
  52. data/doc/rdoc/classes/ESI/MemcachedCache.src/M000048.html +17 -0
  53. data/doc/rdoc/classes/ESI/Parser.html +184 -0
  54. data/doc/rdoc/classes/ESI/Parser.src/M000049.html +51 -0
  55. data/doc/rdoc/classes/ESI/Parser.src/M000050.html +39 -0
  56. data/doc/rdoc/classes/ESI/Parser.src/M000051.html +19 -0
  57. data/doc/rdoc/classes/ESI/Processor.html +194 -0
  58. data/doc/rdoc/classes/ESI/Processor.src/M000037.html +26 -0
  59. data/doc/rdoc/classes/ESI/Processor.src/M000038.html +44 -0
  60. data/doc/rdoc/classes/ESI/Processor.src/M000039.html +26 -0
  61. data/doc/rdoc/classes/ESI/Proxy.html +304 -0
  62. data/doc/rdoc/classes/ESI/Proxy.src/M000069.html +20 -0
  63. data/doc/rdoc/classes/ESI/Proxy.src/M000070.html +55 -0
  64. data/doc/rdoc/classes/ESI/Proxy.src/M000071.html +53 -0
  65. data/doc/rdoc/classes/ESI/Proxy.src/M000072.html +25 -0
  66. data/doc/rdoc/classes/ESI/Proxy.src/M000073.html +19 -0
  67. data/doc/rdoc/classes/ESI/Proxy.src/M000074.html +27 -0
  68. data/doc/rdoc/classes/ESI/Proxy.src/M000075.html +18 -0
  69. data/doc/rdoc/classes/ESI/Proxy.src/M000076.html +28 -0
  70. data/doc/rdoc/classes/ESI/Proxy.src/M000077.html +29 -0
  71. data/doc/rdoc/classes/ESI/Response.html +250 -0
  72. data/doc/rdoc/classes/ESI/Response.src/M000078.html +23 -0
  73. data/doc/rdoc/classes/ESI/Response.src/M000079.html +18 -0
  74. data/doc/rdoc/classes/ESI/Response.src/M000080.html +21 -0
  75. data/doc/rdoc/classes/ESI/Response.src/M000081.html +20 -0
  76. data/doc/rdoc/classes/ESI/Response.src/M000082.html +25 -0
  77. data/doc/rdoc/classes/ESI/Response.src/M000083.html +18 -0
  78. data/doc/rdoc/classes/ESI/Response.src/M000084.html +33 -0
  79. data/doc/rdoc/classes/ESI/Router.html +212 -0
  80. data/doc/rdoc/classes/ESI/Router.src/M000098.html +36 -0
  81. data/doc/rdoc/classes/ESI/Router.src/M000099.html +25 -0
  82. data/doc/rdoc/classes/ESI/RubyCache.html +278 -0
  83. data/doc/rdoc/classes/ESI/RubyCache.src/M000089.html +20 -0
  84. data/doc/rdoc/classes/ESI/RubyCache.src/M000090.html +20 -0
  85. data/doc/rdoc/classes/ESI/RubyCache.src/M000091.html +20 -0
  86. data/doc/rdoc/classes/ESI/RubyCache.src/M000092.html +22 -0
  87. data/doc/rdoc/classes/ESI/RubyCache.src/M000093.html +18 -0
  88. data/doc/rdoc/classes/ESI/RubyCache.src/M000094.html +22 -0
  89. data/doc/rdoc/classes/ESI/RubyCache.src/M000095.html +18 -0
  90. data/doc/rdoc/classes/ESI/RubyCache.src/M000096.html +18 -0
  91. data/doc/rdoc/classes/ESI/RubyCache.src/M000097.html +18 -0
  92. data/doc/rdoc/classes/ESI/Tag.html +141 -0
  93. data/doc/rdoc/classes/ESI/Tag/Attempt.html +113 -0
  94. data/doc/rdoc/classes/ESI/Tag/Base.html +237 -0
  95. data/doc/rdoc/classes/ESI/Tag/Base.src/M000026.html +23 -0
  96. data/doc/rdoc/classes/ESI/Tag/Base.src/M000027.html +22 -0
  97. data/doc/rdoc/classes/ESI/Tag/Base.src/M000028.html +22 -0
  98. data/doc/rdoc/classes/ESI/Tag/Base.src/M000029.html +17 -0
  99. data/doc/rdoc/classes/ESI/Tag/Container.html +206 -0
  100. data/doc/rdoc/classes/ESI/Tag/Container.src/M000015.html +20 -0
  101. data/doc/rdoc/classes/ESI/Tag/Container.src/M000016.html +22 -0
  102. data/doc/rdoc/classes/ESI/Tag/Container.src/M000017.html +25 -0
  103. data/doc/rdoc/classes/ESI/Tag/Except.html +184 -0
  104. data/doc/rdoc/classes/ESI/Tag/Except.src/M000018.html +21 -0
  105. data/doc/rdoc/classes/ESI/Tag/Except.src/M000019.html +20 -0
  106. data/doc/rdoc/classes/ESI/Tag/Except.src/M000020.html +18 -0
  107. data/doc/rdoc/classes/ESI/Tag/Include.html +257 -0
  108. data/doc/rdoc/classes/ESI/Tag/Include.src/M000005.html +20 -0
  109. data/doc/rdoc/classes/ESI/Tag/Include.src/M000006.html +18 -0
  110. data/doc/rdoc/classes/ESI/Tag/Include.src/M000007.html +34 -0
  111. data/doc/rdoc/classes/ESI/Tag/Include.src/M000008.html +22 -0
  112. data/doc/rdoc/classes/ESI/Tag/Include.src/M000009.html +27 -0
  113. data/doc/rdoc/classes/ESI/Tag/Include.src/M000010.html +30 -0
  114. data/doc/rdoc/classes/ESI/Tag/Include.src/M000011.html +51 -0
  115. data/doc/rdoc/classes/ESI/Tag/Include/Request.html +199 -0
  116. data/doc/rdoc/classes/ESI/Tag/Include/Request.src/M000012.html +18 -0
  117. data/doc/rdoc/classes/ESI/Tag/Include/Request.src/M000013.html +44 -0
  118. data/doc/rdoc/classes/ESI/Tag/Include/Request/Error.html +155 -0
  119. data/doc/rdoc/classes/ESI/Tag/Include/Request/Error.src/M000014.html +19 -0
  120. data/doc/rdoc/classes/ESI/Tag/Invalidate.html +171 -0
  121. data/doc/rdoc/classes/ESI/Tag/Invalidate.src/M000023.html +19 -0
  122. data/doc/rdoc/classes/ESI/Tag/Invalidate.src/M000024.html +51 -0
  123. data/doc/rdoc/classes/ESI/Tag/Invalidate.src/M000025.html +19 -0
  124. data/doc/rdoc/classes/ESI/Tag/Try.html +154 -0
  125. data/doc/rdoc/classes/ESI/Tag/Try.src/M000021.html +38 -0
  126. data/doc/rdoc/classes/ESI/Tag/Try.src/M000022.html +18 -0
  127. data/doc/rdoc/classes/MultiDirHandler.html +198 -0
  128. data/doc/rdoc/classes/MultiDirHandler.src/M000001.html +20 -0
  129. data/doc/rdoc/classes/MultiDirHandler.src/M000002.html +28 -0
  130. data/doc/rdoc/classes/MultiDirHandler.src/M000003.html +22 -0
  131. data/doc/rdoc/created.rid +1 -0
  132. data/doc/rdoc/files/COPYING.html +167 -0
  133. data/doc/rdoc/files/LICENSE.html +605 -0
  134. data/doc/rdoc/files/README.html +359 -0
  135. data/doc/rdoc/files/ext/esi/common_rl.html +160 -0
  136. data/doc/rdoc/files/ext/esi/esi_parser_c.html +101 -0
  137. data/doc/rdoc/files/ext/esi/parser_c.html +101 -0
  138. data/doc/rdoc/files/ext/esi/parser_h.html +101 -0
  139. data/doc/rdoc/files/ext/esi/parser_rl.html +827 -0
  140. data/doc/rdoc/files/ext/esi/test/common_rl.html +160 -0
  141. data/doc/rdoc/files/ext/esi/test/parser_c.html +101 -0
  142. data/doc/rdoc/files/ext/esi/test/parser_h.html +101 -0
  143. data/doc/rdoc/files/ext/esi/test/parser_rl.html +827 -0
  144. data/doc/rdoc/files/ext/esi/test/sp_c.html +101 -0
  145. data/doc/rdoc/files/ext/esi/test/test_c.html +101 -0
  146. data/doc/rdoc/files/lib/esi/cache_rb.html +119 -0
  147. data/doc/rdoc/files/lib/esi/config_rb.html +114 -0
  148. data/doc/rdoc/files/lib/esi/dispatcher_rb.html +108 -0
  149. data/doc/rdoc/files/lib/esi/invalidator_rb.html +114 -0
  150. data/doc/rdoc/files/lib/esi/logger_rb.html +108 -0
  151. data/doc/rdoc/files/lib/esi/parser_rb.html +120 -0
  152. data/doc/rdoc/files/lib/esi/processor_rb.html +115 -0
  153. data/doc/rdoc/files/lib/esi/proxy_rb.html +123 -0
  154. data/doc/rdoc/files/lib/esi/response_rb.html +116 -0
  155. data/doc/rdoc/files/lib/esi/router_rb.html +107 -0
  156. data/doc/rdoc/files/lib/esi/tag/attempt_rb.html +114 -0
  157. data/doc/rdoc/files/lib/esi/tag/base_rb.html +114 -0
  158. data/doc/rdoc/files/lib/esi/tag/container_rb.html +115 -0
  159. data/doc/rdoc/files/lib/esi/tag/except_rb.html +114 -0
  160. data/doc/rdoc/files/lib/esi/tag/include_rb.html +116 -0
  161. data/doc/rdoc/files/lib/esi/tag/invalidate_rb.html +115 -0
  162. data/doc/rdoc/files/lib/esi/tag/try_rb.html +115 -0
  163. data/doc/rdoc/files/lib/esi/version_rb.html +101 -0
  164. data/doc/rdoc/files/lib/multi_dirhandler_rb.html +109 -0
  165. data/doc/rdoc/fr_class_index.html +53 -0
  166. data/doc/rdoc/fr_file_index.html +59 -0
  167. data/doc/rdoc/fr_method_index.html +128 -0
  168. data/doc/rdoc/index.html +24 -0
  169. data/doc/rdoc/rdoc-style.css +208 -0
  170. data/ext/esi/esi_parser.c +12 -1
  171. data/ext/esi/parser.c +492 -3927
  172. data/ext/esi/parser.rl +83 -14
  173. data/ext/esi/test/parser.c +1587 -367
  174. data/ext/esi/test/parser.rl +83 -14
  175. data/ext/esi/test/sp.c +125 -0
  176. data/ext/esi/test/test.c +198 -6
  177. data/lib/esi/cache.rb +5 -8
  178. data/lib/esi/config.rb +3 -3
  179. data/lib/esi/dispatcher.rb +2 -4
  180. data/lib/esi/parser.rb +26 -13
  181. data/lib/esi/processor.rb +13 -35
  182. data/lib/esi/proxy.rb +113 -44
  183. data/lib/esi/response.rb +23 -55
  184. data/lib/esi/router.rb +0 -11
  185. data/lib/esi/tag/attempt.rb +2 -1
  186. data/lib/esi/tag/base.rb +1 -24
  187. data/lib/esi/tag/container.rb +40 -0
  188. data/lib/esi/tag/except.rb +3 -1
  189. data/lib/esi/tag/include.rb +53 -62
  190. data/lib/esi/tag/try.rb +16 -18
  191. data/lib/esi/version.rb +9 -0
  192. data/test/integration/handler_test.rb +49 -12
  193. data/test/integration/help.rb +12 -0
  194. data/test/load_test.rb +8 -4
  195. data/test/load_test_ab.rb +8 -0
  196. data/test/sample.html +31 -0
  197. data/test/unit/help.rb +12 -8
  198. data/test/unit/include_request_test.rb +14 -21
  199. data/test/unit/parser_test.rb +2 -1
  200. data/test/unit/response_test.rb +4 -8
  201. data/tools/rakehelp.rb +1 -1
  202. metadata +216 -5
@@ -0,0 +1,101 @@
1
+ <?xml version="1.0" encoding="iso-8859-1"?>
2
+ <!DOCTYPE html
3
+ PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
4
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
5
+
6
+ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
7
+ <head>
8
+ <title>File: esi_parser.c</title>
9
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
10
+ <meta http-equiv="Content-Script-Type" content="text/javascript" />
11
+ <link rel="stylesheet" href="../../.././rdoc-style.css" type="text/css" media="screen" />
12
+ <script type="text/javascript">
13
+ // <![CDATA[
14
+
15
+ function popupCode( url ) {
16
+ window.open(url, "Code", "resizable=yes,scrollbars=yes,toolbar=no,status=no,height=150,width=400")
17
+ }
18
+
19
+ function toggleCode( id ) {
20
+ if ( document.getElementById )
21
+ elem = document.getElementById( id );
22
+ else if ( document.all )
23
+ elem = eval( "document.all." + id );
24
+ else
25
+ return false;
26
+
27
+ elemStyle = elem.style;
28
+
29
+ if ( elemStyle.display != "block" ) {
30
+ elemStyle.display = "block"
31
+ } else {
32
+ elemStyle.display = "none"
33
+ }
34
+
35
+ return true;
36
+ }
37
+
38
+ // Make codeblocks hidden by default
39
+ document.writeln( "<style type=\"text/css\">div.method-source-code { display: none }</style>" )
40
+
41
+ // ]]>
42
+ </script>
43
+
44
+ </head>
45
+ <body>
46
+
47
+
48
+
49
+ <div id="fileHeader">
50
+ <h1>esi_parser.c</h1>
51
+ <table class="header-table">
52
+ <tr class="top-aligned-row">
53
+ <td><strong>Path:</strong></td>
54
+ <td>ext/esi/esi_parser.c
55
+ </td>
56
+ </tr>
57
+ <tr class="top-aligned-row">
58
+ <td><strong>Last Update:</strong></td>
59
+ <td>Tue Jun 10 10:15:53 -0400 2008</td>
60
+ </tr>
61
+ </table>
62
+ </div>
63
+ <!-- banner header -->
64
+
65
+ <div id="bodyContent">
66
+
67
+
68
+
69
+ <div id="contextContent">
70
+
71
+
72
+
73
+ </div>
74
+
75
+
76
+ </div>
77
+
78
+
79
+ <!-- if includes -->
80
+
81
+ <div id="section">
82
+
83
+
84
+
85
+
86
+
87
+
88
+
89
+
90
+ <!-- if method_list -->
91
+
92
+
93
+ </div>
94
+
95
+
96
+ <div id="validator-badges">
97
+ <p><small><a href="http://validator.w3.org/check/referer">[Validate]</a></small></p>
98
+ </div>
99
+
100
+ </body>
101
+ </html>
@@ -0,0 +1,101 @@
1
+ <?xml version="1.0" encoding="iso-8859-1"?>
2
+ <!DOCTYPE html
3
+ PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
4
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
5
+
6
+ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
7
+ <head>
8
+ <title>File: parser.c</title>
9
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
10
+ <meta http-equiv="Content-Script-Type" content="text/javascript" />
11
+ <link rel="stylesheet" href="../../.././rdoc-style.css" type="text/css" media="screen" />
12
+ <script type="text/javascript">
13
+ // <![CDATA[
14
+
15
+ function popupCode( url ) {
16
+ window.open(url, "Code", "resizable=yes,scrollbars=yes,toolbar=no,status=no,height=150,width=400")
17
+ }
18
+
19
+ function toggleCode( id ) {
20
+ if ( document.getElementById )
21
+ elem = document.getElementById( id );
22
+ else if ( document.all )
23
+ elem = eval( "document.all." + id );
24
+ else
25
+ return false;
26
+
27
+ elemStyle = elem.style;
28
+
29
+ if ( elemStyle.display != "block" ) {
30
+ elemStyle.display = "block"
31
+ } else {
32
+ elemStyle.display = "none"
33
+ }
34
+
35
+ return true;
36
+ }
37
+
38
+ // Make codeblocks hidden by default
39
+ document.writeln( "<style type=\"text/css\">div.method-source-code { display: none }</style>" )
40
+
41
+ // ]]>
42
+ </script>
43
+
44
+ </head>
45
+ <body>
46
+
47
+
48
+
49
+ <div id="fileHeader">
50
+ <h1>parser.c</h1>
51
+ <table class="header-table">
52
+ <tr class="top-aligned-row">
53
+ <td><strong>Path:</strong></td>
54
+ <td>ext/esi/parser.c
55
+ </td>
56
+ </tr>
57
+ <tr class="top-aligned-row">
58
+ <td><strong>Last Update:</strong></td>
59
+ <td>Mon Jun 16 11:19:34 -0400 2008</td>
60
+ </tr>
61
+ </table>
62
+ </div>
63
+ <!-- banner header -->
64
+
65
+ <div id="bodyContent">
66
+
67
+
68
+
69
+ <div id="contextContent">
70
+
71
+
72
+
73
+ </div>
74
+
75
+
76
+ </div>
77
+
78
+
79
+ <!-- if includes -->
80
+
81
+ <div id="section">
82
+
83
+
84
+
85
+
86
+
87
+
88
+
89
+
90
+ <!-- if method_list -->
91
+
92
+
93
+ </div>
94
+
95
+
96
+ <div id="validator-badges">
97
+ <p><small><a href="http://validator.w3.org/check/referer">[Validate]</a></small></p>
98
+ </div>
99
+
100
+ </body>
101
+ </html>
@@ -0,0 +1,101 @@
1
+ <?xml version="1.0" encoding="iso-8859-1"?>
2
+ <!DOCTYPE html
3
+ PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
4
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
5
+
6
+ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
7
+ <head>
8
+ <title>File: parser.h</title>
9
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
10
+ <meta http-equiv="Content-Script-Type" content="text/javascript" />
11
+ <link rel="stylesheet" href="../../.././rdoc-style.css" type="text/css" media="screen" />
12
+ <script type="text/javascript">
13
+ // <![CDATA[
14
+
15
+ function popupCode( url ) {
16
+ window.open(url, "Code", "resizable=yes,scrollbars=yes,toolbar=no,status=no,height=150,width=400")
17
+ }
18
+
19
+ function toggleCode( id ) {
20
+ if ( document.getElementById )
21
+ elem = document.getElementById( id );
22
+ else if ( document.all )
23
+ elem = eval( "document.all." + id );
24
+ else
25
+ return false;
26
+
27
+ elemStyle = elem.style;
28
+
29
+ if ( elemStyle.display != "block" ) {
30
+ elemStyle.display = "block"
31
+ } else {
32
+ elemStyle.display = "none"
33
+ }
34
+
35
+ return true;
36
+ }
37
+
38
+ // Make codeblocks hidden by default
39
+ document.writeln( "<style type=\"text/css\">div.method-source-code { display: none }</style>" )
40
+
41
+ // ]]>
42
+ </script>
43
+
44
+ </head>
45
+ <body>
46
+
47
+
48
+
49
+ <div id="fileHeader">
50
+ <h1>parser.h</h1>
51
+ <table class="header-table">
52
+ <tr class="top-aligned-row">
53
+ <td><strong>Path:</strong></td>
54
+ <td>ext/esi/parser.h
55
+ </td>
56
+ </tr>
57
+ <tr class="top-aligned-row">
58
+ <td><strong>Last Update:</strong></td>
59
+ <td>Mon Jun 16 11:18:31 -0400 2008</td>
60
+ </tr>
61
+ </table>
62
+ </div>
63
+ <!-- banner header -->
64
+
65
+ <div id="bodyContent">
66
+
67
+
68
+
69
+ <div id="contextContent">
70
+
71
+
72
+
73
+ </div>
74
+
75
+
76
+ </div>
77
+
78
+
79
+ <!-- if includes -->
80
+
81
+ <div id="section">
82
+
83
+
84
+
85
+
86
+
87
+
88
+
89
+
90
+ <!-- if method_list -->
91
+
92
+
93
+ </div>
94
+
95
+
96
+ <div id="validator-badges">
97
+ <p><small><a href="http://validator.w3.org/check/referer">[Validate]</a></small></p>
98
+ </div>
99
+
100
+ </body>
101
+ </html>
@@ -0,0 +1,827 @@
1
+ <?xml version="1.0" encoding="iso-8859-1"?>
2
+ <!DOCTYPE html
3
+ PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
4
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
5
+
6
+ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
7
+ <head>
8
+ <title>File: parser.rl</title>
9
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
10
+ <meta http-equiv="Content-Script-Type" content="text/javascript" />
11
+ <link rel="stylesheet" href="../../.././rdoc-style.css" type="text/css" media="screen" />
12
+ <script type="text/javascript">
13
+ // <![CDATA[
14
+
15
+ function popupCode( url ) {
16
+ window.open(url, "Code", "resizable=yes,scrollbars=yes,toolbar=no,status=no,height=150,width=400")
17
+ }
18
+
19
+ function toggleCode( id ) {
20
+ if ( document.getElementById )
21
+ elem = document.getElementById( id );
22
+ else if ( document.all )
23
+ elem = eval( "document.all." + id );
24
+ else
25
+ return false;
26
+
27
+ elemStyle = elem.style;
28
+
29
+ if ( elemStyle.display != "block" ) {
30
+ elemStyle.display = "block"
31
+ } else {
32
+ elemStyle.display = "none"
33
+ }
34
+
35
+ return true;
36
+ }
37
+
38
+ // Make codeblocks hidden by default
39
+ document.writeln( "<style type=\"text/css\">div.method-source-code { display: none }</style>" )
40
+
41
+ // ]]>
42
+ </script>
43
+
44
+ </head>
45
+ <body>
46
+
47
+
48
+
49
+ <div id="fileHeader">
50
+ <h1>parser.rl</h1>
51
+ <table class="header-table">
52
+ <tr class="top-aligned-row">
53
+ <td><strong>Path:</strong></td>
54
+ <td>ext/esi/parser.rl
55
+ </td>
56
+ </tr>
57
+ <tr class="top-aligned-row">
58
+ <td><strong>Last Update:</strong></td>
59
+ <td>Mon Jun 16 11:19:27 -0400 2008</td>
60
+ </tr>
61
+ </table>
62
+ </div>
63
+ <!-- banner header -->
64
+
65
+ <div id="bodyContent">
66
+
67
+
68
+
69
+ <div id="contextContent">
70
+
71
+ <div id="description">
72
+ <p>
73
+ /**
74
+ </p>
75
+ <pre>
76
+ * Copyright (c) 2008 Todd A. Fisher
77
+ * see LICENSE
78
+ */
79
+ </pre>
80
+ <p>
81
+ include &lt;stdio.h&gt; include &lt;stdlib.h&gt; include &lt;string.h&gt;
82
+ include &lt;ctype.h&gt; include &quot;parser.h&quot;
83
+ </p>
84
+ <p>
85
+ ifdef DEBUG static void debug_string( const char *msg, const char *str,
86
+ size_t len ) {
87
+ </p>
88
+ <pre>
89
+ char *pstr = esi_strndup( str, len );
90
+ printf( &quot;%s :'%s'\n&quot;, msg, pstr );
91
+ free( pstr );
92
+ </pre>
93
+ <p>
94
+ } else define debug_string(m,s,l) endif
95
+ </p>
96
+ <p>
97
+ /* define default callbacks */ static void esi_parser_default_start_cb(
98
+ const void *data,
99
+ </p>
100
+ <pre>
101
+ const char *name_start,
102
+ size_t name_length,
103
+ ESIAttribute *attributes,
104
+ void *user_data )
105
+ </pre>
106
+ <p>
107
+ { } static void esi_parser_default_end_cb( const void *data,
108
+ </p>
109
+ <pre>
110
+ const char *name_start,
111
+ size_t name_length,
112
+ void *user_data )
113
+ </pre>
114
+ <p>
115
+ { } static void esi_parser_default_output_cp(const void *data,
116
+ </p>
117
+ <pre>
118
+ size_t length,
119
+ void *user_data)
120
+ </pre>
121
+ <p>
122
+ { }
123
+ </p>
124
+ <p>
125
+ /*
126
+ </p>
127
+ <pre>
128
+ * flush output buffer
129
+ */
130
+ </pre>
131
+ <p>
132
+ static void esi_parser_flush_output( ESIParser *parser ) {
133
+ </p>
134
+ <pre>
135
+ if( parser-&gt;output_buffer_size &gt; 0 ) {
136
+ //debug_string( &quot;esi_parser_flush_output:&quot;, parser-&gt;output_buffer, parser-&gt;output_buffer_size );
137
+ parser-&gt;output_handler( (void*)parser-&gt;output_buffer, parser-&gt;output_buffer_size, parser-&gt;user_data );
138
+ parser-&gt;output_buffer_size = 0;
139
+ }
140
+ </pre>
141
+ <p>
142
+ } /* send the character to the output handler marking it
143
+ </p>
144
+ <pre>
145
+ * as ready for consumption, e.g. not an esi tag
146
+ */
147
+ </pre>
148
+ <p>
149
+ static void esi_parser_echo_char( ESIParser *parser, char ch ) {
150
+ </p>
151
+ <pre>
152
+ parser-&gt;output_buffer[parser-&gt;output_buffer_size++] = ch;
153
+ if( parser-&gt;output_buffer_size == ESI_OUTPUT_BUFFER_SIZE ) {
154
+ // flush the buffer to the consumer
155
+ esi_parser_flush_output( parser );
156
+ }
157
+ </pre>
158
+ <p>
159
+ } /* send any buffered characters to the output handler.
160
+ </p>
161
+ <pre>
162
+ * This happens when we enter a case such as &lt;em&gt; where the
163
+ * first two characters &lt; and e match the &lt;esi: expression
164
+ */
165
+ </pre>
166
+ <p>
167
+ static void esi_parser_echo_buffer( ESIParser *parser ) {
168
+ </p>
169
+ <pre>
170
+ size_t i = 0, len = parser-&gt;echobuffer_index + 1;;
171
+ //debug_string( &quot;echobuffer&quot;, parser-&gt;echobuffer, parser-&gt;echobuffer_index+1 );
172
+ //parser-&gt;output_handler( parser-&gt;echobuffer, parser-&gt;echobuffer_index+1, parser-&gt;user_data );
173
+ for( ; i &lt; len; ++i ) {
174
+ esi_parser_echo_char( parser, parser-&gt;echobuffer[i] );
175
+ }
176
+ </pre>
177
+ <p>
178
+ } /*
179
+ </p>
180
+ <pre>
181
+ * clear the buffer, no buffered characters should be emitted .
182
+ * e.g. we matched an esi tag completely and all buffered characters can be tossed out
183
+ */
184
+ </pre>
185
+ <p>
186
+ static void esi_parser_echobuffer_clear( ESIParser *parser ) {
187
+ </p>
188
+ <pre>
189
+ parser-&gt;echobuffer_index = -1;
190
+ </pre>
191
+ <p>
192
+ }
193
+ </p>
194
+ <p>
195
+ /*
196
+ </p>
197
+ <pre>
198
+ * add a character to the echobuffer.
199
+ * this happens when we can't determine if the character is allowed to be sent to the client device
200
+ * e.g. matching &lt;e it's not yet determined if these characters are safe to send or not
201
+ */
202
+ </pre>
203
+ <p>
204
+ static void esi_parser_concat_to_echobuffer( ESIParser *parser, char ch ) {
205
+ </p>
206
+ <pre>
207
+ parser-&gt;echobuffer_index++;
208
+
209
+ if( parser-&gt;echobuffer_allocated &lt;= parser-&gt;echobuffer_index ) {
210
+ /* double the echobuffer size
211
+ * we're getting some crazy input if this case ever happens
212
+ */
213
+ parser-&gt;echobuffer_allocated *= 2;
214
+ parser-&gt;echobuffer = (char*)realloc( parser-&gt;echobuffer, parser-&gt;echobuffer_allocated );
215
+ }
216
+ parser-&gt;echobuffer[parser-&gt;echobuffer_index] = ch;
217
+ </pre>
218
+ <p>
219
+ // debug_string( &quot;echo buffer&quot;, parser-&gt;echobuffer,
220
+ parser-&gt;echobuffer_index+1 ); } /*
221
+ </p>
222
+ <pre>
223
+ * the mark boundary is not always going to be exactly on the attribute or tag name boundary
224
+ * this trims characters from the left to right, advancing *ptr and reducing *len
225
+ */
226
+ </pre>
227
+ <p>
228
+ static void ltrim_pointer( const char **ptr, const char *bounds, size_t
229
+ *len ) {
230
+ </p>
231
+ <pre>
232
+ // remove any spaces or = at the before the value
233
+ while( (isspace( **ptr ) ||
234
+ **ptr == '=' ||
235
+ **ptr == '&quot;' ||
236
+ **ptr == '&lt;' ||
237
+ **ptr == '\'' ) &amp;&amp; (*len &gt; 0) &amp;&amp; (*ptr != bounds) ) {
238
+ (*ptr)++;
239
+ (*len)--;
240
+ }
241
+ </pre>
242
+ <p>
243
+ } /*
244
+ </p>
245
+ <pre>
246
+ * similar to ltrim_pointer, this walks from bounds to *ptr, reducing *len
247
+ */
248
+ </pre>
249
+ <p>
250
+ static void rtrim_pointer( const char **ptr, const char *bounds, size_t
251
+ *len ) {
252
+ </p>
253
+ <pre>
254
+ bounds = (*ptr+(*len-1));
255
+ // remove any spaces or = at the before the value
256
+ while( (isspace( *bounds ) ||
257
+ *bounds == '=' ||
258
+ *bounds == '&quot;' ||
259
+ *bounds == '&gt;' ||
260
+ *bounds == '\'') &amp;&amp; (*len &gt; 0) &amp;&amp; (*ptr != bounds) ){
261
+ bounds--;
262
+ (*len)--;
263
+ }
264
+ </pre>
265
+ <p>
266
+ }
267
+ </p>
268
+ <p>
269
+ %%{
270
+ </p>
271
+ <pre>
272
+ machine esi;
273
+
274
+ action begin {
275
+ parser-&gt;mark = p;
276
+ //debug_string( &quot;begin&quot;, p, 1 );
277
+ }
278
+ action finish {
279
+ </pre>
280
+ <p>
281
+ // printf( &quot;finish\n&quot; );
282
+ </p>
283
+ <pre>
284
+ }
285
+
286
+ # record the position of the start tag
287
+ action see_start_tag {
288
+ parser-&gt;tag_text = parser-&gt;mark+1;
289
+ parser-&gt;tag_text_length = p - (parser-&gt;mark+1);
290
+ parser-&gt;mark = p;
291
+ }
292
+
293
+ # detected an inline tag end, sends the start tag and end tag callback
294
+ action see_end_tag {
295
+ /* trim the tag text */
296
+ ltrim_pointer( &amp;(parser-&gt;tag_text), p, &amp;(parser-&gt;tag_text_length) );
297
+ rtrim_pointer( &amp;(parser-&gt;tag_text), p, &amp;(parser-&gt;tag_text_length) );
298
+
299
+ /* send the start tag and end tag message */
300
+ esi_parser_flush_output( parser );
301
+ parser-&gt;start_tag_handler( data, parser-&gt;tag_text, parser-&gt;tag_text_length, parser-&gt;attributes, parser-&gt;user_data );
302
+ esi_parser_flush_output( parser );
303
+ parser-&gt;end_tag_handler( data, parser-&gt;tag_text, parser-&gt;tag_text_length, parser-&gt;user_data );
304
+ esi_parser_flush_output( parser );
305
+
306
+ /* mark the position */
307
+ parser-&gt;tag_text = NULL;
308
+ parser-&gt;tag_text_length = 0;
309
+ parser-&gt;mark = p;
310
+
311
+ /* clear out the echo buffer */
312
+ esi_parser_echobuffer_clear( parser );
313
+ }
314
+
315
+ # block tag start, with attributes
316
+ action see_block_start_with_attributes {
317
+ /* trim tag text */
318
+ ltrim_pointer( &amp;(parser-&gt;tag_text), p, &amp;(parser-&gt;tag_text_length) );
319
+ rtrim_pointer( &amp;(parser-&gt;tag_text), p, &amp;(parser-&gt;tag_text_length) );
320
+
321
+ /* send the start and end tag message */
322
+ esi_parser_flush_output( parser );
323
+ parser-&gt;start_tag_handler( data, parser-&gt;tag_text, parser-&gt;tag_text_length, parser-&gt;attributes, parser-&gt;user_data );
324
+ esi_parser_flush_output( parser );
325
+
326
+ parser-&gt;tag_text = NULL;
327
+ parser-&gt;tag_text_length = 0;
328
+ parser-&gt;mark = p;
329
+
330
+ /* clear out the echo buffer */
331
+ esi_parser_echobuffer_clear( parser );
332
+ }
333
+
334
+ # see an attribute key, /foo\s*=/
335
+ action see_attribute_key {
336
+ /* save the attribute key start */
337
+ parser-&gt;attr_key = parser-&gt;mark;
338
+ /* compute the length of the key */
339
+ parser-&gt;attr_key_length = p - parser-&gt;mark;
340
+ /* save the position following the key */
341
+ parser-&gt;mark = p;
342
+
343
+ /* trim the attribute key */
344
+ ltrim_pointer( &amp;(parser-&gt;attr_key), p, &amp;(parser-&gt;attr_key_length) );
345
+ rtrim_pointer( &amp;(parser-&gt;attr_key), p, &amp;(parser-&gt;attr_key_length) );
346
+ }
347
+
348
+ # see an attribute value, aprox ~= /['&quot;].*['&quot;]/
349
+ action see_attribute_value {
350
+ ESIAttribute *attr;
351
+
352
+ /* save the attribute value start */
353
+ parser-&gt;attr_value = parser-&gt;mark;
354
+ /* compute the length of the value */
355
+ parser-&gt;attr_value_length = p - parser-&gt;mark;
356
+ /* svae the position following the value */
357
+ parser-&gt;mark = p;
358
+
359
+ /* trim the attribute value */
360
+ ltrim_pointer( &amp;(parser-&gt;attr_value), p, &amp;(parser-&gt;attr_value_length) );
361
+ rtrim_pointer( &amp;(parser-&gt;attr_value), p, &amp;(parser-&gt;attr_value_length) );
362
+
363
+ /* using the attr_key and attr_value, allocate a new attribute object */
364
+ attr = esi_attribute_new( parser-&gt;attr_key, parser-&gt;attr_key_length,
365
+ parser-&gt;attr_value, parser-&gt;attr_value_length );
366
+
367
+ /* add the new attribute to the list of attributes */
368
+ if( parser-&gt;attributes ) {
369
+ parser-&gt;last-&gt;next = attr;
370
+ parser-&gt;last = attr;
371
+ }
372
+ else {
373
+ parser-&gt;last = parser-&gt;attributes = attr;
374
+ }
375
+ }
376
+
377
+ # simple block start tag detected, e.g. &lt;esi:try&gt; no attributes
378
+ action block_start_tag {
379
+
380
+ parser-&gt;tag_text = parser-&gt;mark;
381
+ parser-&gt;tag_text_length = p - parser-&gt;mark;
382
+
383
+ parser-&gt;mark = p;
384
+
385
+ ltrim_pointer( &amp;(parser-&gt;tag_text), p, &amp;(parser-&gt;tag_text_length) );
386
+ rtrim_pointer( &amp;(parser-&gt;tag_text), p, &amp;(parser-&gt;tag_text_length) );
387
+
388
+ esi_parser_flush_output( parser );
389
+ parser-&gt;start_tag_handler( data, parser-&gt;tag_text, parser-&gt;tag_text_length, NULL, parser-&gt;user_data );
390
+ esi_parser_flush_output( parser );
391
+
392
+ esi_parser_echobuffer_clear( parser );
393
+ }
394
+
395
+ # block end tag detected, e.g. &lt;/esi:try&gt;
396
+ action block_end_tag {
397
+ /* offset by 2 to account for the &lt;/ characters */
398
+ parser-&gt;tag_text = parser-&gt;mark+2;
399
+ parser-&gt;tag_text_length = p - (parser-&gt;mark+2);
400
+
401
+ parser-&gt;mark = p;
402
+
403
+ ltrim_pointer( &amp;(parser-&gt;tag_text), p, &amp;(parser-&gt;tag_text_length) );
404
+ rtrim_pointer( &amp;(parser-&gt;tag_text), p, &amp;(parser-&gt;tag_text_length) );
405
+
406
+ esi_parser_flush_output( parser );
407
+ parser-&gt;end_tag_handler( data, parser-&gt;tag_text, parser-&gt;tag_text_length, parser-&gt;user_data );
408
+ esi_parser_flush_output( parser );
409
+
410
+ esi_parser_echobuffer_clear( parser );
411
+ }
412
+
413
+ # process each character in the input stream for output
414
+ action echo {
415
+ //printf( &quot;[%c:%d],&quot;, *p, cs );
416
+ switch( cs ) {
417
+ case 0: /* non matching state */
418
+ if( parser-&gt;prev_state != 12 &amp;&amp; parser-&gt;prev_state != 7 ){ /* states following a possible end state for a tag */
419
+ if( parser-&gt;echobuffer &amp;&amp; parser-&gt;echobuffer_index != -1 ){
420
+ /* send the echo buffer */
421
+ esi_parser_echo_buffer( parser );
422
+ }
423
+ /* send the current character */
424
+ esi_parser_echo_char( parser, *p );
425
+ }
426
+ /* clear the echo buffer */
427
+ esi_parser_echobuffer_clear( parser );
428
+ break;
429
+ default:
430
+ /* append to the echo buffer */
431
+ esi_parser_concat_to_echobuffer( parser, *p );
432
+ }
433
+ /* save the previous state, necessary for end case detection such as /&gt; and &lt;/esi:try&gt; the trailing &gt; character
434
+ is state 12 and 7
435
+ */
436
+ parser-&gt;prev_state = cs;
437
+ }
438
+
439
+ include esi_common_parser &quot;common.rl&quot;;
440
+ </pre>
441
+ <p>
442
+ }%%
443
+ </p>
444
+ <p>
445
+ %%write data;
446
+ </p>
447
+ <p>
448
+ /* dup the string up to len */ char *esi_strndup( const char *str, size_t
449
+ len ) {
450
+ </p>
451
+ <pre>
452
+ char *s = (char*)malloc(sizeof(char)*(len+1));
453
+ memcpy( s, str, len );
454
+ s[len] = '\0';
455
+ return s;
456
+ </pre>
457
+ <p>
458
+ }
459
+ </p>
460
+ <p>
461
+ ESIAttribute *esi_attribute_new( const char *name, size_t name_length,
462
+ const char *value, size_t value_length ) {
463
+ </p>
464
+ <pre>
465
+ ESIAttribute *attr = (ESIAttribute*)malloc(sizeof(ESIAttribute));
466
+ attr-&gt;name = esi_strndup(name, name_length);
467
+ attr-&gt;value = esi_strndup(value, value_length);
468
+ attr-&gt;next = NULL;
469
+ return attr;
470
+ </pre>
471
+ <p>
472
+ }
473
+ </p>
474
+ <p>
475
+ ESIAttribute *esi_attribute_copy( ESIAttribute *attribute ) {
476
+ </p>
477
+ <pre>
478
+ ESIAttribute *head, *nattr;
479
+ if( !attribute ){ return NULL; }
480
+
481
+ // copy the first attribute
482
+ nattr = esi_attribute_new( attribute-&gt;name, strlen( attribute-&gt;name ),
483
+ attribute-&gt;value, strlen( attribute-&gt;value ) );
484
+ // save a pointer for return
485
+ head = nattr;
486
+ // copy next attributes
487
+ attribute = attribute-&gt;next;
488
+ while( attribute ) {
489
+ // set the next attribute
490
+ nattr-&gt;next = esi_attribute_new( attribute-&gt;name, strlen( attribute-&gt;name ),
491
+ attribute-&gt;value, strlen( attribute-&gt;value ) );
492
+ // next attribute
493
+ nattr = nattr-&gt;next;
494
+ attribute = attribute-&gt;next;
495
+ }
496
+ return head;
497
+ </pre>
498
+ <p>
499
+ }
500
+ </p>
501
+ <p>
502
+ void esi_attribute_free( ESIAttribute *attribute ) {
503
+ </p>
504
+ <pre>
505
+ ESIAttribute *ptr;
506
+ while( attribute ){
507
+ free( attribute-&gt;name );
508
+ free( attribute-&gt;value );
509
+ ptr = attribute-&gt;next;
510
+ free( attribute );
511
+ attribute = ptr;
512
+ }
513
+ </pre>
514
+ <p>
515
+ }
516
+ </p>
517
+ <p>
518
+ ESIParser *esi_parser_new() {
519
+ </p>
520
+ <pre>
521
+ ESIParser *parser = (ESIParser*)malloc(sizeof(ESIParser));
522
+ parser-&gt;cs = esi_start;
523
+ parser-&gt;mark = NULL;
524
+ parser-&gt;tag_text = NULL;
525
+ parser-&gt;attr_key = NULL;
526
+ parser-&gt;attr_value = NULL;
527
+ parser-&gt;overflow_data_size = 0;
528
+ parser-&gt;overflow_data = NULL;
529
+
530
+ /* allocate ESI_OUTPUT_BUFFER_SIZE bytes for the echobuffer */
531
+ parser-&gt;echobuffer_allocated = ESI_OUTPUT_BUFFER_SIZE;
532
+ parser-&gt;echobuffer_index = -1;
533
+ parser-&gt;echobuffer = (char*)malloc(sizeof(char)*parser-&gt;echobuffer_allocated);
534
+
535
+ parser-&gt;attributes = NULL;
536
+ parser-&gt;last = NULL;
537
+
538
+ parser-&gt;start_tag_handler = esi_parser_default_start_cb;
539
+ parser-&gt;end_tag_handler = esi_parser_default_end_cb;
540
+ parser-&gt;output_handler = esi_parser_default_output_cp;
541
+
542
+ parser-&gt;output_buffer_size = 0;
543
+ memset( parser-&gt;output_buffer, 0, ESI_OUTPUT_BUFFER_SIZE );
544
+
545
+ return parser;
546
+ </pre>
547
+ <p>
548
+ } void esi_parser_free( ESIParser *parser ) {
549
+ </p>
550
+ <pre>
551
+ if( parser-&gt;overflow_data ){ free( parser-&gt;overflow_data ); }
552
+
553
+ free( parser-&gt;echobuffer );
554
+ esi_attribute_free( parser-&gt;attributes );
555
+
556
+ free( parser );
557
+ </pre>
558
+ <p>
559
+ }
560
+ </p>
561
+ <p>
562
+ void esi_parser_output_handler( ESIParser *parser, output_cb output_handler
563
+ ) {
564
+ </p>
565
+ <pre>
566
+ parser-&gt;output_handler = output_handler;
567
+ </pre>
568
+ <p>
569
+ }
570
+ </p>
571
+ <p>
572
+ int esi_parser_init( ESIParser *parser ) {
573
+ </p>
574
+ <pre>
575
+ int cs;
576
+ %% write init;
577
+ parser-&gt;prev_state = parser-&gt;cs = cs;
578
+ return 0;
579
+ </pre>
580
+ <p>
581
+ }
582
+ </p>
583
+ <p>
584
+ static int compute_offset( const char *mark, const char *data ) {
585
+ </p>
586
+ <pre>
587
+ if( mark ) {
588
+ return mark - data;
589
+ }
590
+ return -1;
591
+ </pre>
592
+ <p>
593
+ }
594
+ </p>
595
+ <p>
596
+ /*
597
+ </p>
598
+ <pre>
599
+ * scans the data buffer for a start sequence /&lt;$/, /&lt;e$/, /&lt;es$/, /&lt;esi$/, /&lt;esi:$/
600
+ * returns index of if start sequence found else returns -1
601
+ */
602
+ </pre>
603
+ <p>
604
+ static int esi_parser_scan_for_start( ESIParser *parser, const char *data,
605
+ size_t length ) {
606
+ </p>
607
+ <pre>
608
+ size_t i, f = -2, s = -2;
609
+ char ch;
610
+
611
+ for( i = 0; i &lt; length; ++i ) {
612
+ ch = data[i];
613
+ switch( ch ) {
614
+ case '&lt;':
615
+ f = s = i;
616
+ break;
617
+ case '/':
618
+ if( s == (i-1) &amp;&amp; f != -2 ) { s = i; }
619
+ break;
620
+ case 'e':
621
+ if( s == (i-1) &amp;&amp; f != -2 ) { s = i; }
622
+ break;
623
+ case 's':
624
+ if( s == (i-1) &amp;&amp; f != -2 ) { s = i; }
625
+ break;
626
+ case 'i':
627
+ if( s == (i-1) &amp;&amp; f != -2 ) { s = i; }
628
+ break;
629
+ case ':':
630
+ if( s == (i-1) &amp;&amp; f != -2 ) { s = i; return f; }
631
+ break;
632
+ default:
633
+ f = s = -2;
634
+ break;
635
+ }
636
+ }
637
+
638
+ // if s and f are still valid at end of input return f
639
+ if( f != -2 &amp;&amp; s != -2 ) {
640
+ return f;
641
+ }
642
+ else {
643
+ return -1;
644
+ }
645
+ </pre>
646
+ <p>
647
+ }
648
+ </p>
649
+ <p>
650
+ /* accept an arbitrary length string buffer
651
+ </p>
652
+ <pre>
653
+ * when this methods exits it determines if an end state was reached
654
+ * if no end state was reached it saves the full input into an internal buffer
655
+ * when invoked next, it reuses that internable buffer copying all pointers into the
656
+ * newly allocated buffer. if it exits in a terminal state, e.g. 0 then it will dump these buffers
657
+ */
658
+ </pre>
659
+ <p>
660
+ int esi_parser_execute( ESIParser *parser, const char *data, size_t length
661
+ ) {
662
+ </p>
663
+ <pre>
664
+ int cs = parser-&gt;cs;
665
+ const char *p = data;
666
+ const char *eof = NULL; // ragel 6.x compat
667
+ const char *pe = data + length;
668
+ int pindex;
669
+
670
+ if( length == 0 ){ return cs; }
671
+
672
+ /* scan data for any '&lt;esi:' start sequences, /&lt;$/, /&lt;e$/, /&lt;es$/, /&lt;esi$/, /&lt;esi:$/ */
673
+ if( cs == esi_start ) {
674
+ pindex = esi_parser_scan_for_start( parser, data, length );
675
+ if( pindex == -1 ) {
676
+ for( pindex = 0; pindex &lt; length; ++pindex ) {
677
+ esi_parser_echo_char( parser, data[pindex] );
678
+ }
679
+ return cs;
680
+ }
681
+ }
682
+
683
+ /* there's an existing overflow buffer data append the new data to the existing data */
684
+ if( parser-&gt;overflow_data &amp;&amp; parser-&gt;overflow_data_size &gt; 0 ) {
685
+
686
+ // recompute mark, tag_text, attr_key, and attr_value since they all exist within overflow_data
687
+ int mark_offset = compute_offset( parser-&gt;mark, parser-&gt;overflow_data );
688
+ int tag_text_offset = compute_offset( parser-&gt;tag_text, parser-&gt;overflow_data );
689
+ int attr_key_offset = compute_offset( parser-&gt;attr_key, parser-&gt;overflow_data );
690
+ int attr_value_offset = compute_offset( parser-&gt;attr_value, parser-&gt;overflow_data );
691
+
692
+ parser-&gt;overflow_data = (char*)realloc( parser-&gt;overflow_data, sizeof(char)*(parser-&gt;overflow_data_size+length) );
693
+ memcpy( parser-&gt;overflow_data+parser-&gt;overflow_data_size, data, length );
694
+
695
+ p = parser-&gt;overflow_data + parser-&gt;overflow_data_size;
696
+
697
+ // in our new memory space mark will now be
698
+ parser-&gt;mark = ( mark_offset &gt;= 0 ) ? parser-&gt;overflow_data + mark_offset : NULL;
699
+ parser-&gt;tag_text = ( tag_text_offset &gt;= 0 ) ? parser-&gt;overflow_data + tag_text_offset : NULL;
700
+ parser-&gt;attr_key = ( attr_key_offset &gt;= 0 ) ? parser-&gt;overflow_data + attr_key_offset : NULL;
701
+ parser-&gt;attr_value = ( attr_value_offset &gt;= 0 ) ? parser-&gt;overflow_data + attr_value_offset : NULL;
702
+
703
+ data = parser-&gt;overflow_data;
704
+ parser-&gt;overflow_data_size = length = length + parser-&gt;overflow_data_size;
705
+ </pre>
706
+ <p>
707
+ // printf( &quot;grow overflow data: %ld\n&quot;,
708
+ parser-&gt;overflow_data_size );
709
+ </p>
710
+ <pre>
711
+ pe = data + length;
712
+
713
+ }
714
+
715
+ if( !parser-&gt;mark ) {
716
+ parser-&gt;mark = p;
717
+ }
718
+ </pre>
719
+ <p>
720
+ // printf( &quot;cs: %d, &quot;, cs );
721
+ </p>
722
+ <pre>
723
+ %% write exec;
724
+
725
+ parser-&gt;cs = cs;
726
+
727
+ if( cs != esi_start &amp;&amp; cs != 0 ) {
728
+
729
+ /* reached the end and we're not at a termination point save the buffer as overflow */
730
+ if( !parser-&gt;overflow_data ){
731
+ // recompute mark, tag_text, attr_key, and attr_value since they all exist within overflow_data
732
+ int mark_offset = compute_offset( parser-&gt;mark, data );
733
+ int tag_text_offset = compute_offset( parser-&gt;tag_text, data );
734
+ int attr_key_offset = compute_offset( parser-&gt;attr_key, data );
735
+ int attr_value_offset = compute_offset( parser-&gt;attr_value, data );
736
+ //debug_string( &quot;mark before move&quot;, parser-&gt;mark, 1 );
737
+
738
+ if( ESI_OUTPUT_BUFFER_SIZE &gt; length ) {
739
+ parser-&gt;echobuffer_allocated = ESI_OUTPUT_BUFFER_SIZE;
740
+ }
741
+ else {
742
+ parser-&gt;echobuffer_allocated = length;
743
+ }
744
+ parser-&gt;overflow_data = (char*)malloc( sizeof( char ) * parser-&gt;echobuffer_allocated );
745
+ memcpy( parser-&gt;overflow_data, data, length );
746
+ parser-&gt;overflow_data_size = length;
747
+ //printf( &quot;allocate overflow data: %ld\n&quot;, parser-&gt;echobuffer_allocated );
748
+
749
+ // in our new memory space mark will now be
750
+ parser-&gt;mark = ( mark_offset &gt;= 0 ) ? parser-&gt;overflow_data + mark_offset : NULL;
751
+ parser-&gt;tag_text = ( tag_text_offset &gt;= 0 ) ? parser-&gt;overflow_data + tag_text_offset : NULL;
752
+ parser-&gt;attr_key = ( attr_key_offset &gt;= 0 ) ? parser-&gt;overflow_data + attr_key_offset : NULL;
753
+ parser-&gt;attr_value = ( attr_value_offset &gt;= 0 ) ? parser-&gt;overflow_data + attr_value_offset : NULL;
754
+ //if( parser-&gt;mark ){ debug_string( &quot;mark after move&quot;, parser-&gt;mark, 1 ); } else { printf( &quot;mark is now empty\n&quot; ); }
755
+ }
756
+
757
+ }else if( parser-&gt;overflow_data ) {
758
+ /* dump the overflow buffer execution ended at a final state */
759
+ free( parser-&gt;overflow_data );
760
+ parser-&gt;overflow_data = NULL;
761
+ parser-&gt;overflow_data_size = 0;
762
+ }
763
+
764
+ return cs;
765
+ </pre>
766
+ <p>
767
+ } int esi_parser_finish( ESIParser *parser ) {
768
+ </p>
769
+ <pre>
770
+ esi_parser_flush_output( parser );
771
+ return 0;
772
+ </pre>
773
+ <p>
774
+ }
775
+ </p>
776
+ <p>
777
+ void esi_parser_start_tag_handler( ESIParser *parser, start_tag_cb callback
778
+ ) {
779
+ </p>
780
+ <pre>
781
+ parser-&gt;start_tag_handler = callback;
782
+ </pre>
783
+ <p>
784
+ }
785
+ </p>
786
+ <p>
787
+ void esi_parser_end_tag_handler( ESIParser *parser, end_tag_cb callback ) {
788
+ </p>
789
+ <pre>
790
+ parser-&gt;end_tag_handler = callback;
791
+ </pre>
792
+ <p>
793
+ }
794
+ </p>
795
+
796
+ </div>
797
+
798
+
799
+ </div>
800
+
801
+
802
+ </div>
803
+
804
+
805
+ <!-- if includes -->
806
+
807
+ <div id="section">
808
+
809
+
810
+
811
+
812
+
813
+
814
+
815
+
816
+ <!-- if method_list -->
817
+
818
+
819
+ </div>
820
+
821
+
822
+ <div id="validator-badges">
823
+ <p><small><a href="http://validator.w3.org/check/referer">[Validate]</a></small></p>
824
+ </div>
825
+
826
+ </body>
827
+ </html>