mongrel_esi 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
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