mongrel_esi 0.5.0 → 0.5.1
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +14 -6
- data/doc/rdoc/classes/ESI/CParser.html +122 -0
- data/doc/rdoc/classes/ESI/Cache.html +178 -0
- data/doc/rdoc/classes/ESI/Cache.src/M000085.html +17 -0
- data/doc/rdoc/classes/ESI/Cache.src/M000086.html +20 -0
- data/doc/rdoc/classes/ESI/Config.html +333 -0
- data/doc/rdoc/classes/ESI/Config.src/M000052.html +18 -0
- data/doc/rdoc/classes/ESI/Config.src/M000053.html +18 -0
- data/doc/rdoc/classes/ESI/Config.src/M000054.html +35 -0
- data/doc/rdoc/classes/ESI/Config.src/M000055.html +38 -0
- data/doc/rdoc/classes/ESI/Config.src/M000056.html +23 -0
- data/doc/rdoc/classes/ESI/Config.src/M000057.html +18 -0
- data/doc/rdoc/classes/ESI/Config.src/M000058.html +20 -0
- data/doc/rdoc/classes/ESI/Config.src/M000059.html +18 -0
- data/doc/rdoc/classes/ESI/Config.src/M000060.html +24 -0
- data/doc/rdoc/classes/ESI/Config/CacheConfig.html +212 -0
- data/doc/rdoc/classes/ESI/Config/CacheConfig.src/M000064.html +19 -0
- data/doc/rdoc/classes/ESI/Config/CacheConfig.src/M000065.html +19 -0
- data/doc/rdoc/classes/ESI/Config/CacheConfig.src/M000066.html +18 -0
- data/doc/rdoc/classes/ESI/Config/CacheConfig.src/M000067.html +18 -0
- data/doc/rdoc/classes/ESI/Config/CacheConfig.src/M000068.html +18 -0
- data/doc/rdoc/classes/ESI/Config/ConfigRouter.html +187 -0
- data/doc/rdoc/classes/ESI/Config/ConfigRouter.src/M000061.html +19 -0
- data/doc/rdoc/classes/ESI/Config/ConfigRouter.src/M000062.html +21 -0
- data/doc/rdoc/classes/ESI/Config/ConfigRouter.src/M000063.html +21 -0
- data/doc/rdoc/classes/ESI/Dispatcher.html +172 -0
- data/doc/rdoc/classes/ESI/Dispatcher.src/M000087.html +22 -0
- data/doc/rdoc/classes/ESI/Dispatcher.src/M000088.html +18 -0
- data/doc/rdoc/classes/ESI/Fragment.html +218 -0
- data/doc/rdoc/classes/ESI/Fragment.src/M000100.html +20 -0
- data/doc/rdoc/classes/ESI/Fragment.src/M000101.html +18 -0
- data/doc/rdoc/classes/ESI/Fragment.src/M000102.html +18 -0
- data/doc/rdoc/classes/ESI/Invalidator.html +131 -0
- data/doc/rdoc/classes/ESI/Invalidator.src/M000004.html +41 -0
- data/doc/rdoc/classes/ESI/Log.html +221 -0
- data/doc/rdoc/classes/ESI/Log.src/M000030.html +18 -0
- data/doc/rdoc/classes/ESI/Log.src/M000031.html +18 -0
- data/doc/rdoc/classes/ESI/Log.src/M000032.html +18 -0
- data/doc/rdoc/classes/ESI/Log.src/M000033.html +18 -0
- data/doc/rdoc/classes/ESI/Log.src/M000034.html +18 -0
- data/doc/rdoc/classes/ESI/Log.src/M000035.html +18 -0
- data/doc/rdoc/classes/ESI/Log.src/M000036.html +18 -0
- data/doc/rdoc/classes/ESI/MemcachedCache.html +314 -0
- data/doc/rdoc/classes/ESI/MemcachedCache.src/M000040.html +24 -0
- data/doc/rdoc/classes/ESI/MemcachedCache.src/M000041.html +22 -0
- data/doc/rdoc/classes/ESI/MemcachedCache.src/M000042.html +19 -0
- data/doc/rdoc/classes/ESI/MemcachedCache.src/M000043.html +23 -0
- data/doc/rdoc/classes/ESI/MemcachedCache.src/M000044.html +18 -0
- data/doc/rdoc/classes/ESI/MemcachedCache.src/M000045.html +19 -0
- data/doc/rdoc/classes/ESI/MemcachedCache.src/M000046.html +18 -0
- data/doc/rdoc/classes/ESI/MemcachedCache.src/M000047.html +18 -0
- data/doc/rdoc/classes/ESI/MemcachedCache.src/M000048.html +17 -0
- data/doc/rdoc/classes/ESI/Parser.html +184 -0
- data/doc/rdoc/classes/ESI/Parser.src/M000049.html +51 -0
- data/doc/rdoc/classes/ESI/Parser.src/M000050.html +39 -0
- data/doc/rdoc/classes/ESI/Parser.src/M000051.html +19 -0
- data/doc/rdoc/classes/ESI/Processor.html +194 -0
- data/doc/rdoc/classes/ESI/Processor.src/M000037.html +26 -0
- data/doc/rdoc/classes/ESI/Processor.src/M000038.html +44 -0
- data/doc/rdoc/classes/ESI/Processor.src/M000039.html +26 -0
- data/doc/rdoc/classes/ESI/Proxy.html +304 -0
- data/doc/rdoc/classes/ESI/Proxy.src/M000069.html +20 -0
- data/doc/rdoc/classes/ESI/Proxy.src/M000070.html +55 -0
- data/doc/rdoc/classes/ESI/Proxy.src/M000071.html +53 -0
- data/doc/rdoc/classes/ESI/Proxy.src/M000072.html +25 -0
- data/doc/rdoc/classes/ESI/Proxy.src/M000073.html +19 -0
- data/doc/rdoc/classes/ESI/Proxy.src/M000074.html +27 -0
- data/doc/rdoc/classes/ESI/Proxy.src/M000075.html +18 -0
- data/doc/rdoc/classes/ESI/Proxy.src/M000076.html +28 -0
- data/doc/rdoc/classes/ESI/Proxy.src/M000077.html +29 -0
- data/doc/rdoc/classes/ESI/Response.html +250 -0
- data/doc/rdoc/classes/ESI/Response.src/M000078.html +23 -0
- data/doc/rdoc/classes/ESI/Response.src/M000079.html +18 -0
- data/doc/rdoc/classes/ESI/Response.src/M000080.html +21 -0
- data/doc/rdoc/classes/ESI/Response.src/M000081.html +20 -0
- data/doc/rdoc/classes/ESI/Response.src/M000082.html +25 -0
- data/doc/rdoc/classes/ESI/Response.src/M000083.html +18 -0
- data/doc/rdoc/classes/ESI/Response.src/M000084.html +33 -0
- data/doc/rdoc/classes/ESI/Router.html +212 -0
- data/doc/rdoc/classes/ESI/Router.src/M000098.html +36 -0
- data/doc/rdoc/classes/ESI/Router.src/M000099.html +25 -0
- data/doc/rdoc/classes/ESI/RubyCache.html +278 -0
- data/doc/rdoc/classes/ESI/RubyCache.src/M000089.html +20 -0
- data/doc/rdoc/classes/ESI/RubyCache.src/M000090.html +20 -0
- data/doc/rdoc/classes/ESI/RubyCache.src/M000091.html +20 -0
- data/doc/rdoc/classes/ESI/RubyCache.src/M000092.html +22 -0
- data/doc/rdoc/classes/ESI/RubyCache.src/M000093.html +18 -0
- data/doc/rdoc/classes/ESI/RubyCache.src/M000094.html +22 -0
- data/doc/rdoc/classes/ESI/RubyCache.src/M000095.html +18 -0
- data/doc/rdoc/classes/ESI/RubyCache.src/M000096.html +18 -0
- data/doc/rdoc/classes/ESI/RubyCache.src/M000097.html +18 -0
- data/doc/rdoc/classes/ESI/Tag.html +141 -0
- data/doc/rdoc/classes/ESI/Tag/Attempt.html +113 -0
- data/doc/rdoc/classes/ESI/Tag/Base.html +237 -0
- data/doc/rdoc/classes/ESI/Tag/Base.src/M000026.html +23 -0
- data/doc/rdoc/classes/ESI/Tag/Base.src/M000027.html +22 -0
- data/doc/rdoc/classes/ESI/Tag/Base.src/M000028.html +22 -0
- data/doc/rdoc/classes/ESI/Tag/Base.src/M000029.html +17 -0
- data/doc/rdoc/classes/ESI/Tag/Container.html +206 -0
- data/doc/rdoc/classes/ESI/Tag/Container.src/M000015.html +20 -0
- data/doc/rdoc/classes/ESI/Tag/Container.src/M000016.html +22 -0
- data/doc/rdoc/classes/ESI/Tag/Container.src/M000017.html +25 -0
- data/doc/rdoc/classes/ESI/Tag/Except.html +184 -0
- data/doc/rdoc/classes/ESI/Tag/Except.src/M000018.html +21 -0
- data/doc/rdoc/classes/ESI/Tag/Except.src/M000019.html +20 -0
- data/doc/rdoc/classes/ESI/Tag/Except.src/M000020.html +18 -0
- data/doc/rdoc/classes/ESI/Tag/Include.html +257 -0
- data/doc/rdoc/classes/ESI/Tag/Include.src/M000005.html +20 -0
- data/doc/rdoc/classes/ESI/Tag/Include.src/M000006.html +18 -0
- data/doc/rdoc/classes/ESI/Tag/Include.src/M000007.html +34 -0
- data/doc/rdoc/classes/ESI/Tag/Include.src/M000008.html +22 -0
- data/doc/rdoc/classes/ESI/Tag/Include.src/M000009.html +27 -0
- data/doc/rdoc/classes/ESI/Tag/Include.src/M000010.html +30 -0
- data/doc/rdoc/classes/ESI/Tag/Include.src/M000011.html +51 -0
- data/doc/rdoc/classes/ESI/Tag/Include/Request.html +199 -0
- data/doc/rdoc/classes/ESI/Tag/Include/Request.src/M000012.html +18 -0
- data/doc/rdoc/classes/ESI/Tag/Include/Request.src/M000013.html +44 -0
- data/doc/rdoc/classes/ESI/Tag/Include/Request/Error.html +155 -0
- data/doc/rdoc/classes/ESI/Tag/Include/Request/Error.src/M000014.html +19 -0
- data/doc/rdoc/classes/ESI/Tag/Invalidate.html +171 -0
- data/doc/rdoc/classes/ESI/Tag/Invalidate.src/M000023.html +19 -0
- data/doc/rdoc/classes/ESI/Tag/Invalidate.src/M000024.html +51 -0
- data/doc/rdoc/classes/ESI/Tag/Invalidate.src/M000025.html +19 -0
- data/doc/rdoc/classes/ESI/Tag/Try.html +154 -0
- data/doc/rdoc/classes/ESI/Tag/Try.src/M000021.html +38 -0
- data/doc/rdoc/classes/ESI/Tag/Try.src/M000022.html +18 -0
- data/doc/rdoc/classes/MultiDirHandler.html +198 -0
- data/doc/rdoc/classes/MultiDirHandler.src/M000001.html +20 -0
- data/doc/rdoc/classes/MultiDirHandler.src/M000002.html +28 -0
- data/doc/rdoc/classes/MultiDirHandler.src/M000003.html +22 -0
- data/doc/rdoc/created.rid +1 -0
- data/doc/rdoc/files/COPYING.html +167 -0
- data/doc/rdoc/files/LICENSE.html +605 -0
- data/doc/rdoc/files/README.html +359 -0
- data/doc/rdoc/files/ext/esi/common_rl.html +160 -0
- data/doc/rdoc/files/ext/esi/esi_parser_c.html +101 -0
- data/doc/rdoc/files/ext/esi/parser_c.html +101 -0
- data/doc/rdoc/files/ext/esi/parser_h.html +101 -0
- data/doc/rdoc/files/ext/esi/parser_rl.html +827 -0
- data/doc/rdoc/files/ext/esi/test/common_rl.html +160 -0
- data/doc/rdoc/files/ext/esi/test/parser_c.html +101 -0
- data/doc/rdoc/files/ext/esi/test/parser_h.html +101 -0
- data/doc/rdoc/files/ext/esi/test/parser_rl.html +827 -0
- data/doc/rdoc/files/ext/esi/test/sp_c.html +101 -0
- data/doc/rdoc/files/ext/esi/test/test_c.html +101 -0
- data/doc/rdoc/files/lib/esi/cache_rb.html +119 -0
- data/doc/rdoc/files/lib/esi/config_rb.html +114 -0
- data/doc/rdoc/files/lib/esi/dispatcher_rb.html +108 -0
- data/doc/rdoc/files/lib/esi/invalidator_rb.html +114 -0
- data/doc/rdoc/files/lib/esi/logger_rb.html +108 -0
- data/doc/rdoc/files/lib/esi/parser_rb.html +120 -0
- data/doc/rdoc/files/lib/esi/processor_rb.html +115 -0
- data/doc/rdoc/files/lib/esi/proxy_rb.html +123 -0
- data/doc/rdoc/files/lib/esi/response_rb.html +116 -0
- data/doc/rdoc/files/lib/esi/router_rb.html +107 -0
- data/doc/rdoc/files/lib/esi/tag/attempt_rb.html +114 -0
- data/doc/rdoc/files/lib/esi/tag/base_rb.html +114 -0
- data/doc/rdoc/files/lib/esi/tag/container_rb.html +115 -0
- data/doc/rdoc/files/lib/esi/tag/except_rb.html +114 -0
- data/doc/rdoc/files/lib/esi/tag/include_rb.html +116 -0
- data/doc/rdoc/files/lib/esi/tag/invalidate_rb.html +115 -0
- data/doc/rdoc/files/lib/esi/tag/try_rb.html +115 -0
- data/doc/rdoc/files/lib/esi/version_rb.html +101 -0
- data/doc/rdoc/files/lib/multi_dirhandler_rb.html +109 -0
- data/doc/rdoc/fr_class_index.html +53 -0
- data/doc/rdoc/fr_file_index.html +59 -0
- data/doc/rdoc/fr_method_index.html +128 -0
- data/doc/rdoc/index.html +24 -0
- data/doc/rdoc/rdoc-style.css +208 -0
- data/ext/esi/esi_parser.c +12 -1
- data/ext/esi/parser.c +492 -3927
- data/ext/esi/parser.rl +83 -14
- data/ext/esi/test/parser.c +1587 -367
- data/ext/esi/test/parser.rl +83 -14
- data/ext/esi/test/sp.c +125 -0
- data/ext/esi/test/test.c +198 -6
- data/lib/esi/cache.rb +5 -8
- data/lib/esi/config.rb +3 -3
- data/lib/esi/dispatcher.rb +2 -4
- data/lib/esi/parser.rb +26 -13
- data/lib/esi/processor.rb +13 -35
- data/lib/esi/proxy.rb +113 -44
- data/lib/esi/response.rb +23 -55
- data/lib/esi/router.rb +0 -11
- data/lib/esi/tag/attempt.rb +2 -1
- data/lib/esi/tag/base.rb +1 -24
- data/lib/esi/tag/container.rb +40 -0
- data/lib/esi/tag/except.rb +3 -1
- data/lib/esi/tag/include.rb +53 -62
- data/lib/esi/tag/try.rb +16 -18
- data/lib/esi/version.rb +9 -0
- data/test/integration/handler_test.rb +49 -12
- data/test/integration/help.rb +12 -0
- data/test/load_test.rb +8 -4
- data/test/load_test_ab.rb +8 -0
- data/test/sample.html +31 -0
- data/test/unit/help.rb +12 -8
- data/test/unit/include_request_test.rb +14 -21
- data/test/unit/parser_test.rb +2 -1
- data/test/unit/response_test.rb +4 -8
- data/tools/rakehelp.rb +1 -1
- metadata +216 -5
data/ext/esi/test/parser.rl
CHANGED
@@ -15,6 +15,8 @@ static void debug_string( const char *msg, const char *str, size_t len )
|
|
15
15
|
printf( "%s :'%s'\n", msg, pstr );
|
16
16
|
free( pstr );
|
17
17
|
}
|
18
|
+
#else
|
19
|
+
#define debug_string(m,s,l)
|
18
20
|
#endif
|
19
21
|
|
20
22
|
/* define default callbacks */
|
@@ -93,7 +95,7 @@ static void esi_parser_concat_to_echobuffer( ESIParser *parser, char ch )
|
|
93
95
|
{
|
94
96
|
parser->echobuffer_index++;
|
95
97
|
|
96
|
-
if( parser->echobuffer_allocated <= parser->echobuffer_index ){
|
98
|
+
if( parser->echobuffer_allocated <= parser->echobuffer_index ) {
|
97
99
|
/* double the echobuffer size
|
98
100
|
* we're getting some crazy input if this case ever happens
|
99
101
|
*/
|
@@ -114,7 +116,7 @@ static void ltrim_pointer( const char **ptr, const char *bounds, size_t *len )
|
|
114
116
|
**ptr == '=' ||
|
115
117
|
**ptr == '"' ||
|
116
118
|
**ptr == '<' ||
|
117
|
-
**ptr == '\'' ) && (*len > 0) && (*ptr != bounds) ){
|
119
|
+
**ptr == '\'' ) && (*len > 0) && (*ptr != bounds) ) {
|
118
120
|
(*ptr)++;
|
119
121
|
(*len)--;
|
120
122
|
}
|
@@ -229,11 +231,11 @@ static void rtrim_pointer( const char **ptr, const char *bounds, size_t *len )
|
|
229
231
|
parser->attr_value, parser->attr_value_length );
|
230
232
|
|
231
233
|
/* add the new attribute to the list of attributes */
|
232
|
-
if( parser->attributes ){
|
234
|
+
if( parser->attributes ) {
|
233
235
|
parser->last->next = attr;
|
234
236
|
parser->last = attr;
|
235
237
|
}
|
236
|
-
else{
|
238
|
+
else {
|
237
239
|
parser->last = parser->attributes = attr;
|
238
240
|
}
|
239
241
|
}
|
@@ -277,7 +279,7 @@ static void rtrim_pointer( const char **ptr, const char *bounds, size_t *len )
|
|
277
279
|
# process each character in the input stream for output
|
278
280
|
action echo {
|
279
281
|
//printf( "[%c:%d],", *p, cs );
|
280
|
-
switch( cs ){
|
282
|
+
switch( cs ) {
|
281
283
|
case 0: /* non matching state */
|
282
284
|
if( parser->prev_state != 12 && parser->prev_state != 7 ){ /* states following a possible end state for a tag */
|
283
285
|
if( parser->echobuffer && parser->echobuffer_index != -1 ){
|
@@ -363,11 +365,14 @@ ESIParser *esi_parser_new()
|
|
363
365
|
ESIParser *parser = (ESIParser*)malloc(sizeof(ESIParser));
|
364
366
|
parser->cs = esi_start;
|
365
367
|
parser->mark = NULL;
|
368
|
+
parser->tag_text = NULL;
|
369
|
+
parser->attr_key = NULL;
|
370
|
+
parser->attr_value = NULL;
|
366
371
|
parser->overflow_data_size = 0;
|
367
372
|
parser->overflow_data = NULL;
|
368
373
|
|
369
|
-
/* allocate
|
370
|
-
parser->echobuffer_allocated = ESI_OUTPUT_BUFFER_SIZE;
|
374
|
+
/* allocate ESI_OUTPUT_BUFFER_SIZE bytes for the echobuffer */
|
375
|
+
parser->echobuffer_allocated = ESI_OUTPUT_BUFFER_SIZE;
|
371
376
|
parser->echobuffer_index = -1;
|
372
377
|
parser->echobuffer = (char*)malloc(sizeof(char)*parser->echobuffer_allocated);
|
373
378
|
|
@@ -408,12 +413,58 @@ int esi_parser_init( ESIParser *parser )
|
|
408
413
|
|
409
414
|
static int compute_offset( const char *mark, const char *data )
|
410
415
|
{
|
411
|
-
if( mark ){
|
416
|
+
if( mark ) {
|
412
417
|
return mark - data;
|
413
418
|
}
|
414
419
|
return -1;
|
415
420
|
}
|
416
421
|
|
422
|
+
/*
|
423
|
+
* scans the data buffer for a start sequence /<$/, /<e$/, /<es$/, /<esi$/, /<esi:$/
|
424
|
+
* returns index of if start sequence found else returns -1
|
425
|
+
*/
|
426
|
+
static int
|
427
|
+
esi_parser_scan_for_start( ESIParser *parser, const char *data, size_t length )
|
428
|
+
{
|
429
|
+
size_t i, f = -2, s = -2;
|
430
|
+
char ch;
|
431
|
+
|
432
|
+
for( i = 0; i < length; ++i ) {
|
433
|
+
ch = data[i];
|
434
|
+
switch( ch ) {
|
435
|
+
case '<':
|
436
|
+
f = s = i;
|
437
|
+
break;
|
438
|
+
case '/':
|
439
|
+
if( s == (i-1) && f != -2 ) { s = i; }
|
440
|
+
break;
|
441
|
+
case 'e':
|
442
|
+
if( s == (i-1) && f != -2 ) { s = i; }
|
443
|
+
break;
|
444
|
+
case 's':
|
445
|
+
if( s == (i-1) && f != -2 ) { s = i; }
|
446
|
+
break;
|
447
|
+
case 'i':
|
448
|
+
if( s == (i-1) && f != -2 ) { s = i; }
|
449
|
+
break;
|
450
|
+
case ':':
|
451
|
+
if( s == (i-1) && f != -2 ) { s = i; return f; }
|
452
|
+
break;
|
453
|
+
default:
|
454
|
+
f = s = -2;
|
455
|
+
break;
|
456
|
+
}
|
457
|
+
}
|
458
|
+
|
459
|
+
// if s and f are still valid at end of input return f
|
460
|
+
if( f != -2 && s != -2 ) {
|
461
|
+
return f;
|
462
|
+
}
|
463
|
+
else {
|
464
|
+
return -1;
|
465
|
+
}
|
466
|
+
}
|
467
|
+
|
417
468
|
/* accept an arbitrary length string buffer
|
418
469
|
* when this methods exits it determines if an end state was reached
|
419
470
|
* if no end state was reached it saves the full input into an internal buffer
|
@@ -426,11 +477,23 @@ int esi_parser_execute( ESIParser *parser, const char *data, size_t length )
|
|
426
477
|
const char *p = data;
|
427
478
|
const char *eof = NULL; // ragel 6.x compat
|
428
479
|
const char *pe = data + length;
|
480
|
+
int pindex;
|
429
481
|
|
430
482
|
if( length == 0 ){ return cs; }
|
431
483
|
|
484
|
+
/* scan data for any '<esi:' start sequences, /<$/, /<e$/, /<es$/, /<esi$/, /<esi:$/ */
|
485
|
+
if( cs == esi_start ) {
|
486
|
+
pindex = esi_parser_scan_for_start( parser, data, length );
|
487
|
+
if( pindex == -1 ) {
|
488
|
+
for( pindex = 0; pindex < length; ++pindex ) {
|
489
|
+
esi_parser_echo_char( parser, data[pindex] );
|
490
|
+
}
|
491
|
+
return cs;
|
492
|
+
}
|
493
|
+
}
|
494
|
+
|
432
495
|
/* there's an existing overflow buffer data append the new data to the existing data */
|
433
|
-
if( parser->overflow_data && parser->overflow_data_size > 0 ){
|
496
|
+
if( parser->overflow_data && parser->overflow_data_size > 0 ) {
|
434
497
|
|
435
498
|
// recompute mark, tag_text, attr_key, and attr_value since they all exist within overflow_data
|
436
499
|
int mark_offset = compute_offset( parser->mark, parser->overflow_data );
|
@@ -456,7 +519,7 @@ int esi_parser_execute( ESIParser *parser, const char *data, size_t length )
|
|
456
519
|
|
457
520
|
}
|
458
521
|
|
459
|
-
if( !parser->mark ){
|
522
|
+
if( !parser->mark ) {
|
460
523
|
parser->mark = p;
|
461
524
|
}
|
462
525
|
|
@@ -466,7 +529,7 @@ int esi_parser_execute( ESIParser *parser, const char *data, size_t length )
|
|
466
529
|
|
467
530
|
parser->cs = cs;
|
468
531
|
|
469
|
-
if( cs != esi_start && cs != 0 ){
|
532
|
+
if( cs != esi_start && cs != 0 ) {
|
470
533
|
|
471
534
|
/* reached the end and we're not at a termination point save the buffer as overflow */
|
472
535
|
if( !parser->overflow_data ){
|
@@ -477,10 +540,16 @@ int esi_parser_execute( ESIParser *parser, const char *data, size_t length )
|
|
477
540
|
int attr_value_offset = compute_offset( parser->attr_value, data );
|
478
541
|
//debug_string( "mark before move", parser->mark, 1 );
|
479
542
|
|
480
|
-
|
543
|
+
if( ESI_OUTPUT_BUFFER_SIZE > length ) {
|
544
|
+
parser->echobuffer_allocated = ESI_OUTPUT_BUFFER_SIZE;
|
545
|
+
}
|
546
|
+
else {
|
547
|
+
parser->echobuffer_allocated = length;
|
548
|
+
}
|
549
|
+
parser->overflow_data = (char*)malloc( sizeof( char ) * parser->echobuffer_allocated );
|
481
550
|
memcpy( parser->overflow_data, data, length );
|
482
551
|
parser->overflow_data_size = length;
|
483
|
-
//
|
552
|
+
//printf( "allocate overflow data: %ld\n", parser->echobuffer_allocated );
|
484
553
|
|
485
554
|
// in our new memory space mark will now be
|
486
555
|
parser->mark = ( mark_offset >= 0 ) ? parser->overflow_data + mark_offset : NULL;
|
@@ -490,7 +559,7 @@ int esi_parser_execute( ESIParser *parser, const char *data, size_t length )
|
|
490
559
|
//if( parser->mark ){ debug_string( "mark after move", parser->mark, 1 ); } else { printf( "mark is now empty\n" ); }
|
491
560
|
}
|
492
561
|
|
493
|
-
}else if( parser->overflow_data ){
|
562
|
+
}else if( parser->overflow_data ) {
|
494
563
|
/* dump the overflow buffer execution ended at a final state */
|
495
564
|
free( parser->overflow_data );
|
496
565
|
parser->overflow_data = NULL;
|
data/ext/esi/test/sp.c
ADDED
@@ -0,0 +1,125 @@
|
|
1
|
+
/*
|
2
|
+
* This is an attempt at a custom fast parser for ESI
|
3
|
+
*
|
4
|
+
* call backs
|
5
|
+
*
|
6
|
+
* esi_output
|
7
|
+
* esi_start
|
8
|
+
* esi_end
|
9
|
+
*
|
10
|
+
*/
|
11
|
+
|
12
|
+
#include <stdio.h>
|
13
|
+
#include <stdlib.h>
|
14
|
+
#include <string.h>
|
15
|
+
|
16
|
+
typedef int (*esi_start_cb)(const char *tag_str, size_t tag_length, void *ptr);
|
17
|
+
typedef int (*esi_end_cb)(const char *tag_str, size_t tag_length, void *ptr);
|
18
|
+
typedef int (*esi_output_cb)(const char *data, size_t data_length, void *ptr);
|
19
|
+
|
20
|
+
#define ESI_BUFFER_SIZE 1024
|
21
|
+
|
22
|
+
typedef struct _ESIParser {
|
23
|
+
esi_start_cb start_cb;
|
24
|
+
esi_end_cb end_cb;
|
25
|
+
esi_output_cb output_cb;
|
26
|
+
char buffer[ESI_BUFFER_SIZE];
|
27
|
+
char tag_buffer[ESI_BUFFER_SIZE];
|
28
|
+
int tag_size;
|
29
|
+
|
30
|
+
void *callptr;
|
31
|
+
}ESIParser;
|
32
|
+
|
33
|
+
ESIParser *esi_parser_new();
|
34
|
+
void esi_parser_free( ESIParser *parser );
|
35
|
+
|
36
|
+
int esi_parser_feed( ESIParser *parser, const char *data, size_t length );
|
37
|
+
|
38
|
+
int esi_parser_finish( ESIParser *parser );
|
39
|
+
|
40
|
+
static int start_cb( const char *tag_str, size_t tag_length, void *ptr )
|
41
|
+
{
|
42
|
+
return 0;
|
43
|
+
}
|
44
|
+
static int end_cb( const char *tag_str, size_t tag_length, void *ptr )
|
45
|
+
{
|
46
|
+
return 0;
|
47
|
+
}
|
48
|
+
static int output_cb( const char *data, size_t data_length, void *ptr )
|
49
|
+
{
|
50
|
+
return 0;
|
51
|
+
}
|
52
|
+
|
53
|
+
int main( int argc, char **argv )
|
54
|
+
{
|
55
|
+
char *ptr = NULL;
|
56
|
+
const int buffer_size = 1024;
|
57
|
+
char buffer[buffer_size];
|
58
|
+
FILE *file = NULL;
|
59
|
+
ESIParser *parser = esi_parser_new();
|
60
|
+
|
61
|
+
parser->start_cb = start_cb;
|
62
|
+
parser->end_cb = end_cb;
|
63
|
+
parser->output_cb = output_cb;
|
64
|
+
|
65
|
+
file = fopen("sample.html","r");
|
66
|
+
if( !file ){ fprintf( stderr, "Failed to open sample.html\n" ); return 1; }
|
67
|
+
|
68
|
+
while( (ptr=fgets(buffer, buffer_size, file)) ) {
|
69
|
+
esi_parser_feed( parser, ptr, strlen(ptr) );
|
70
|
+
}
|
71
|
+
|
72
|
+
fclose(file);
|
73
|
+
esi_parser_free( parser );
|
74
|
+
return 0;
|
75
|
+
}
|
76
|
+
|
77
|
+
ESIParser *esi_parser_new()
|
78
|
+
{
|
79
|
+
ESIParser *parser = (ESIParser*)calloc(1,sizeof(ESIParser));
|
80
|
+
|
81
|
+
return parser;
|
82
|
+
}
|
83
|
+
void esi_parser_free( ESIParser *parser )
|
84
|
+
{
|
85
|
+
free( parser );
|
86
|
+
}
|
87
|
+
|
88
|
+
int esi_parser_feed( ESIParser *parser, const char *data, size_t length )
|
89
|
+
{
|
90
|
+
size_t i;
|
91
|
+
size_t buffered = 0;
|
92
|
+
|
93
|
+
for( i = 0; (i+4) < length ; ++i ) {
|
94
|
+
if( data[i] == '<' &&
|
95
|
+
data[i+1] == 'e' &&
|
96
|
+
data[i+2] == 's' &&
|
97
|
+
data[i+3] == 'i' &&
|
98
|
+
data[i+4] == ':' ) { // start sequence
|
99
|
+
printf("start: %ld\n", i );
|
100
|
+
}
|
101
|
+
else if( data[i] == '<' &&
|
102
|
+
data[i+1] == '/' &&
|
103
|
+
data[i+2] == 'e' &&
|
104
|
+
data[i+3] == 's' &&
|
105
|
+
data[i+4] == 'i' &&
|
106
|
+
data[i+5] == ':' ) { // end sequence
|
107
|
+
printf("end: %ld\n", i );
|
108
|
+
}
|
109
|
+
else {
|
110
|
+
parser->buffer[buffered++] = data[i];
|
111
|
+
if( buffered == ESI_BUFFER_SIZE ) {
|
112
|
+
if( parser->output_cb ) {
|
113
|
+
parser->output_cb( parser->buffer, buffered, parser->callptr );
|
114
|
+
}
|
115
|
+
buffered = 0;
|
116
|
+
}
|
117
|
+
}
|
118
|
+
}
|
119
|
+
return buffered;
|
120
|
+
}
|
121
|
+
|
122
|
+
int esi_parser_finish( ESIParser *parser )
|
123
|
+
{
|
124
|
+
return 0;
|
125
|
+
}
|
data/ext/esi/test/test.c
CHANGED
@@ -35,6 +35,23 @@ TagInfo* tag_info_new( const char *name, size_t len, ESIAttribute *attributes )
|
|
35
35
|
return ti;
|
36
36
|
}
|
37
37
|
|
38
|
+
static
|
39
|
+
void tag_info_show( TagInfo *ti )
|
40
|
+
{
|
41
|
+
ESIAttribute *attrs = ti->attributes;
|
42
|
+
if( attrs ) {
|
43
|
+
printf("%s{", ti->name );
|
44
|
+
while( attrs ) {
|
45
|
+
printf( "(%s=>%s),", attrs->name, attrs->value );
|
46
|
+
attrs = attrs->next;
|
47
|
+
}
|
48
|
+
printf("}\n");
|
49
|
+
}
|
50
|
+
else {
|
51
|
+
printf("%s\n", ti->name );
|
52
|
+
}
|
53
|
+
}
|
54
|
+
|
38
55
|
static
|
39
56
|
void tag_info_free( TagInfo *ti )
|
40
57
|
{
|
@@ -68,7 +85,7 @@ static int verify_match_string( const char *expr, const char *str_value, int lin
|
|
68
85
|
status = regexec( ®_expr, str_value, (size_t) 0, NULL, 0 );
|
69
86
|
regfree( ®_expr );
|
70
87
|
if( status != 0 ){
|
71
|
-
printf( "No matching %s expression found in '%s' at %s:%d ", expr, str_value, test_name, line );
|
88
|
+
printf( "No matching %s expression found in '%s' at %s:%d \n", expr, str_value, test_name, line );
|
72
89
|
return 1;
|
73
90
|
}
|
74
91
|
return 0;
|
@@ -181,7 +198,7 @@ static void feed_data( ESIParser *parser, const char *data )
|
|
181
198
|
#define TEST_WITH_FILE(file)\
|
182
199
|
int size = 0;\
|
183
200
|
FILE *input = NULL;\
|
184
|
-
char buffer[
|
201
|
+
char buffer[1024]; /* intentially using a small buffer size */\
|
185
202
|
TEST_INIT\
|
186
203
|
\
|
187
204
|
input = fopen( file, "r" );\
|
@@ -190,7 +207,7 @@ static void feed_data( ESIParser *parser, const char *data )
|
|
190
207
|
return;\
|
191
208
|
}\
|
192
209
|
\
|
193
|
-
while( (size = fread( buffer, sizeof(char),
|
210
|
+
while( (size = fread( buffer, sizeof(char), 1023, input )) > 0 ){\
|
194
211
|
esi_parser_execute( parser, buffer, size );\
|
195
212
|
}\
|
196
213
|
\
|
@@ -257,6 +274,36 @@ static void test_simple_parser_input( ESIParser *parser )
|
|
257
274
|
TEST_FINISH
|
258
275
|
}
|
259
276
|
|
277
|
+
static void test_small_buffer( ESIParser *parser )
|
278
|
+
{
|
279
|
+
const int input_size = 2;
|
280
|
+
const char *input = "<p>some input</p><esi:include />some more input\nsome input<esi:include timeout='10' src='hello'/>some more input";
|
281
|
+
int i, len = strlen(input);
|
282
|
+
|
283
|
+
TEST_INIT
|
284
|
+
|
285
|
+
for( i = 0; i < len; i += input_size ) {
|
286
|
+
if( i + input_size <= len ) {
|
287
|
+
esi_parser_execute( parser, (input+i), input_size );
|
288
|
+
}
|
289
|
+
else {
|
290
|
+
printf("using: %d\n", len - i );
|
291
|
+
esi_parser_execute( parser, (input+i), len - i );
|
292
|
+
}
|
293
|
+
}
|
294
|
+
|
295
|
+
TEST_PREPARE_ASSERTIONS
|
296
|
+
|
297
|
+
ASSERT_EQUAL( "<p>some input</p>some more input\nsome inputsome more input", output );
|
298
|
+
ASSERT_TRUE( start_tag_count == 2 );
|
299
|
+
ASSERT_TRUE( end_tag_count == 2 );
|
300
|
+
|
301
|
+
ASSERT_TAG_NAMES( start_tags )
|
302
|
+
ASSERT_TAG_NAMES( end_tags )
|
303
|
+
|
304
|
+
TEST_FINISH
|
305
|
+
}
|
306
|
+
|
260
307
|
static void test_chunked_input( ESIParser *parser )
|
261
308
|
{
|
262
309
|
TEST_INIT
|
@@ -313,7 +360,8 @@ static void test_sample_input( ESIParser *parser )
|
|
313
360
|
|
314
361
|
printf( "start_tag_count: %d\n", start_tag_count );
|
315
362
|
printf( "end_tag_count: %d\n", end_tag_count );
|
316
|
-
*/
|
363
|
+
*/
|
364
|
+
|
317
365
|
ASSERT_TRUE( start_tag_count == 13 );
|
318
366
|
ASSERT_TRUE( end_tag_count == 13 );
|
319
367
|
|
@@ -361,13 +409,89 @@ static void test_large_file( ESIParser *parser )
|
|
361
409
|
|
362
410
|
TEST_FINISH
|
363
411
|
}
|
364
|
-
|
365
|
-
|
412
|
+
|
413
|
+
static void test_sample1( ESIParser *parser )
|
414
|
+
{
|
415
|
+
TEST_WITH_FILE( "sample1.html" );
|
416
|
+
|
417
|
+
TEST_PREPARE_ASSERTIONS
|
418
|
+
|
419
|
+
// ASSERT_MATCH("YYY", output);
|
420
|
+
//ASSERT_NO_MATCH("failed", output );
|
421
|
+
ASSERT_NO_MATCH("<esi:", output);
|
422
|
+
ASSERT_MATCH("<html", output);
|
423
|
+
ASSERT_MATCH("</html>", output);
|
424
|
+
ASSERT_MATCH("line 1: <pre>", output);
|
425
|
+
ASSERT_MATCH("line 2: <pre>", output);
|
426
|
+
ASSERT_MATCH("line 3: <pre>", output);
|
427
|
+
ASSERT_MATCH("line 4: <pre>", output);
|
428
|
+
ASSERT_MATCH("line 5: <pre>", output);
|
429
|
+
ASSERT_MATCH("line 6: <pre>", output);
|
430
|
+
ASSERT_MATCH("line 7: <pre>", output);
|
431
|
+
ASSERT_MATCH("line 8: <pre>", output);
|
432
|
+
ASSERT_MATCH("line 9: <pre>", output);
|
433
|
+
|
434
|
+
|
435
|
+
/*
|
436
|
+
TagInfo *ptr = start_tags;
|
437
|
+
while( ptr ) {
|
438
|
+
tag_info_show( ptr );
|
439
|
+
ptr = ptr->next;
|
440
|
+
}
|
441
|
+
printf( "start_tag_count: %d\n", start_tag_count );
|
442
|
+
printf( "end_tag_count: %d\n", end_tag_count );
|
443
|
+
*/
|
444
|
+
|
445
|
+
|
446
|
+
ASSERT_TRUE( start_tag_count == 30 );
|
447
|
+
ASSERT_TRUE( end_tag_count == 30 );
|
448
|
+
|
449
|
+
ASSERT_TAG_NAMES( start_tags )
|
450
|
+
ASSERT_TAG_NAMES( end_tags )
|
451
|
+
|
452
|
+
TEST_FINISH
|
453
|
+
}
|
454
|
+
#if 0
|
455
|
+
static void test_sample1_with_chunking( ESIParser *parser )
|
456
|
+
{
|
457
|
+
TEST_WITH_FILE( "sample1.html" );
|
458
|
+
|
459
|
+
TEST_PREPARE_ASSERTIONS
|
460
|
+
|
461
|
+
// ASSERT_MATCH("YYY", output);
|
462
|
+
ASSERT_NO_MATCH("failed", output );
|
463
|
+
ASSERT_NO_MATCH("<esi:", output);
|
464
|
+
|
465
|
+
/*TagInfo *ptr = start_tags;
|
466
|
+
while( ptr ) {
|
467
|
+
tag_info_show( ptr );
|
468
|
+
ptr = ptr->next;
|
469
|
+
}
|
470
|
+
printf( "start_tag_count: %d\n", start_tag_count );
|
471
|
+
printf( "end_tag_count: %d\n", end_tag_count );
|
472
|
+
*/
|
473
|
+
|
474
|
+
ASSERT_TRUE( start_tag_count == 23 );
|
475
|
+
ASSERT_TRUE( end_tag_count == 16 );
|
476
|
+
|
477
|
+
ASSERT_TAG_NAMES( start_tags )
|
478
|
+
ASSERT_TAG_NAMES( end_tags )
|
479
|
+
|
480
|
+
TEST_FINISH
|
481
|
+
}
|
482
|
+
#endif
|
483
|
+
|
484
|
+
static void test_large_chunked_file( ESIParser *parser );
|
485
|
+
|
486
|
+
static void run_parser_through_all()
|
366
487
|
{
|
367
488
|
ESIParser *parser = esi_parser_new();
|
489
|
+
printf( "%s\n", __FUNCTION__ );
|
368
490
|
|
369
491
|
test_simple_parser_input( parser );
|
370
492
|
|
493
|
+
test_small_buffer( parser );
|
494
|
+
|
371
495
|
test_chunked_input( parser );
|
372
496
|
|
373
497
|
test_sample_input( parser );
|
@@ -376,7 +500,75 @@ int main( int argc, char **argv )
|
|
376
500
|
|
377
501
|
test_large_file( parser );
|
378
502
|
|
503
|
+
test_large_chunked_file( parser );
|
504
|
+
|
505
|
+
test_sample1( parser );
|
506
|
+
|
379
507
|
esi_parser_free( parser );
|
508
|
+
}
|
380
509
|
|
510
|
+
int main( int argc, char **argv )
|
511
|
+
{
|
512
|
+
run_parser_through_all();
|
381
513
|
return 0;
|
382
514
|
}
|
515
|
+
|
516
|
+
#define ESI_LARGE_FILE_CHUNKED "chunks.txt"
|
517
|
+
static void test_large_chunked_file( ESIParser *parser )
|
518
|
+
{
|
519
|
+
int size = 0;
|
520
|
+
FILE *input = NULL;
|
521
|
+
char *buffer = NULL;
|
522
|
+
char *chunk_start = NULL;
|
523
|
+
char *chunk_end = NULL;
|
524
|
+
char *buffer_end = NULL;
|
525
|
+
|
526
|
+
TEST_INIT
|
527
|
+
|
528
|
+
// printf( "\n" );
|
529
|
+
|
530
|
+
input = fopen( ESI_LARGE_FILE_CHUNKED, "r" );
|
531
|
+
if( !input ){
|
532
|
+
printf( "Failed to open %s\n", ESI_LARGE_FILE_CHUNKED );
|
533
|
+
return;
|
534
|
+
}
|
535
|
+
|
536
|
+
fstat( fileno(input), &st );
|
537
|
+
|
538
|
+
buffer = (char*)malloc(sizeof(char)*st.st_size);
|
539
|
+
|
540
|
+
size = fread( buffer, sizeof(char), st.st_size, input );
|
541
|
+
if( size != st.st_size ) {
|
542
|
+
printf( "Read error\n" );
|
543
|
+
return;
|
544
|
+
}
|
545
|
+
buffer_end = buffer + size;
|
546
|
+
|
547
|
+
for( chunk_start = buffer; chunk_start != buffer_end; ) {
|
548
|
+
while( *chunk_start != '{' && chunk_start != buffer_end ) { ++chunk_start; }
|
549
|
+
if( chunk_start == buffer_end ){ break; }
|
550
|
+
chunk_end = chunk_start;
|
551
|
+
while( *chunk_end != '}' && chunk_end != buffer_end ) { ++chunk_end; }
|
552
|
+
++chunk_start;
|
553
|
+
if( chunk_start > buffer_end ){ break; }
|
554
|
+
|
555
|
+
if( (chunk_end - chunk_start) > 0 ) {
|
556
|
+
esi_parser_execute( parser, chunk_start, chunk_end - chunk_start );
|
557
|
+
chunk_start = chunk_end;
|
558
|
+
}
|
559
|
+
}
|
560
|
+
|
561
|
+
fclose( input );
|
562
|
+
free( buffer );
|
563
|
+
|
564
|
+
TEST_PREPARE_ASSERTIONS
|
565
|
+
|
566
|
+
ASSERT_NO_MATCH("<esi:", output);
|
567
|
+
|
568
|
+
ASSERT_MATCH( "</html>", output );
|
569
|
+
|
570
|
+
ASSERT_TAG_NAMES( start_tags )
|
571
|
+
ASSERT_TAG_NAMES( end_tags )
|
572
|
+
|
573
|
+
TEST_FINISH
|
574
|
+
}
|