mongrel_esi 0.5.1 → 0.5.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (179) hide show
  1. data/README +10 -9
  2. data/doc/rdoc/classes/ESI/Cache.html +10 -10
  3. data/doc/rdoc/classes/ESI/Cache.src/{M000085.html → M000087.html} +0 -0
  4. data/doc/rdoc/classes/ESI/Cache.src/{M000086.html → M000088.html} +0 -0
  5. data/doc/rdoc/classes/ESI/Config.html +43 -62
  6. data/doc/rdoc/classes/ESI/Config.src/M000049.html +18 -0
  7. data/doc/rdoc/classes/ESI/Config.src/{M000059.html → M000050.html} +5 -5
  8. data/doc/rdoc/classes/ESI/Config.src/M000051.html +35 -0
  9. data/doc/rdoc/classes/ESI/Config.src/M000052.html +27 -5
  10. data/doc/rdoc/classes/ESI/Config.src/M000053.html +10 -5
  11. data/doc/rdoc/classes/ESI/Config.src/M000054.html +5 -22
  12. data/doc/rdoc/classes/ESI/Config.src/M000055.html +7 -25
  13. data/doc/rdoc/classes/ESI/Config.src/M000056.html +11 -10
  14. data/doc/rdoc/classes/ESI/Config/CacheConfig.html +25 -25
  15. data/doc/rdoc/classes/ESI/Config/CacheConfig.src/{M000068.html → M000060.html} +6 -5
  16. data/doc/rdoc/classes/ESI/Config/CacheConfig.src/{M000065.html → M000061.html} +5 -5
  17. data/doc/rdoc/classes/ESI/Config/CacheConfig.src/{M000066.html → M000062.html} +4 -4
  18. data/doc/rdoc/classes/ESI/Config/CacheConfig.src/{M000067.html → M000063.html} +4 -4
  19. data/doc/rdoc/classes/ESI/Config/CacheConfig.src/M000064.html +5 -6
  20. data/doc/rdoc/classes/ESI/Config/ConfigRouter.html +15 -15
  21. data/doc/rdoc/classes/ESI/Config/ConfigRouter.src/{M000061.html → M000057.html} +5 -5
  22. data/doc/rdoc/classes/ESI/Config/ConfigRouter.src/{M000062.html → M000058.html} +7 -7
  23. data/doc/rdoc/classes/ESI/Config/ConfigRouter.src/{M000063.html → M000059.html} +7 -7
  24. data/doc/rdoc/classes/ESI/Dispatcher.html +17 -15
  25. data/doc/rdoc/classes/ESI/Dispatcher.src/{M000087.html → M000092.html} +4 -7
  26. data/doc/rdoc/classes/ESI/Dispatcher.src/M000093.html +27 -0
  27. data/doc/rdoc/classes/ESI/Fragment.html +15 -15
  28. data/doc/rdoc/classes/ESI/Fragment.src/{M000100.html → M000111.html} +0 -0
  29. data/doc/rdoc/classes/ESI/Fragment.src/{M000101.html → M000112.html} +0 -0
  30. data/doc/rdoc/classes/ESI/Fragment.src/{M000102.html → M000113.html} +0 -0
  31. data/doc/rdoc/classes/ESI/MemcachedCache.html +46 -46
  32. data/doc/rdoc/classes/ESI/MemcachedCache.src/M000037.html +24 -0
  33. data/doc/rdoc/classes/ESI/MemcachedCache.src/M000038.html +22 -0
  34. data/doc/rdoc/classes/ESI/MemcachedCache.src/M000039.html +19 -0
  35. data/doc/rdoc/classes/ESI/MemcachedCache.src/M000040.html +10 -11
  36. data/doc/rdoc/classes/ESI/MemcachedCache.src/M000041.html +5 -9
  37. data/doc/rdoc/classes/ESI/MemcachedCache.src/M000042.html +6 -6
  38. data/doc/rdoc/classes/ESI/MemcachedCache.src/M000043.html +5 -10
  39. data/doc/rdoc/classes/ESI/MemcachedCache.src/M000044.html +5 -5
  40. data/doc/rdoc/classes/ESI/MemcachedCache.src/M000045.html +4 -6
  41. data/doc/rdoc/classes/ESI/OutputAdapter.html +204 -0
  42. data/doc/rdoc/classes/ESI/OutputAdapter.src/M000094.html +37 -0
  43. data/doc/rdoc/classes/ESI/OutputAdapter.src/M000095.html +18 -0
  44. data/doc/rdoc/classes/ESI/OutputAdapter.src/M000096.html +18 -0
  45. data/doc/rdoc/classes/ESI/OutputAdapter.src/M000097.html +18 -0
  46. data/doc/rdoc/classes/ESI/Parser.html +15 -15
  47. data/doc/rdoc/classes/ESI/Parser.src/{M000049.html → M000065.html} +0 -0
  48. data/doc/rdoc/classes/ESI/Parser.src/{M000050.html → M000066.html} +0 -0
  49. data/doc/rdoc/classes/ESI/Parser.src/{M000051.html → M000067.html} +0 -0
  50. data/doc/rdoc/classes/ESI/Processor.html +15 -15
  51. data/doc/rdoc/classes/ESI/Processor.src/{M000037.html → M000046.html} +0 -0
  52. data/doc/rdoc/classes/ESI/Processor.src/{M000038.html → M000047.html} +1 -1
  53. data/doc/rdoc/classes/ESI/Processor.src/{M000039.html → M000048.html} +0 -0
  54. data/doc/rdoc/classes/ESI/Proxy.html +48 -48
  55. data/doc/rdoc/classes/ESI/Proxy.src/M000071.html +7 -40
  56. data/doc/rdoc/classes/ESI/Proxy.src/M000072.html +50 -12
  57. data/doc/rdoc/classes/ESI/Proxy.src/M000073.html +49 -6
  58. data/doc/rdoc/classes/ESI/Proxy.src/M000074.html +11 -14
  59. data/doc/rdoc/classes/ESI/Proxy.src/M000075.html +6 -5
  60. data/doc/rdoc/classes/ESI/Proxy.src/M000076.html +9 -15
  61. data/doc/rdoc/classes/ESI/Proxy.src/M000077.html +5 -16
  62. data/doc/rdoc/classes/ESI/Proxy.src/M000078.html +28 -0
  63. data/doc/rdoc/classes/ESI/Proxy.src/M000079.html +29 -0
  64. data/doc/rdoc/classes/ESI/RackAdapter.html +214 -0
  65. data/doc/rdoc/classes/ESI/RackAdapter.src/M000068.html +18 -0
  66. data/doc/rdoc/classes/ESI/RackAdapter.src/M000069.html +34 -0
  67. data/doc/rdoc/classes/ESI/{MemcachedCache.src/M000048.html → RackAdapter.src/M000070.html} +4 -4
  68. data/doc/rdoc/classes/ESI/RackConfig.html +173 -0
  69. data/doc/rdoc/classes/ESI/RackConfig.src/M000089.html +28 -0
  70. data/doc/rdoc/classes/ESI/RackConfig.src/M000090.html +18 -0
  71. data/doc/rdoc/classes/ESI/RackConfig.src/M000091.html +20 -0
  72. data/doc/rdoc/classes/ESI/Request.html +158 -0
  73. data/doc/rdoc/classes/ESI/{MemcachedCache.src/M000046.html → Request.src/M000098.html} +5 -5
  74. data/doc/rdoc/classes/ESI/Request.src/M000099.html +18 -0
  75. data/doc/rdoc/classes/ESI/Response.html +36 -36
  76. data/doc/rdoc/classes/ESI/Response.src/M000080.html +10 -8
  77. data/doc/rdoc/classes/ESI/Response.src/M000081.html +5 -7
  78. data/doc/rdoc/classes/ESI/Response.src/M000082.html +8 -12
  79. data/doc/rdoc/classes/ESI/Response.src/M000083.html +7 -5
  80. data/doc/rdoc/classes/ESI/Response.src/M000084.html +12 -20
  81. data/doc/rdoc/classes/ESI/Response.src/{M000079.html → M000085.html} +5 -5
  82. data/doc/rdoc/classes/ESI/Response.src/M000086.html +33 -0
  83. data/doc/rdoc/classes/ESI/Router.html +10 -10
  84. data/doc/rdoc/classes/ESI/Router.src/{M000098.html → M000109.html} +0 -0
  85. data/doc/rdoc/classes/ESI/Router.src/{M000099.html → M000110.html} +0 -0
  86. data/doc/rdoc/classes/ESI/RubyCache.html +45 -45
  87. data/doc/rdoc/classes/ESI/RubyCache.src/{M000089.html → M000100.html} +6 -6
  88. data/doc/rdoc/classes/ESI/RubyCache.src/{M000090.html → M000101.html} +6 -6
  89. data/doc/rdoc/classes/ESI/RubyCache.src/{M000091.html → M000102.html} +6 -6
  90. data/doc/rdoc/classes/ESI/RubyCache.src/{M000092.html → M000103.html} +8 -8
  91. data/doc/rdoc/classes/ESI/RubyCache.src/{M000093.html → M000104.html} +4 -4
  92. data/doc/rdoc/classes/ESI/RubyCache.src/{M000094.html → M000105.html} +8 -8
  93. data/doc/rdoc/classes/ESI/RubyCache.src/{M000095.html → M000106.html} +4 -4
  94. data/doc/rdoc/classes/ESI/RubyCache.src/{M000096.html → M000107.html} +4 -4
  95. data/doc/rdoc/classes/ESI/RubyCache.src/{M000097.html → M000108.html} +4 -4
  96. data/doc/rdoc/classes/ESI/Tag.html +8 -8
  97. data/doc/rdoc/created.rid +1 -1
  98. data/doc/rdoc/files/COPYING.html +1 -1
  99. data/doc/rdoc/files/LICENSE.html +1 -1
  100. data/doc/rdoc/files/README.html +12 -10
  101. data/doc/rdoc/files/ext/esi/common_rl.html +1 -1
  102. data/doc/rdoc/files/ext/esi/esi_parser_c.html +1 -1
  103. data/doc/rdoc/files/ext/esi/parser_c.html +1 -1
  104. data/doc/rdoc/files/ext/esi/parser_h.html +1 -1
  105. data/doc/rdoc/files/ext/esi/parser_rl.html +122 -82
  106. data/doc/rdoc/files/ext/esi/test/test_c.html +1 -1
  107. data/doc/rdoc/files/lib/esi/cache_rb.html +2 -1
  108. data/doc/rdoc/files/lib/esi/config_rb.html +2 -1
  109. data/doc/rdoc/files/lib/esi/dispatcher_rb.html +3 -1
  110. data/doc/rdoc/files/lib/esi/invalidator_rb.html +1 -1
  111. data/doc/rdoc/files/lib/esi/logger_rb.html +1 -1
  112. data/doc/rdoc/files/lib/esi/parser_rb.html +1 -1
  113. data/doc/rdoc/files/lib/esi/processor_rb.html +1 -1
  114. data/doc/rdoc/files/lib/esi/proxy_rb.html +2 -2
  115. data/doc/rdoc/files/{ext/esi/test/parser_c.html → lib/esi/rack_adapter_rb.html} +21 -5
  116. data/doc/rdoc/files/lib/esi/response_rb.html +1 -1
  117. data/doc/rdoc/files/lib/esi/router_rb.html +1 -1
  118. data/doc/rdoc/files/lib/esi/tag/attempt_rb.html +1 -1
  119. data/doc/rdoc/files/lib/esi/tag/base_rb.html +1 -1
  120. data/doc/rdoc/files/lib/esi/tag/container_rb.html +1 -1
  121. data/doc/rdoc/files/lib/esi/tag/except_rb.html +1 -1
  122. data/doc/rdoc/files/lib/esi/tag/include_rb.html +1 -1
  123. data/doc/rdoc/files/lib/esi/tag/invalidate_rb.html +1 -1
  124. data/doc/rdoc/files/lib/esi/tag/try_rb.html +1 -1
  125. data/doc/rdoc/files/lib/esi/version_rb.html +1 -1
  126. data/doc/rdoc/files/lib/multi_dirhandler_rb.html +1 -1
  127. data/doc/rdoc/fr_class_index.html +4 -0
  128. data/doc/rdoc/fr_file_index.html +1 -5
  129. data/doc/rdoc/fr_method_index.html +87 -76
  130. data/ext/esi/esi_parser.c +2 -2
  131. data/ext/esi/parser.c +133 -107
  132. data/ext/esi/parser.h +9 -4
  133. data/ext/esi/parser.rl +99 -73
  134. data/ext/esi/test/test.c +11 -6
  135. data/lib/esi/cache.rb +7 -3
  136. data/lib/esi/config.rb +4 -8
  137. data/lib/esi/dispatcher.rb +14 -5
  138. data/lib/esi/processor.rb +1 -1
  139. data/lib/esi/proxy.rb +58 -48
  140. data/lib/esi/rack_adapter.rb +97 -0
  141. data/lib/esi/response.rb +30 -1
  142. data/lib/esi/version.rb +1 -1
  143. data/test/bench-plot.rb +31 -0
  144. data/test/benchmarks/csv-perf-serial0.4 +101 -0
  145. data/test/benchmarks/csv-perf-trunk +101 -0
  146. data/test/benchmarks/perf-serial0.4-n1000-c1.csv +101 -0
  147. data/test/benchmarks/perf-serial0.4-n1000-c2.csv +101 -0
  148. data/test/benchmarks/perf-serial0.4-n1000-c3.csv +101 -0
  149. data/test/benchmarks/perf-serial0.4-n1000-c4.csv +101 -0
  150. data/test/benchmarks/perf-serial0.4-n1000-c5.csv +101 -0
  151. data/test/benchmarks/perf-serial0.4-n1000-c6.csv +101 -0
  152. data/test/benchmarks/perf-serial0.4-n1000-c7.csv +101 -0
  153. data/test/benchmarks/perf-trunk-n1000-c1.csv +101 -0
  154. data/test/benchmarks/perf-trunk-n1000-c2.csv +101 -0
  155. data/test/benchmarks/perf-trunk-n1000-c3.csv +101 -0
  156. data/test/benchmarks/perf-trunk-n1000-c4.csv +101 -0
  157. data/test/benchmarks/perf-trunk-n1000-c5.csv +101 -0
  158. data/test/benchmarks/perf-trunk-n1000-c6.csv +101 -0
  159. data/test/benchmarks/perf-trunk-n1000-c7.csv +101 -0
  160. data/test/load_test.rb +5 -2
  161. data/test/load_test_ab.rb +9 -4
  162. metadata +261 -227
  163. data/doc/rdoc/classes/ESI/Config.src/M000057.html +0 -18
  164. data/doc/rdoc/classes/ESI/Config.src/M000058.html +0 -20
  165. data/doc/rdoc/classes/ESI/Config.src/M000060.html +0 -24
  166. data/doc/rdoc/classes/ESI/Dispatcher.src/M000088.html +0 -18
  167. data/doc/rdoc/classes/ESI/MemcachedCache.src/M000047.html +0 -18
  168. data/doc/rdoc/classes/ESI/Proxy.src/M000069.html +0 -20
  169. data/doc/rdoc/classes/ESI/Proxy.src/M000070.html +0 -55
  170. data/doc/rdoc/classes/ESI/Response.src/M000078.html +0 -23
  171. data/doc/rdoc/files/ext/esi/test/common_rl.html +0 -160
  172. data/doc/rdoc/files/ext/esi/test/parser_h.html +0 -101
  173. data/doc/rdoc/files/ext/esi/test/parser_rl.html +0 -827
  174. data/doc/rdoc/files/ext/esi/test/sp_c.html +0 -101
  175. data/ext/esi/test/common.rl +0 -46
  176. data/ext/esi/test/parser.c +0 -1875
  177. data/ext/esi/test/parser.h +0 -120
  178. data/ext/esi/test/parser.rl +0 -585
  179. data/ext/esi/test/sp.c +0 -125
@@ -1,827 +0,0 @@
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/test/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>