mongrel_esi 0.4.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 (73) hide show
  1. data/COPYING +53 -0
  2. data/LICENSE +471 -0
  3. data/README +186 -0
  4. data/Rakefile +141 -0
  5. data/bin/mongrel_esi +271 -0
  6. data/ext/esi/common.rl +41 -0
  7. data/ext/esi/esi_parser.c +387 -0
  8. data/ext/esi/extconf.rb +6 -0
  9. data/ext/esi/machine.rb +499 -0
  10. data/ext/esi/parser.c +1675 -0
  11. data/ext/esi/parser.h +113 -0
  12. data/ext/esi/parser.rb +49 -0
  13. data/ext/esi/parser.rl +398 -0
  14. data/ext/esi/ruby_esi.rl +135 -0
  15. data/ext/esi/run-test.rb +3 -0
  16. data/ext/esi/test/common.rl +41 -0
  17. data/ext/esi/test/parser.c +1676 -0
  18. data/ext/esi/test/parser.h +113 -0
  19. data/ext/esi/test/parser.rl +398 -0
  20. data/ext/esi/test/test.c +373 -0
  21. data/ext/esi/test1.rb +56 -0
  22. data/ext/esi/test2.rb +45 -0
  23. data/lib/esi/cache.rb +207 -0
  24. data/lib/esi/config.rb +154 -0
  25. data/lib/esi/dispatcher.rb +27 -0
  26. data/lib/esi/handler.rb +236 -0
  27. data/lib/esi/invalidator.rb +40 -0
  28. data/lib/esi/logger.rb +46 -0
  29. data/lib/esi/router.rb +84 -0
  30. data/lib/esi/tag/attempt.rb +6 -0
  31. data/lib/esi/tag/base.rb +85 -0
  32. data/lib/esi/tag/except.rb +24 -0
  33. data/lib/esi/tag/include.rb +190 -0
  34. data/lib/esi/tag/invalidate.rb +54 -0
  35. data/lib/esi/tag/try.rb +40 -0
  36. data/lib/multi_dirhandler.rb +70 -0
  37. data/setup.rb +1585 -0
  38. data/test/integration/basic_test.rb +39 -0
  39. data/test/integration/cache_test.rb +37 -0
  40. data/test/integration/docs/content/500.html +16 -0
  41. data/test/integration/docs/content/500_with_failover.html +16 -0
  42. data/test/integration/docs/content/500_with_failover_to_alt.html +8 -0
  43. data/test/integration/docs/content/ajax_test_page.html +15 -0
  44. data/test/integration/docs/content/cookie_variable.html +3 -0
  45. data/test/integration/docs/content/foo.html +15 -0
  46. data/test/integration/docs/content/include_in_include.html +15 -0
  47. data/test/integration/docs/content/malformed_transforms.html +16 -0
  48. data/test/integration/docs/content/malformed_transforms.html-correct +11 -0
  49. data/test/integration/docs/content/static-failover.html +20 -0
  50. data/test/integration/docs/content/test2.html +1 -0
  51. data/test/integration/docs/content/test3.html +17 -0
  52. data/test/integration/docs/esi_invalidate.html +6 -0
  53. data/test/integration/docs/esi_mixed_content.html +15 -0
  54. data/test/integration/docs/esi_test_content.html +27 -0
  55. data/test/integration/docs/index.html +688 -0
  56. data/test/integration/docs/test1.html +1 -0
  57. data/test/integration/docs/test3.html +9 -0
  58. data/test/integration/docs/test_failover.html +1 -0
  59. data/test/integration/handler_test.rb +270 -0
  60. data/test/integration/help.rb +234 -0
  61. data/test/net/get_test.rb +197 -0
  62. data/test/net/net_helper.rb +16 -0
  63. data/test/net/server_test.rb +249 -0
  64. data/test/unit/base_tag_test.rb +44 -0
  65. data/test/unit/esi-sample.html +56 -0
  66. data/test/unit/help.rb +77 -0
  67. data/test/unit/include_request_test.rb +69 -0
  68. data/test/unit/include_tag_test.rb +14 -0
  69. data/test/unit/parser_test.rb +478 -0
  70. data/test/unit/router_test.rb +34 -0
  71. data/test/unit/sample.html +21 -0
  72. data/tools/rakehelp.rb +119 -0
  73. metadata +182 -0
data/ext/esi/common.rl ADDED
@@ -0,0 +1,41 @@
1
+ %%{
2
+ machine esi_common_parser;
3
+
4
+ # inline tags e.g. <esi:comment text='some useless text'/> or <esi:include src='/foo/'/>, etc...
5
+ esi_inline_tag = (
6
+ start: (
7
+ '<esi:' [a-z]+ space @see_start_tag -> start_attribute |
8
+ '<esi:' [a-z]+ space* '/>' >see_start_tag %see_end_tag -> final
9
+ ),
10
+ start_attribute: (
11
+ space* [a-zA-Z_\-]+ [a-zA-Z_\-0-9]* '=' @see_attribute_key -> end_attribute |
12
+ space* '/>' @see_end_tag -> final
13
+ ),
14
+ end_attribute: (
15
+ space* ['"][!{}#-&(-/:-@a-zA-Z0-9+_\-]+['"] @see_attribute_value -> start_attribute
16
+ )
17
+ ) >begin %finish;
18
+
19
+ # block tags e.g. <esi:try> <esi:attempt>, etc..
20
+ esi_block_tag = (
21
+ start: (
22
+ '<esi:' [a-z]+ '>' @block_start_tag -> start |
23
+ '<esi:' [a-z]+ space @see_start_tag -> start_attribute |
24
+ '</esi:' [a-z]+ '>' @block_end_tag
25
+ ),
26
+ start_attribute: (
27
+ space* [a-zA-Z_\-]+ [a-zA-Z_\-0-9]* '=' @see_attribute_key -> end_attribute | '>' @see_block_start_with_attributes -> final
28
+ ),
29
+ end_attribute: (
30
+ space* ['"][!{}#-&(-/:-@a-zA-Z0-9+_\-]+['"] @see_attribute_value -> start_attribute
31
+ )
32
+ ) >begin %finish;
33
+
34
+ echo_state = (
35
+ start: (
36
+ /./ @echo
37
+ )
38
+ );
39
+
40
+ main := ((/.*/)? @echo (esi_inline_tag|esi_block_tag) )*;
41
+ }%%
@@ -0,0 +1,387 @@
1
+ /**
2
+ * Copyright (c) 2008 Todd A. Fisher
3
+ * see LICENSE
4
+ */
5
+ #include "ruby.h"
6
+ #include "parser.h"
7
+ #define DEBUG
8
+ #ifdef DEBUG
9
+ #define TRACE() fprintf(stderr, "> %s:%d:%s\n", __FILE__, __LINE__, __FUNCTION__)
10
+ #else
11
+ #define TRACE()
12
+ #endif
13
+
14
+ /* ruby 1.9 compat */
15
+ #ifndef RSTRING_PTR
16
+ #define RSTRING_PTR(str) RSTRING(str)->ptr
17
+ #endif
18
+
19
+ #ifndef RSTRING_LEN
20
+ #define RSTRING_LEN(str) RSTRING(str)->len
21
+ #endif
22
+
23
+ #define OUTPUT_BUFFER_SIZE 1024
24
+
25
+ static VALUE rb_ESI;
26
+ static VALUE rb_ESIParser;
27
+
28
+ // TODO: we can use rb_iv_set instead and just pass the whole parser as the user_data to each call back
29
+ typedef struct _ParserUserData{
30
+ VALUE output_block;
31
+ VALUE start_tag_block;
32
+ VALUE end_tag_block;
33
+ VALUE depth;
34
+ VALUE esi_tag;
35
+ char buffer[OUTPUT_BUFFER_SIZE]; /* buffer bytes before sending them to ruby */
36
+ size_t buffered; /* amount buffered */
37
+ }ParserUserData;
38
+
39
+ static
40
+ VALUE ESIParser_set_output_cb( VALUE self )
41
+ {
42
+ ESIParser *parser;
43
+ ParserUserData *user_data;
44
+
45
+ if( !rb_block_given_p() ){
46
+ rb_raise(rb_eArgError, "Block expected. Call this method with a closure. { ... }");
47
+ }
48
+
49
+ Data_Get_Struct( self, ESIParser, parser );
50
+
51
+ user_data = (ParserUserData*)parser->user_data;
52
+
53
+ user_data->output_block = rb_block_proc();
54
+
55
+ return Qnil;
56
+ }
57
+
58
+ static
59
+ VALUE ESIParser_set_start_tag_cb( VALUE self )
60
+ {
61
+ ESIParser *parser;
62
+ ParserUserData *user_data;
63
+
64
+ if( !rb_block_given_p() ){
65
+ rb_raise(rb_eArgError, "Block expected. Call this method with a closure. { ... }");
66
+ }
67
+
68
+ Data_Get_Struct( self, ESIParser, parser );
69
+
70
+ user_data = (ParserUserData*)parser->user_data;
71
+
72
+ user_data->start_tag_block = rb_block_proc();
73
+
74
+ return Qnil;
75
+ }
76
+
77
+ static
78
+ VALUE ESIParser_set_end_tag_cb( VALUE self )
79
+ {
80
+ ESIParser *parser;
81
+ ParserUserData *user_data;
82
+
83
+ if( !rb_block_given_p() ){
84
+ rb_raise(rb_eArgError, "Block expected. Call this method with a closure. { ... }");
85
+ }
86
+
87
+ Data_Get_Struct( self, ESIParser, parser );
88
+
89
+ user_data = (ParserUserData*)parser->user_data;
90
+
91
+ user_data->end_tag_block = rb_block_proc();
92
+
93
+ return Qnil;
94
+ }
95
+
96
+ static
97
+ void ESIParser_free( ESIParser *parser )
98
+ {
99
+ ParserUserData *user_data = (ParserUserData*)parser->user_data;
100
+
101
+ free( user_data );
102
+ parser->user_data = NULL;
103
+
104
+ esi_parser_free( parser );
105
+ }
106
+ static
107
+ void ESIParser_mark( ESIParser *parser )
108
+ {
109
+ ParserUserData *user_data = (ParserUserData*)parser->user_data;
110
+ if( user_data ){
111
+
112
+ if( !NIL_P( user_data->output_block ) )
113
+ rb_gc_mark( user_data->output_block );
114
+ if( !NIL_P( user_data->start_tag_block ) )
115
+ rb_gc_mark( user_data->start_tag_block );
116
+ if( !NIL_P( user_data->end_tag_block ) )
117
+ rb_gc_mark( user_data->end_tag_block );
118
+ if( !NIL_P( user_data->depth ) )
119
+ rb_gc_mark( user_data->depth );
120
+ if( !NIL_P( user_data->esi_tag ) )
121
+ rb_gc_mark( user_data->esi_tag );
122
+
123
+ }
124
+ }
125
+
126
+ /* default callbacks */
127
+ static void
128
+ esi_parser_default_start_cb( const void *data,
129
+ const char *name_start,
130
+ size_t name_length,
131
+ ESIAttribute *attr,
132
+ void *user_data )
133
+ {
134
+ ParserUserData *ud = (ParserUserData*)user_data;
135
+ if( ud->start_tag_block && !NIL_P(ud->start_tag_block) && rb_respond_to( ud->start_tag_block, rb_intern("call") ) ){
136
+ VALUE attr_hash = rb_hash_new();
137
+ VALUE tag_text = rb_str_new( name_start, name_length );
138
+ while( attr ){
139
+ VALUE name = rb_str_new( attr->name, strlen( attr->name ) );
140
+ VALUE value = rb_str_new( attr->value, strlen( attr->value ) );
141
+ rb_hash_aset( attr_hash, name, value );
142
+ attr = attr->next;
143
+ }
144
+ rb_funcall( ud->start_tag_block, rb_intern("call"), 2, tag_text, attr_hash );
145
+ }
146
+ }
147
+
148
+ static void
149
+ esi_parser_default_end_cb( const void *data,
150
+ const char *name_start,
151
+ size_t name_length,
152
+ void *user_data )
153
+ {
154
+ ParserUserData *ud = (ParserUserData*)user_data;
155
+ if( ud->end_tag_block && !NIL_P(ud->end_tag_block) && rb_respond_to( ud->end_tag_block, rb_intern("call") ) ){
156
+ VALUE tag_text = rb_str_new( name_start, name_length );
157
+ rb_funcall( ud->end_tag_block, rb_intern("call"), 1, tag_text );
158
+ }
159
+ }
160
+
161
+ static void
162
+ send_output( VALUE output, VALUE esi_tag_context, VALUE rbstr )
163
+ {
164
+ if( !NIL_P( esi_tag_context ) && rb_respond_to( esi_tag_context, rb_intern("buffer") ) ){
165
+ /* a tag is currently open so send the output to it so that i can decide if the output is ready or not */
166
+ rb_funcall( esi_tag_context, rb_intern("buffer"), 2, output, rbstr );
167
+ }
168
+ else{
169
+ /* if no tag is in the current context send the output directly to the device */
170
+ if( rb_respond_to( output, rb_intern("call") ) ){
171
+ rb_funcall( output, rb_intern("call"), 1, rbstr );
172
+ }
173
+ else{
174
+ rb_funcall( output, rb_intern("<<"), 1, rbstr );
175
+ }
176
+ }
177
+ }
178
+
179
+ static void
180
+ esi_parser_default_output_cp( const void *data,
181
+ size_t length,
182
+ void *user_data )
183
+ {
184
+ VALUE rbstr;
185
+ ParserUserData *ud = (ParserUserData*)user_data;
186
+
187
+ if( ud->output_block && !NIL_P(ud->output_block) ){
188
+ rbstr = rb_str_new( data, length );
189
+ send_output( ud->output_block, ud->esi_tag, rbstr );
190
+ /* buffer the output to the ruby script */
191
+ /*if( ud->buffered+length < OUTPUT_BUFFER_SIZE ){
192
+ memcpy( ud->buffer + ud->buffered, data, length );
193
+ ud->buffered += length;
194
+ }
195
+ else{
196
+ if( ud->buffered > 0 ){
197
+ rbstr = rb_str_new( ud->buffer, ud->buffered );
198
+ send_output( ud->output_block, ud->esi_tag, rbstr );
199
+ ud->buffered = 0;
200
+ }
201
+ rbstr = rb_str_new( data, length );
202
+ send_output( ud->output_block, ud->esi_tag, rbstr );
203
+ }*/
204
+ //rb_funcall( ud->output_block, rb_intern("call"), 1, rb_str_new( data, length ) );
205
+ }
206
+ }
207
+
208
+ static
209
+ VALUE ESIParser_process( VALUE self, VALUE data )
210
+ {
211
+ ESIParser *parser;
212
+
213
+ Data_Get_Struct( self, ESIParser, parser );
214
+
215
+ esi_parser_execute( parser, RSTRING_PTR( data ), RSTRING_LEN( data ) );
216
+
217
+ return Qnil;
218
+ }
219
+
220
+ static
221
+ VALUE ESIParser_finish( VALUE self )
222
+ {
223
+ ESIParser *parser;
224
+ ParserUserData *user_data;
225
+
226
+ Data_Get_Struct( self, ESIParser, parser );
227
+ user_data = (ParserUserData*)parser->user_data;
228
+
229
+ esi_parser_finish( parser );
230
+ /*
231
+ if( user_data->buffered > 0 ){
232
+ VALUE rbstr = rb_str_new( user_data->buffer, user_data->buffered );
233
+ send_output( user_data->output_block, user_data->esi_tag, rbstr );
234
+ memset( user_data->buffer, 0, OUTPUT_BUFFER_SIZE );
235
+ user_data->buffered = 0;
236
+ }
237
+ */
238
+
239
+ return Qnil;
240
+ }
241
+
242
+ static
243
+ VALUE ESIParser_alloc(VALUE klass)
244
+ {
245
+ VALUE object;
246
+ ESIParser *parser = esi_parser_new();
247
+
248
+ ParserUserData *user_data = (ParserUserData*)malloc(sizeof(ParserUserData));
249
+
250
+ user_data->output_block = Qnil;
251
+ user_data->start_tag_block = Qnil;
252
+ user_data->end_tag_block = Qnil;
253
+ user_data->depth = rb_int_new(0);
254
+ user_data->esi_tag = Qnil;
255
+ memset( user_data->buffer, 0, OUTPUT_BUFFER_SIZE );
256
+ user_data->buffered = 0;
257
+
258
+ parser->user_data = user_data;
259
+
260
+ esi_parser_init( parser );
261
+
262
+ esi_parser_start_tag_handler( parser, esi_parser_default_start_cb );
263
+
264
+ esi_parser_end_tag_handler( parser, esi_parser_default_end_cb );
265
+
266
+ esi_parser_output_handler( parser, esi_parser_default_output_cp );
267
+
268
+ object = Data_Wrap_Struct( klass, ESIParser_mark, ESIParser_free, parser );
269
+
270
+ return object;
271
+ }
272
+
273
+ static
274
+ VALUE ESIParser_set_esi_tag( VALUE self, VALUE esi_tag )
275
+ {
276
+ ESIParser *parser;
277
+ ParserUserData *user_data;
278
+
279
+ Data_Get_Struct( self, ESIParser, parser );
280
+
281
+ user_data = (ParserUserData*)parser->user_data;
282
+
283
+ user_data->esi_tag = esi_tag;
284
+
285
+ return esi_tag;
286
+ }
287
+
288
+ static
289
+ VALUE ESIParser_get_esi_tag( VALUE self )
290
+ {
291
+ ESIParser *parser;
292
+ ParserUserData *user_data;
293
+
294
+ Data_Get_Struct( self, ESIParser, parser );
295
+
296
+ user_data = (ParserUserData*)parser->user_data;
297
+
298
+ return user_data->esi_tag;
299
+ }
300
+
301
+ static
302
+ VALUE ESIParser_set_depth( VALUE self, VALUE depth )
303
+ {
304
+ ESIParser *parser;
305
+ ParserUserData *user_data;
306
+
307
+ Data_Get_Struct( self, ESIParser, parser );
308
+
309
+ user_data = (ParserUserData*)parser->user_data;
310
+
311
+ user_data->depth = depth;
312
+
313
+ return depth;
314
+ }
315
+
316
+ static
317
+ VALUE ESIParser_get_depth( VALUE self )
318
+ {
319
+ ESIParser *parser;
320
+ ParserUserData *user_data;
321
+
322
+ Data_Get_Struct( self, ESIParser, parser );
323
+
324
+ user_data = (ParserUserData*)parser->user_data;
325
+
326
+ return user_data->depth;
327
+ }
328
+
329
+ static
330
+ VALUE ESIParser_set_output( VALUE self, VALUE output )
331
+ {
332
+ ESIParser *parser;
333
+ ParserUserData *user_data;
334
+
335
+ Data_Get_Struct( self, ESIParser, parser );
336
+
337
+ user_data = (ParserUserData*)parser->user_data;
338
+
339
+ user_data->output_block = output;
340
+
341
+ return output;
342
+ }
343
+
344
+ static
345
+ VALUE ESIParser_get_output( VALUE self )
346
+ {
347
+ ESIParser *parser;
348
+ ParserUserData *user_data;
349
+
350
+ Data_Get_Struct( self, ESIParser, parser );
351
+
352
+ user_data = (ParserUserData*)parser->user_data;
353
+
354
+ return user_data->output_block;
355
+ }
356
+ static
357
+ VALUE ESIParser_send_output( VALUE self, VALUE output )
358
+ {
359
+ ESIParser *parser;
360
+
361
+ Data_Get_Struct( self, ESIParser, parser );
362
+
363
+ esi_parser_default_output_cp( RSTRING_PTR(output), RSTRING_LEN(output), parser->user_data );
364
+
365
+ return Qnil;
366
+ }
367
+ void Init_esi()
368
+ {
369
+ rb_ESI = rb_define_module( "ESI" );
370
+ rb_ESIParser = rb_define_class_under( rb_ESI, "CParser", rb_cObject );
371
+
372
+ rb_define_alloc_func( rb_ESIParser, ESIParser_alloc );
373
+
374
+ rb_define_method( rb_ESIParser, "output_handler", ESIParser_set_output_cb, 0 );
375
+ rb_define_method( rb_ESIParser, "start_tag_handler", ESIParser_set_start_tag_cb, 0 );
376
+ rb_define_method( rb_ESIParser, "end_tag_handler", ESIParser_set_end_tag_cb, 0 );
377
+ rb_define_method( rb_ESIParser, "process", ESIParser_process, 1 );
378
+ rb_define_method( rb_ESIParser, "finish", ESIParser_finish, 0 );
379
+ rb_define_method( rb_ESIParser, "esi_tag=", ESIParser_set_esi_tag, 1 );
380
+ rb_define_method( rb_ESIParser, "esi_tag", ESIParser_get_esi_tag, 0 );
381
+ rb_define_method( rb_ESIParser, "depth=", ESIParser_set_depth, 1 );
382
+ rb_define_method( rb_ESIParser, "depth", ESIParser_get_depth, 0 );
383
+ rb_define_method( rb_ESIParser, "output", ESIParser_get_output, 0 );
384
+ rb_define_method( rb_ESIParser, "output=", ESIParser_set_output, 1 );
385
+ rb_define_method( rb_ESIParser, "output<<", ESIParser_send_output, 1 );
386
+
387
+ }
@@ -0,0 +1,6 @@
1
+ require 'mkmf'
2
+
3
+ dir_config("esi")
4
+ have_library("c", "main")
5
+
6
+ create_makefile("esi")
@@ -0,0 +1,499 @@
1
+ # line 1 "ruby_esi.rl"
2
+ module ESI
3
+ class ParserMachine
4
+
5
+ # line 100 "ruby_esi.rl"
6
+
7
+
8
+ def initialize
9
+
10
+ # line 11 "machine.rb"
11
+ class << self
12
+ attr_accessor :_esi_actions
13
+ private :_esi_actions, :_esi_actions=
14
+ end
15
+ self._esi_actions = [
16
+ 0, 1, 9, 2, 9, 0, 2, 9,
17
+ 1, 2, 9, 2, 2, 9, 3, 2,
18
+ 9, 4, 2, 9, 5, 2, 9, 6,
19
+ 2, 9, 7, 2, 9, 8, 3, 9,
20
+ 0, 1, 3, 9, 3, 1, 4, 9,
21
+ 0, 3, 1, 4, 9, 3, 6, 1
22
+ ]
23
+
24
+ class << self
25
+ attr_accessor :_esi_key_offsets
26
+ private :_esi_key_offsets, :_esi_key_offsets=
27
+ end
28
+ self._esi_key_offsets = [
29
+ 0, 1, 4, 6, 8, 10, 12, 15,
30
+ 19, 21, 23, 25, 28, 36, 48, 59,
31
+ 69, 75, 85, 94, 106, 117, 119, 130,
32
+ 140, 150, 160, 170, 180, 191, 201, 211,
33
+ 221, 231, 246, 256, 265, 277, 288, 298,
34
+ 304, 314, 325, 335, 345, 355, 365, 375,
35
+ 386, 396, 406, 416, 426, 441, 451, 453,
36
+ 455, 456, 457, 466, 475
37
+ ]
38
+
39
+ class << self
40
+ attr_accessor :_esi_trans_keys
41
+ private :_esi_trans_keys, :_esi_trans_keys=
42
+ end
43
+ self._esi_trans_keys = [
44
+ 60, 47, 60, 101, 60, 101, 60, 115,
45
+ 60, 105, 58, 60, 60, 97, 122, 60,
46
+ 62, 97, 122, 60, 115, 60, 105, 58,
47
+ 60, 60, 97, 122, 32, 47, 60, 62,
48
+ 9, 13, 97, 122, 32, 45, 47, 60,
49
+ 62, 95, 9, 13, 65, 90, 97, 122,
50
+ 32, 45, 47, 60, 95, 9, 13, 65,
51
+ 90, 97, 122, 45, 60, 61, 95, 48,
52
+ 57, 65, 90, 97, 122, 32, 34, 39,
53
+ 60, 9, 13, 33, 60, 95, 125, 35,
54
+ 38, 40, 90, 97, 123, 34, 39, 60,
55
+ 95, 125, 33, 90, 97, 123, 32, 45,
56
+ 47, 60, 62, 95, 9, 13, 65, 90,
57
+ 97, 122, 32, 45, 47, 60, 95, 9,
58
+ 13, 65, 90, 97, 122, 60, 62, 34,
59
+ 39, 47, 60, 95, 101, 125, 33, 90,
60
+ 97, 123, 34, 39, 60, 95, 101, 125,
61
+ 33, 90, 97, 123, 34, 39, 60, 95,
62
+ 115, 125, 33, 90, 97, 123, 34, 39,
63
+ 60, 95, 105, 125, 33, 90, 97, 123,
64
+ 34, 39, 58, 60, 95, 125, 33, 90,
65
+ 97, 123, 34, 39, 60, 95, 123, 125,
66
+ 33, 90, 97, 122, 34, 39, 60, 62,
67
+ 95, 123, 125, 33, 90, 97, 122, 34,
68
+ 39, 60, 95, 115, 125, 33, 90, 97,
69
+ 123, 34, 39, 60, 95, 105, 125, 33,
70
+ 90, 97, 123, 34, 39, 58, 60, 95,
71
+ 125, 33, 90, 97, 123, 34, 39, 60,
72
+ 95, 123, 125, 33, 90, 97, 122, 32,
73
+ 34, 39, 47, 60, 62, 95, 123, 125,
74
+ 9, 13, 33, 90, 97, 122, 34, 39,
75
+ 60, 62, 95, 125, 33, 90, 97, 123,
76
+ 34, 39, 60, 95, 125, 33, 90, 97,
77
+ 123, 32, 45, 47, 60, 62, 95, 9,
78
+ 13, 65, 90, 97, 122, 32, 45, 47,
79
+ 60, 95, 9, 13, 65, 90, 97, 122,
80
+ 45, 60, 61, 95, 48, 57, 65, 90,
81
+ 97, 122, 32, 34, 39, 60, 9, 13,
82
+ 33, 60, 95, 125, 35, 38, 40, 90,
83
+ 97, 123, 34, 39, 47, 60, 95, 101,
84
+ 125, 33, 90, 97, 123, 34, 39, 60,
85
+ 95, 101, 125, 33, 90, 97, 123, 34,
86
+ 39, 60, 95, 115, 125, 33, 90, 97,
87
+ 123, 34, 39, 60, 95, 105, 125, 33,
88
+ 90, 97, 123, 34, 39, 58, 60, 95,
89
+ 125, 33, 90, 97, 123, 34, 39, 60,
90
+ 95, 123, 125, 33, 90, 97, 122, 34,
91
+ 39, 60, 62, 95, 123, 125, 33, 90,
92
+ 97, 122, 34, 39, 60, 95, 115, 125,
93
+ 33, 90, 97, 123, 34, 39, 60, 95,
94
+ 105, 125, 33, 90, 97, 123, 34, 39,
95
+ 58, 60, 95, 125, 33, 90, 97, 123,
96
+ 34, 39, 60, 95, 123, 125, 33, 90,
97
+ 97, 122, 32, 34, 39, 47, 60, 62,
98
+ 95, 123, 125, 9, 13, 33, 90, 97,
99
+ 122, 34, 39, 60, 62, 95, 125, 33,
100
+ 90, 97, 123, 60, 62, 60, 62, 60,
101
+ 60, 34, 39, 60, 95, 125, 33, 90,
102
+ 97, 123, 34, 39, 60, 95, 125, 33,
103
+ 90, 97, 123, 60, 0
104
+ ]
105
+
106
+ class << self
107
+ attr_accessor :_esi_single_lengths
108
+ private :_esi_single_lengths, :_esi_single_lengths=
109
+ end
110
+ self._esi_single_lengths = [
111
+ 1, 3, 2, 2, 2, 2, 1, 2,
112
+ 2, 2, 2, 1, 4, 6, 5, 4,
113
+ 4, 4, 5, 6, 5, 2, 7, 6,
114
+ 6, 6, 6, 6, 7, 6, 6, 6,
115
+ 6, 9, 6, 5, 6, 5, 4, 4,
116
+ 4, 7, 6, 6, 6, 6, 6, 7,
117
+ 6, 6, 6, 6, 9, 6, 2, 2,
118
+ 1, 1, 5, 5, 1
119
+ ]
120
+
121
+ class << self
122
+ attr_accessor :_esi_range_lengths
123
+ private :_esi_range_lengths, :_esi_range_lengths=
124
+ end
125
+ self._esi_range_lengths = [
126
+ 0, 0, 0, 0, 0, 0, 1, 1,
127
+ 0, 0, 0, 1, 2, 3, 3, 3,
128
+ 1, 3, 2, 3, 3, 0, 2, 2,
129
+ 2, 2, 2, 2, 2, 2, 2, 2,
130
+ 2, 3, 2, 2, 3, 3, 3, 1,
131
+ 3, 2, 2, 2, 2, 2, 2, 2,
132
+ 2, 2, 2, 2, 3, 2, 0, 0,
133
+ 0, 0, 2, 2, 0
134
+ ]
135
+
136
+ class << self
137
+ attr_accessor :_esi_index_offsets
138
+ private :_esi_index_offsets, :_esi_index_offsets=
139
+ end
140
+ self._esi_index_offsets = [
141
+ 0, 2, 6, 9, 12, 15, 18, 21,
142
+ 25, 28, 31, 34, 37, 44, 54, 63,
143
+ 71, 77, 85, 93, 103, 112, 115, 125,
144
+ 134, 143, 152, 161, 170, 180, 189, 198,
145
+ 207, 216, 229, 238, 246, 256, 265, 273,
146
+ 279, 287, 297, 306, 315, 324, 333, 342,
147
+ 352, 361, 370, 379, 388, 401, 410, 413,
148
+ 416, 418, 420, 428, 436
149
+ ]
150
+
151
+ class << self
152
+ attr_accessor :_esi_indicies
153
+ private :_esi_indicies, :_esi_indicies=
154
+ end
155
+ self._esi_indicies = [
156
+ 1, 0, 2, 1, 3, 0, 1, 4,
157
+ 0, 1, 5, 0, 1, 6, 0, 7,
158
+ 1, 0, 1, 8, 0, 1, 9, 8,
159
+ 0, 1, 10, 0, 1, 11, 0, 12,
160
+ 1, 0, 1, 13, 0, 14, 15, 1,
161
+ 16, 14, 13, 0, 17, 18, 19, 1,
162
+ 20, 18, 17, 18, 18, 0, 17, 18,
163
+ 19, 1, 18, 17, 18, 18, 0, 18,
164
+ 1, 21, 18, 18, 18, 18, 0, 22,
165
+ 23, 23, 1, 22, 0, 24, 25, 24,
166
+ 24, 24, 24, 24, 0, 26, 26, 25,
167
+ 24, 24, 24, 24, 0, 27, 18, 28,
168
+ 1, 20, 18, 27, 18, 18, 0, 27,
169
+ 18, 28, 1, 18, 27, 18, 18, 0,
170
+ 1, 29, 0, 26, 26, 30, 25, 24,
171
+ 31, 24, 24, 24, 0, 26, 26, 25,
172
+ 24, 32, 24, 24, 24, 0, 26, 26,
173
+ 25, 24, 33, 24, 24, 24, 0, 26,
174
+ 26, 25, 24, 34, 24, 24, 24, 0,
175
+ 26, 26, 35, 25, 24, 24, 24, 24,
176
+ 0, 26, 26, 25, 24, 24, 24, 24,
177
+ 36, 0, 26, 26, 25, 37, 24, 24,
178
+ 24, 24, 36, 0, 26, 26, 25, 24,
179
+ 38, 24, 24, 24, 0, 26, 26, 25,
180
+ 24, 39, 24, 24, 24, 0, 26, 26,
181
+ 40, 25, 24, 24, 24, 24, 0, 26,
182
+ 26, 25, 24, 24, 24, 24, 41, 0,
183
+ 14, 26, 26, 42, 25, 43, 24, 24,
184
+ 24, 14, 24, 41, 0, 26, 26, 25,
185
+ 44, 24, 24, 24, 24, 0, 46, 46,
186
+ 47, 45, 45, 45, 45, 0, 48, 49,
187
+ 28, 1, 20, 49, 48, 49, 49, 0,
188
+ 48, 49, 28, 1, 49, 48, 49, 49,
189
+ 0, 49, 1, 50, 49, 49, 49, 49,
190
+ 0, 51, 52, 52, 1, 51, 0, 45,
191
+ 47, 45, 45, 45, 45, 45, 0, 46,
192
+ 46, 53, 47, 45, 54, 45, 45, 45,
193
+ 0, 46, 46, 47, 45, 55, 45, 45,
194
+ 45, 0, 46, 46, 47, 45, 56, 45,
195
+ 45, 45, 0, 46, 46, 47, 45, 57,
196
+ 45, 45, 45, 0, 46, 46, 58, 47,
197
+ 45, 45, 45, 45, 0, 46, 46, 47,
198
+ 45, 45, 45, 45, 59, 0, 46, 46,
199
+ 47, 60, 45, 45, 45, 45, 59, 0,
200
+ 46, 46, 47, 45, 61, 45, 45, 45,
201
+ 0, 46, 46, 47, 45, 62, 45, 45,
202
+ 45, 0, 46, 46, 63, 47, 45, 45,
203
+ 45, 45, 0, 46, 46, 47, 45, 45,
204
+ 45, 45, 64, 0, 14, 46, 46, 65,
205
+ 47, 66, 45, 45, 45, 14, 45, 64,
206
+ 0, 46, 46, 47, 67, 45, 45, 45,
207
+ 45, 0, 1, 68, 0, 1, 69, 0,
208
+ 1, 0, 71, 70, 74, 74, 75, 73,
209
+ 73, 73, 73, 72, 74, 74, 75, 73,
210
+ 73, 73, 73, 72, 76, 72, 0
211
+ ]
212
+
213
+ class << self
214
+ attr_accessor :_esi_trans_targs_wi
215
+ private :_esi_trans_targs_wi, :_esi_trans_targs_wi=
216
+ end
217
+ self._esi_trans_targs_wi = [
218
+ 0, 1, 2, 8, 3, 4, 5, 6,
219
+ 7, 0, 9, 10, 11, 12, 13, 55,
220
+ 0, 14, 15, 54, 57, 16, 16, 17,
221
+ 18, 22, 19, 20, 21, 57, 23, 29,
222
+ 24, 25, 26, 27, 28, 18, 30, 31,
223
+ 32, 33, 34, 18, 58, 35, 36, 41,
224
+ 37, 38, 39, 39, 40, 42, 48, 43,
225
+ 44, 45, 46, 47, 35, 49, 50, 51,
226
+ 52, 53, 35, 59, 60, 60, 0, 1,
227
+ 0, 35, 36, 41, 1
228
+ ]
229
+
230
+ class << self
231
+ attr_accessor :_esi_trans_actions_wi
232
+ private :_esi_trans_actions_wi, :_esi_trans_actions_wi=
233
+ end
234
+ self._esi_trans_actions_wi = [
235
+ 1, 3, 1, 1, 1, 1, 1, 1,
236
+ 1, 27, 1, 1, 1, 1, 9, 9,
237
+ 24, 1, 1, 9, 15, 18, 1, 1,
238
+ 1, 3, 21, 1, 1, 12, 1, 1,
239
+ 1, 1, 1, 1, 1, 27, 1, 1,
240
+ 1, 1, 9, 24, 1, 1, 21, 3,
241
+ 1, 1, 18, 1, 1, 1, 1, 1,
242
+ 1, 1, 1, 1, 27, 1, 1, 1,
243
+ 1, 9, 24, 1, 12, 1, 6, 30,
244
+ 34, 34, 43, 38, 38
245
+ ]
246
+
247
+ class << self
248
+ attr_accessor :esi_start
249
+ end
250
+ self.esi_start = 56;
251
+ class << self
252
+ attr_accessor :esi_first_final
253
+ end
254
+ self.esi_first_final = 56;
255
+ class << self
256
+ attr_accessor :esi_error
257
+ end
258
+ self.esi_error = -1;
259
+
260
+ class << self
261
+ attr_accessor :esi_en_main
262
+ end
263
+ self.esi_en_main = 56;
264
+
265
+ # line 104 "ruby_esi.rl"
266
+ end
267
+
268
+ # process a block of esi tags
269
+ def process(data)
270
+ if @data
271
+ # puts "append : #{@mark} : #{p}"
272
+ data = @data + data
273
+ p = @data.length
274
+ end
275
+ @mark ||= 0
276
+ p ||= 0
277
+ pe ||= data.length
278
+ @cs ||= esi_start
279
+ cs = @cs
280
+ # puts "process: #{cs.inspect} :start #{data.inspect}, #{p}"
281
+
282
+ # line 283 "machine.rb"
283
+ begin
284
+ _klen, _trans, _keys, _acts, _nacts = nil
285
+ if p != pe
286
+ while true
287
+ _break_resume = false
288
+ begin
289
+ _break_again = false
290
+ _keys = _esi_key_offsets[cs]
291
+ _trans = _esi_index_offsets[cs]
292
+ _klen = _esi_single_lengths[cs]
293
+ _break_match = false
294
+
295
+ begin
296
+ if _klen > 0
297
+ _lower = _keys
298
+ _upper = _keys + _klen - 1
299
+
300
+ loop do
301
+ break if _upper < _lower
302
+ _mid = _lower + ( (_upper - _lower) >> 1 )
303
+
304
+ if data[p] < _esi_trans_keys[_mid]
305
+ _upper = _mid - 1
306
+ elsif data[p] > _esi_trans_keys[_mid]
307
+ _lower = _mid + 1
308
+ else
309
+ _trans += (_mid - _keys)
310
+ _break_match = true
311
+ break
312
+ end
313
+ end # loop
314
+ break if _break_match
315
+ _keys += _klen
316
+ _trans += _klen
317
+ end
318
+ _klen = _esi_range_lengths[cs]
319
+ if _klen > 0
320
+ _lower = _keys
321
+ _upper = _keys + (_klen << 1) - 2
322
+ loop do
323
+ break if _upper < _lower
324
+ _mid = _lower + (((_upper-_lower) >> 1) & ~1)
325
+ if data[p] < _esi_trans_keys[_mid]
326
+ _upper = _mid - 2
327
+ elsif data[p] > _esi_trans_keys[_mid+1]
328
+ _lower = _mid + 2
329
+ else
330
+ _trans += ((_mid - _keys) >> 1)
331
+ _break_match = true
332
+ break
333
+ end
334
+ end # loop
335
+ break if _break_match
336
+ _trans += _klen
337
+ end
338
+ end while false
339
+ _trans = _esi_indicies[_trans]
340
+ cs = _esi_trans_targs_wi[_trans]
341
+ break if _esi_trans_actions_wi[_trans] == 0
342
+ _acts = _esi_trans_actions_wi[_trans]
343
+ _nacts = _esi_actions[_acts]
344
+ _acts += 1
345
+ while _nacts > 0
346
+ _nacts -= 1
347
+ _acts += 1
348
+ case _esi_actions[_acts - 1]
349
+ when 0:
350
+ # line 7 "ruby_esi.rl"
351
+ begin
352
+
353
+ @mark = p
354
+ end
355
+ # line 7 "ruby_esi.rl"
356
+ when 1:
357
+ # line 10 "ruby_esi.rl"
358
+ begin
359
+
360
+ end
361
+ # line 10 "ruby_esi.rl"
362
+ when 2:
363
+ # line 14 "ruby_esi.rl"
364
+ begin
365
+
366
+ @tag_text = data[@mark,p-@mark]
367
+ @tag_info = {} # store the tag attributes
368
+ @tag_info[:name] = @tag_text.sub('<','').strip
369
+ @tag_info[:attributes] = {}
370
+ # puts "have esi tag at #{p}=>#{@mark}:#{data[p,1].inspect} with data #{@tag_text.inspect}"
371
+ @mark = p
372
+ end
373
+ # line 14 "ruby_esi.rl"
374
+ when 3:
375
+ # line 23 "ruby_esi.rl"
376
+ begin
377
+
378
+ # puts "parsed esi tag at #{p}=>#{@mark}:#{data[p,1].inspect} with data #{@tag_text.inspect}"
379
+ @start_tag.call @tag_info[:name], @tag_info[:attributes] if @start_tag
380
+ @end_tag.call @tag_info[:name] if @end_tag
381
+ @attr_key = nil
382
+ @attr_value = nil
383
+ @tag_text = nil
384
+ @tag_info = nil
385
+ end
386
+ # line 23 "ruby_esi.rl"
387
+ when 4:
388
+ # line 33 "ruby_esi.rl"
389
+ begin
390
+
391
+ # puts "parsed esi tag at #{p}=>#{@mark}:#{data[p,1].inspect} with data #{@tag_text.inspect}"
392
+ @start_tag.call @tag_info[:name], @tag_info[:attributes] if @start_tag
393
+ @attr_key = nil
394
+ @attr_value = nil
395
+ @tag_text = nil
396
+ @tag_info = nil
397
+ end
398
+ # line 33 "ruby_esi.rl"
399
+ when 5:
400
+ # line 42 "ruby_esi.rl"
401
+ begin
402
+
403
+ @attr_key = data[@mark,p-@mark]
404
+ @mark += (@attr_key.size)
405
+ @attr_key.gsub!(/^['"]/,'')
406
+ @attr_key.strip!
407
+ # puts "SeeAttributeKey: #{data[@mark,1].inspect}: #{data[p,1].inspect} #{@attr_key.inspect}"
408
+ end
409
+ # line 42 "ruby_esi.rl"
410
+ when 6:
411
+ # line 50 "ruby_esi.rl"
412
+ begin
413
+
414
+ @attr_value = data[@mark,p-@mark]
415
+ @attr_value.strip!
416
+ @attr_value.gsub!(/^=?\s*['"]/,'')
417
+ @attr_value.gsub!(/['"]$/,'')
418
+
419
+ @tag_info[:attributes][@attr_key] = @attr_value
420
+ # puts "SeeAttributeValue: #{p} #{data[@mark,1].inspect}: #{data[p,1].inspect} #{@attr_key.inspect} => #{@attr_value.inspect}"
421
+ @mark = p
422
+ end
423
+ # line 50 "ruby_esi.rl"
424
+ when 7:
425
+ # line 61 "ruby_esi.rl"
426
+ begin
427
+
428
+ tag_text = data[@mark+1,p-@mark-1]
429
+ @start_tag.call tag_text, {} if @start_tag
430
+ # puts "Block start: #{p} #{tag_text}"
431
+ end
432
+ # line 61 "ruby_esi.rl"
433
+ when 8:
434
+ # line 67 "ruby_esi.rl"
435
+ begin
436
+
437
+ tag_text = data[@mark+2,p-@mark-2]
438
+ @end_tag.call tag_text if @end_tag
439
+ # puts "Block end: #{p} #{tag_text}"
440
+ end
441
+ # line 67 "ruby_esi.rl"
442
+ when 9:
443
+ # line 73 "ruby_esi.rl"
444
+ begin
445
+
446
+ # print " [#{data[p,1].inspect}:#{cs}] " if $debug
447
+
448
+ case cs
449
+ when 0
450
+ # NOTE: state 12 is the character state before <esi:try>, state 7 is the character before </esi:try>
451
+ # | |
452
+ # - state 12 - state 7
453
+ # state 60 is for empty inline tags e.g.
454
+ # <esi:include/>
455
+ # |
456
+ # - 60
457
+
458
+ if @prev_state != 12 and @prev_state != 7
459
+ if !@prev_buffer.empty? and (@prev_state != (esi_en_main + 1)) and @prev_state != 60
460
+ stream_buffer @prev_buffer
461
+ end
462
+ stream_buffer data[p,1]
463
+ end
464
+ @prev_buffer = ""
465
+ else
466
+ @prev_buffer << data[p,1]
467
+ end
468
+ @prev_state = cs
469
+ end
470
+ # line 73 "ruby_esi.rl"
471
+ # line 472 "machine.rb"
472
+ end # action switch
473
+ end
474
+ end while false
475
+ break if _break_resume
476
+ p += 1
477
+ break if p == pe
478
+ end
479
+ end
480
+ end
481
+ # line 120 "ruby_esi.rl"
482
+ @cs = cs
483
+ if( @cs != esi_start && @cs != 0 )
484
+ # puts "append process: #{@cs.inspect}"
485
+ @data = data
486
+ else
487
+ @data = nil
488
+ end
489
+ end
490
+
491
+ def finish
492
+
493
+ # line 494 "machine.rb"
494
+ # line 131 "ruby_esi.rl"
495
+ end
496
+
497
+ end
498
+
499
+ end