Changeset 506
- Timestamp:
- 08/08/2005 10:00:24 AM (3 years ago)
- Location:
- trunk
- Files:
-
- 2 added
- 11 modified
-
doc/configuration.txt (modified) (2 diffs)
-
doc/lighttpd.conf (modified) (1 diff)
-
src/.cvsignore (modified) (1 diff)
-
src/Makefile.am (modified) (4 diffs)
-
src/configfile.c (modified) (20 diffs)
-
src/configfile.h (modified) (1 diff)
-
src/configparser.y (modified) (5 diffs)
-
src/plugin.c (modified) (1 diff)
-
src/plugin.h (modified) (1 diff)
-
src/proc_open.c (added)
-
src/proc_open.h (added)
-
tests/core-var-include.t (modified) (3 diffs)
-
tests/var-include-sub.conf (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/doc/configuration.txt
r404 r506 36 36 <array> : "(" [ <string> "=>" ] <value> [, [ <string> "=>" ] <value> ]* ")" 37 37 INCLUDE : "include" VALUE 38 INCLUDE_SHELL : "include_shell" STRING_VALUE 38 39 39 40 Example … … 57 58 # include, relative to dirname of main config file 58 59 include "mime.types.conf" 60 61 # read configuration from output of a command 62 include_shell "/usr/local/bin/confmimetype /etc/mime.types" 59 63 60 64 -
trunk/doc/lighttpd.conf
r373 r506 299 299 ## same as above if you run: "lighttpd -f /etc/lighttpd/lighttpd.conf" 300 300 #include "lighttpd-inc.conf" 301 302 #### include_shell 303 #include_shell "echo var.a=1" 304 ## the above is same as: 305 #var.a=1 -
trunk/src/.cvsignore
r323 r506 10 10 .libs 11 11 array 12 proc_open 13 regex 12 14 mod_ssi_exprparser.c 13 15 mod_ssi_exprparser.h -
trunk/src/Makefile.am
r298 r506 1 noinst_PROGRAMS=array lemon # simple-fcgi #graphic evalo bench ajp ssl error_test adserver gen-license1 noinst_PROGRAMS=array proc_open lemon # simple-fcgi #graphic evalo bench ajp ssl error_test adserver gen-license 2 2 sbin_PROGRAMS=lighttpd 3 3 bin_PROGRAMS=spawn-fcgi … … 43 43 network_freebsd_sendfile.c network_writev.c \ 44 44 network_solaris_sendfilev.c network_openssl.c \ 45 network_send.c network-glue.c fdevent-glue.c 45 network_send.c network-glue.c fdevent-glue.c \ 46 proc_open.c 46 47 47 48 src = server.c response.c connections.c configfile.c configparser.c \ … … 226 227 sys-mmap.h sys-socket.h file_descr.h \ 227 228 file_cache_funcs.h file_descr_funcs.h \ 228 chunk_funcs.h 229 chunk_funcs.h proc_open.h 229 230 230 231 … … 238 239 array_CPPFLAGS= -DDEBUG_ARRAY 239 240 241 proc_open_SOURCES = proc_open.c buffer.c 242 proc_open_CPPFLAGS= -DDEBUG_PROC_OPEN 243 240 244 #gen_license_SOURCES = license.c md5.c buffer.c gen_license.c 241 245 -
trunk/src/configfile.c
r340 r506 20 20 #include "configparser.h" 21 21 #include "configfile.h" 22 #include "proc_open.h" 22 23 23 24 … … 292 293 } 293 294 #undef PATCH 295 294 296 typedef struct { 295 297 int foo; 296 298 int bar; 297 299 298 buffer *file; 299 stream s; 300 const buffer *source; 300 301 const char *input; 301 302 size_t offset; … … 309 310 int in_cond; 310 311 } tokenizer_t; 311 312 static int tokenizer_open(server *srv, tokenizer_t *t, buffer *basedir, const char *fn) {313 if (buffer_is_empty(basedir) &&314 (fn[0] == '/' || fn[0] == '\\') &&315 (fn[0] == '.' && (fn[1] == '/' || fn[1] == '\\'))) {316 t->file = buffer_init_string(fn);317 }318 else {319 t->file = buffer_init_buffer(basedir);320 buffer_append_string(t->file, fn);321 }322 323 if (0 != stream_open(&(t->s), t->file)) {324 log_error_write(srv, __FILE__, __LINE__, "sbss",325 "opening configfile ", t->file, "failed:", strerror(errno));326 buffer_free(t->file);327 return -1;328 }329 330 t->input = t->s.start;331 t->offset = 0;332 t->size = t->s.size;333 t->line = 1;334 t->line_pos = 1;335 336 t->in_key = 1;337 t->in_brace = 0;338 t->in_cond = 0;339 return 0;340 }341 342 static int tokenizer_close(server *srv, tokenizer_t *t) {343 UNUSED(srv);344 345 buffer_free(t->file);346 return stream_close(&(t->s));347 }348 312 349 313 static int config_skip_newline(tokenizer_t *t) { … … 387 351 } else { 388 352 log_error_write(srv, __FILE__, __LINE__, "sbsdsds", 389 " file:", t->file,353 "source:", t->source, 390 354 "line:", t->line, "pos:", t->line_pos, 391 355 "use => for assignments in arrays"); … … 407 371 } else { 408 372 log_error_write(srv, __FILE__, __LINE__, "sbsdsds", 409 " file:", t->file,373 "source:", t->source, 410 374 "line:", t->line, "pos:", t->line_pos, 411 375 "only =~ and == are allow in the condition"); … … 423 387 } else { 424 388 log_error_write(srv, __FILE__, __LINE__, "sbsdsds", 425 " file:", t->file,389 "source:", t->source, 426 390 "line:", t->line, "pos:", t->line_pos, 427 391 "unexpected equal-sign: ="); … … 446 410 } else { 447 411 log_error_write(srv, __FILE__, __LINE__, "sbsdsds", 448 " file:", t->file,412 "source:", t->source, 449 413 "line:", t->line, "pos:", t->line_pos, 450 414 "only !~ and != are allow in the condition"); … … 455 419 } else { 456 420 log_error_write(srv, __FILE__, __LINE__, "sbsdsds", 457 " file:", t->file,421 "source:", t->source, 458 422 "line:", t->line, "pos:", t->line_pos, 459 423 "unexpected exclamation-marks: !"); … … 545 509 546 510 log_error_write(srv, __FILE__, __LINE__, "sbsdsds", 547 " file:", t->file,511 "source:", t->source, 548 512 "line:", t->line, "pos:", t->line_pos, 549 513 "missing closing quote"); … … 588 552 buffer_copy_string(token, "+="); 589 553 tid = TK_APPEND; 590 } 591 else { 554 } else { 592 555 t->offset++; 593 556 tid = TK_PLUS; … … 650 613 /* ERROR */ 651 614 log_error_write(srv, __FILE__, __LINE__, "sbsdsds", 652 " file:", t->file,615 "source:", t->source, 653 616 "line:", t->line, "pos:", t->line_pos, 654 617 "invalid character in condition"); … … 670 633 /* ERROR */ 671 634 log_error_write(srv, __FILE__, __LINE__, "sbsdsds", 672 " file:", t->file,635 "source:", t->source, 673 636 "line:", t->line, "pos:", t->line_pos, 674 637 "unexpected EOF"); … … 676 639 return -1; 677 640 } 678 } 679 else { 641 } else { 680 642 /* the key might consist of [-.0-9a-z] */ 681 643 for (i = 0; t->input[t->offset + i] && … … 690 652 if (strcmp(token->ptr, "include") == 0) { 691 653 tid = TK_INCLUDE; 692 } 693 else if (strcmp(token->ptr, "else") == 0) { 654 } else if (strcmp(token->ptr, "include_shell") == 0) { 655 tid = TK_INCLUDE_SHELL; 656 } else if (strcmp(token->ptr, "else") == 0) { 694 657 tid = TK_ELSE; 695 } 696 else { 658 } else { 697 659 tid = TK_LKEY; 698 660 } … … 703 665 /* ERROR */ 704 666 log_error_write(srv, __FILE__, __LINE__, "sbsdsds", 705 " file:", t->file,667 "source:", t->source, 706 668 "line:", t->line, "pos:", t->line_pos, 707 669 "invalid character in variable name"); … … 717 679 #if 0 718 680 log_error_write(srv, __FILE__, __LINE__, "sbsdsdbdd", 719 " file:", t->file,681 "source:", t->source, 720 682 "line:", t->line, "pos:", t->line_pos, 721 683 token, token->used - 1, tid); … … 731 693 } 732 694 733 int config_parse_file(server *srv, config_t *context, const char *fn) { 734 tokenizer_t t; 695 static int config_parse(server *srv, config_t *context, tokenizer_t *t) { 735 696 void *pParser; 736 697 int token_id; … … 738 699 int ret; 739 700 740 if (tokenizer_open(srv, &t, context->basedir, fn) == -1) {741 return -1;742 }743 744 701 pParser = configparserAlloc( malloc ); 745 702 lasttoken = buffer_init(); 746 703 token = buffer_init(); 747 while((1 == (ret = config_tokenizer(srv, &t, &token_id, token))) && context->ok) {704 while((1 == (ret = config_tokenizer(srv, t, &token_id, token))) && context->ok) { 748 705 buffer_copy_string_buffer(lasttoken, token); 749 706 configparser(pParser, token_id, token, context); … … 765 722 log_error_write(srv, __FILE__, __LINE__, "sb", 766 723 "configfile parser failed:", lasttoken); 767 } 768 else if (context->ok == 0) { 724 } else if (context->ok == 0) { 769 725 log_error_write(srv, __FILE__, __LINE__, "sbsdsdsb", 770 " file:", t.file,771 "line:", t .line, "pos:", t.line_pos,726 "source:", t->source, 727 "line:", t->line, "pos:", t->line_pos, 772 728 "parser failed somehow near here:", lasttoken); 773 729 ret = -1; … … 775 731 buffer_free(lasttoken); 776 732 777 tokenizer_close(srv, &t);778 733 return ret == -1 ? -1 : 0; 734 } 735 736 static int tokenizer_init(tokenizer_t *t, const buffer *source, const char *input, size_t size) { 737 738 t->source = source; 739 t->input = input; 740 t->size = size; 741 t->offset = 0; 742 t->line = 1; 743 t->line_pos = 1; 744 745 t->in_key = 1; 746 t->in_brace = 0; 747 t->in_cond = 0; 748 return 0; 749 } 750 751 int config_parse_file(server *srv, config_t *context, const char *fn) { 752 tokenizer_t t; 753 stream s; 754 int ret; 755 buffer *filename; 756 757 if (buffer_is_empty(context->basedir) && 758 (fn[0] == '/' || fn[0] == '\\') && 759 (fn[0] == '.' && (fn[1] == '/' || fn[1] == '\\'))) { 760 filename = buffer_init_string(fn); 761 } else { 762 filename = buffer_init_buffer(context->basedir); 763 buffer_append_string(filename, fn); 764 } 765 766 if (0 != stream_open(&s, filename)) { 767 log_error_write(srv, __FILE__, __LINE__, "sbss", 768 "opening configfile ", filename, "failed:", strerror(errno)); 769 ret = -1; 770 } else { 771 tokenizer_init(&t, filename, s.start, s.size); 772 ret = config_parse(srv, context, &t); 773 } 774 775 stream_close(&s); 776 buffer_free(filename); 777 return ret; 778 } 779 780 int config_parse_cmd(server *srv, config_t *context, const char *cmd) { 781 proc_handler_t proc; 782 tokenizer_t t; 783 int ret; 784 buffer *source; 785 buffer *out; 786 char oldpwd[PATH_MAX]; 787 788 if (NULL == getcwd(oldpwd, sizeof(oldpwd))) { 789 log_error_write(srv, __FILE__, __LINE__, "s", 790 "cannot get cwd", strerror(errno)); 791 return -1; 792 } 793 794 source = buffer_init_string(cmd); 795 out = buffer_init(); 796 797 if (!buffer_is_empty(context->basedir)) { 798 chdir(context->basedir->ptr); 799 } 800 801 if (0 != proc_open_buffer(&proc, cmd, NULL, out, NULL)) { 802 log_error_write(srv, __FILE__, __LINE__, "sbss", 803 "opening", source, "failed:", strerror(errno)); 804 ret = -1; 805 } else { 806 tokenizer_init(&t, source, out->ptr, out->used); 807 ret = config_parse(srv, context, &t); 808 } 809 810 buffer_free(source); 811 buffer_free(out); 812 chdir(oldpwd); 813 return ret; 779 814 } 780 815 -
trunk/src/configfile.h
r307 r506 19 19 void configparser(void *yyp, int yymajor, buffer *yyminor, config_t *ctx); 20 20 int config_parse_file(server *srv, config_t *context, const char *fn); 21 int config_parse_cmd(server *srv, config_t *context, const char *cmd); 21 22 22 23 #endif -
trunk/src/configparser.y
r420 r506 132 132 metaline ::= condlines(A) EOL. { A = NULL; } 133 133 metaline ::= include. 134 metaline ::= include_shell. 134 135 metaline ::= EOL. 135 136 … … 142 143 %type array {array *} 143 144 %type key {buffer *} 145 %type stringop {buffer *} 144 146 145 147 %type cond {config_cond_t } … … 151 153 %destructor array { array_free($$); } 152 154 %destructor key { buffer_free($$); } 155 %destructor stringop { buffer_free($$); } 153 156 154 157 %token_type {buffer *} … … 346 349 default: 347 350 assert(0); 348 break;351 return; 349 352 } 350 353 … … 469 472 } 470 473 471 include ::= INCLUDE expression(A). { 474 stringop(A) ::= expression(B). { 475 A = NULL; 472 476 if (ctx->ok) { 473 if ( A->type != TYPE_STRING) {474 fprintf(stderr, " filemust be string");477 if (B->type != TYPE_STRING) { 478 fprintf(stderr, "operand must be string"); 475 479 ctx->ok = 0; 476 480 } else { 477 buffer *file = ((data_string*)A)->value; 478 if (0 != config_parse_file(ctx->srv, ctx, file->ptr)) { 479 ctx->ok = 0; 480 } 481 } 482 } 483 A->free(A); 484 A = NULL; 485 } 481 A = buffer_init_buffer(((data_string*)B)->value); 482 } 483 } 484 B->free(B); 485 B = NULL; 486 } 487 488 include ::= INCLUDE stringop(A). { 489 if (ctx->ok) { 490 if (0 != config_parse_file(ctx->srv, ctx, A->ptr)) { 491 ctx->ok = 0; 492 } 493 buffer_free(A); 494 A = NULL; 495 } 496 } 497 498 include_shell ::= INCLUDE_SHELL stringop(A). { 499 if (ctx->ok) { 500 if (0 != config_parse_cmd(ctx->srv, ctx, A->ptr)) { 501 ctx->ok = 0; 502 } 503 buffer_free(A); 504 A = NULL; 505 } 506 } -
trunk/src/plugin.c
r284 r506 62 62 if (p->name) buffer_free(p->name); 63 63 #ifdef HAVE_VALGRIND_VALGRIND_H 64 if (RUNNING_ON_VALGRIND) use_dlclose = 0;64 /*if (RUNNING_ON_VALGRIND) use_dlclose = 0;*/ 65 65 #endif 66 66 -
trunk/src/plugin.h
r339 r506 88 88 int config_patch_connection(server *srv, connection *con, comp_key_t comp); 89 89 int config_check_cond(server *srv, connection *con, data_config *dc); 90 int config_append_cond_match_buffer(connection *con, data_config *dc, buffer *buf, int n); 90 91 91 92 #endif -
trunk/tests/core-var-include.t
r341 r506 3 3 use strict; 4 4 use IO::Socket; 5 use Test::More tests => 1 5;5 use Test::More tests => 16; 6 6 7 7 my $basedir = (defined $ENV{'top_builddir'} ? $ENV{'top_builddir'} : '..'); … … 194 194 @request = ( "GET /index.html HTTP/1.0\r\nHost: www.example.org\r\n" ); 195 195 @response = ( { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 301, 'Location' => "/redirect" } ); 196 skip "redirect is not working as expected", 1 2if handle_http != 0;196 skip "redirect is not working as expected", 13 if handle_http != 0; 197 197 my $myvar = "good"; 198 198 my $server_name = "test.example.org"; … … 213 213 "array_append" => "/good_array_append", 214 214 "string_append" => "/good_" . $mystr, 215 "number_append" => "/good_" . "2" 215 "number_append" => "/good_" . "2", 216 217 "include_shell" => "/good_include_shell_" . "456" 216 218 }; 217 219 foreach my $test (keys %{ $tests }) { -
trunk/tests/var-include-sub.conf
r341 r506 26 26 "^/number_append$" => "/good_" + one, 27 27 ) 28 29 cmd = "echo cmd_ok=456" 30 include_shell cmd 31 url.redirect += ( 32 "^/include_shell$" => "/good_include_shell_" + cmd_ok, 33 ) 28 34 }

