cvs commit: modperl-2.0 STATUS
stas2003/01/14 21:22:53 Modified:.STATUS Log: an issue to resolve Revision ChangesPath 1.33 +8 -1 modperl-2.0/STATUS Index: STATUS === RCS file: /home/cvs/modperl-2.0/STATUS,v retrieving revision 1.32 retrieving revision 1.33 diff -u -r1.32 -r1.33 --- STATUS11 Jan 2003 04:14:55 - 1.32 +++ STATUS15 Jan 2003 05:22:53 - 1.33 @@ -50,6 +50,13 @@ Needs Patch or Further Investigation: - +* Currently modperl_filter_add_{connection|request} check the filter + handler function attrs before accepting the filter. If the module + wasn't preloaded the check fails and filter handler is skipped. We + could have this issue documented (which is OK, but might raise too + many questions), but we could also always preload the filter + handlers. To test see TestFilter::input_msg + * we still have a problem with mod_perl starting from a vhost. consider the following config:
cvs commit: modperl-2.0/xs/tables/current/ModPerl FunctionTable.pm
stas2003/01/14 22:07:11 Modified:src/modules/perl modperl_filter.c modperl_filter.h modperl_types.h xs/tables/current/ModPerl FunctionTable.pm Log: - implementation of the input stream filtering support (1st phase) - code refactoring to be re-use for input and output filtering - proper support for mis-behaved feeding filters that send more than one EOS bucket Revision ChangesPath 1.43 +225 -66 modperl-2.0/src/modules/perl/modperl_filter.c Index: modperl_filter.c === RCS file: /home/cvs/modperl-2.0/src/modules/perl/modperl_filter.c,v retrieving revision 1.42 retrieving revision 1.43 diff -u -r1.42 -r1.43 --- modperl_filter.c 12 Jan 2003 02:21:37 - 1.42 +++ modperl_filter.c 15 Jan 2003 06:07:10 - 1.43 @@ -94,15 +94,23 @@ filter-mode = mode; filter-f = f; -filter-bb = bb; filter-pool = p; filter-wbucket.pool = p; filter-wbucket.filters = f-next; filter-wbucket.outcnt = 0; +if (mode == MP_INPUT_FILTER_MODE) { +filter-bb_in = NULL; +filter-bb_out = bb; +} +else { +filter-bb_in = bb; +filter-bb_out = NULL; +} + MP_TRACE_f(MP_FUNC, filter=0x%lx, mode=%s\n, - (unsigned long)filter, mode == MP_OUTPUT_FILTER_MODE ? - output : input); + (unsigned long)filter, + mode == MP_INPUT_FILTER_MODE ? input : output); return filter; } @@ -138,7 +146,10 @@ modperl_handler_make_args(aTHX_ args, Apache::Filter, filter-f, - APR::Brigade, filter-bb, + APR::Brigade, + (filter-mode == MP_INPUT_FILTER_MODE + ? filter-bb_out + : filter-bb_in), NULL); modperl_filter_mg_set(aTHX_ AvARRAY(args)[0], filter); @@ -168,26 +179,59 @@ filter-seen_eos = 0; } -if (filter-mode == MP_OUTPUT_FILTER_MODE) { +if (filter-mode == MP_INPUT_FILTER_MODE) { +if (filter-bb_in) { +/* in the streaming mode filter-bb_in is populated on the + * first modperl_input_filter_read, so it must be + * destroyed at the end of the filter invocation + */ +/* XXX: may be the filter must consume all the data? add a + * test to check */ +apr_brigade_destroy(filter-bb_in); +filter-bb_in = NULL; +} +modperl_input_filter_flush(filter); +} +else { modperl_output_filter_flush(filter); } + return status; } /* output filters */ -MP_INLINE static apr_status_t send_eos(ap_filter_t *f) +MP_INLINE static apr_status_t send_input_eos(modperl_filter_t *filter) +{ +apr_bucket_alloc_t *ba = filter-f-c-bucket_alloc; +apr_bucket *b = apr_bucket_eos_create(ba); +APR_BRIGADE_INSERT_TAIL(filter-bb_out, b); +((modperl_filter_ctx_t *)filter-f-ctx)-sent_eos = 1; +return APR_SUCCESS; + +} + +MP_INLINE static apr_status_t send_input_flush(modperl_filter_t *filter) +{ +apr_bucket_alloc_t *ba = filter-f-c-bucket_alloc; +apr_bucket *b = apr_bucket_flush_create(ba); +APR_BRIGADE_INSERT_TAIL(filter-bb_out, b); +return APR_SUCCESS; +} + +MP_INLINE static apr_status_t send_output_eos(ap_filter_t *f) { apr_bucket_alloc_t *ba = f-c-bucket_alloc; apr_bucket_brigade *bb = apr_brigade_create(MP_FILTER_POOL(f), ba); apr_bucket *b = apr_bucket_eos_create(ba); APR_BRIGADE_INSERT_TAIL(bb, b); +((modperl_filter_ctx_t *)f-ctx)-sent_eos = 1; return ap_pass_brigade(f-next, bb); } -MP_INLINE static apr_status_t send_flush(ap_filter_t *f) +MP_INLINE static apr_status_t send_output_flush(ap_filter_t *f) { apr_bucket_alloc_t *ba = f-c-bucket_alloc; apr_bucket_brigade *bb = apr_brigade_create(MP_FILTER_POOL(f), @@ -199,11 +243,14 @@ /* unrolled APR_BRIGADE_FOREACH loop */ +#define MP_FILTER_EMPTY(filter) \ +APR_BRIGADE_EMPTY(filter-bb_in) + #define MP_FILTER_SENTINEL(filter) \ -APR_BRIGADE_SENTINEL(filter-bb) +APR_BRIGADE_SENTINEL(filter-bb_in) #define MP_FILTER_FIRST(filter) \ -APR_BRIGADE_FIRST(filter-bb) +APR_BRIGADE_FIRST(filter-bb_in) #define MP_FILTER_NEXT(filter) \ APR_BUCKET_NEXT(filter-bucket) @@ -216,52 +263,83 @@ MP_INLINE static int get_bucket(modperl_filter_t *filter) { -if (!filter-bb) { +if (!filter-bb_in || MP_FILTER_EMPTY(filter)) { +MP_TRACE_f(MP_FUNC, %s
cvs commit: modperl-2.0/t/filter input_body.t
stas2003/01/14 22:08:16 Modified:t/filter input_body.t Log: no more need for XXX Revision ChangesPath 1.5 +0 -1 modperl-2.0/t/filter/input_body.t Index: input_body.t === RCS file: /home/cvs/modperl-2.0/t/filter/input_body.t,v retrieving revision 1.4 retrieving revision 1.5 diff -u -r1.4 -r1.5 --- input_body.t 20 Dec 2001 03:54:41 - 1.4 +++ input_body.t 15 Jan 2003 06:08:16 - 1.5 @@ -4,7 +4,6 @@ use Apache::Test; use Apache::TestRequest; -#XXX: skip input_body filter test until filter changes dust settles plan tests = 2; my $location = '/TestFilter::input_body';
cvs commit: modperl-2.0/xs/Apache/Filter Apache__Filter.h
stas2003/01/14 22:11:09 Modified:xs/Apache/Filter Apache__Filter.h Log: input filters are now supported Revision ChangesPath 1.22 +21 -8 modperl-2.0/xs/Apache/Filter/Apache__Filter.h Index: Apache__Filter.h === RCS file: /home/cvs/modperl-2.0/xs/Apache/Filter/Apache__Filter.h,v retrieving revision 1.21 retrieving revision 1.22 diff -u -r1.21 -r1.22 --- Apache__Filter.h 12 Jan 2003 02:33:27 - 1.21 +++ Apache__Filter.h 15 Jan 2003 06:11:08 - 1.22 @@ -26,7 +26,7 @@ mpxs_write_loop(modperl_output_filter_write, modperl_filter); } else { -Perl_croak(aTHX_ input filters not yet supported); +mpxs_write_loop(modperl_input_filter_write, modperl_filter); } /* XXX: ap_rflush if $| */ @@ -38,23 +38,36 @@ SV **MARK, SV **SP) { modperl_filter_t *modperl_filter; +ap_input_mode_t mode = 0; +apr_read_type_e block = 0; +apr_off_t readbytes = 0; apr_size_t wanted, len=0; SV *buffer; - -mpxs_usage_va_2(modperl_filter, buffer, $filter-read(buf, [len])); - -if (items 2) { + +if (items 4) { +mpxs_usage_va_2(modperl_filter, buffer, $filter-read(buf, [len])); +} +else { +modperl_filter = mp_xs_sv2_modperl_filter(*MARK); MARK++; +mode = (ap_input_mode_t)SvIV(*MARK); MARK++; +block = (apr_read_type_e)SvIV(*MARK); MARK++; +readbytes = (apr_off_t)SvIV(*MARK); MARK++; +buffer = *MARK++; +} + +if (items == 3 || items == 6) { wanted = SvIV(*MARK); } else { wanted = MP_IOBUFSIZE; } -if (modperl_filter-mode == MP_OUTPUT_FILTER_MODE) { -len = modperl_output_filter_read(aTHX_ modperl_filter, buffer, wanted); +if (modperl_filter-mode == MP_INPUT_FILTER_MODE) { +len = modperl_input_filter_read(aTHX_ modperl_filter, mode, +block, readbytes, buffer, wanted); } else { -Perl_croak(aTHX_ input filters not yet supported); +len = modperl_output_filter_read(aTHX_ modperl_filter, buffer, wanted); } return len;
cvs commit: modperl-2.0/t/filter/TestFilter in_bbs_body.pm in_bbs_msg.pm out_bbs_basic.pm out_bbs_ctx.pm out_str_api.pm out_str_ctx.pm out_str_lc.pm out_str_reverse.pm in_str_msg.pm api.pm buckets.pm context.pm context_stream.pm input_body.pm input_msg.pm lc.pm reverse.pm
stas2003/01/14 22:47:16 Modified:t/filter/TestFilter in_str_msg.pm Added: t/filter in_bbs_body.t in_bbs_msg.t out_bbs_basic.t out_bbs_ctx.t out_str_api.t out_str_ctx.t out_str_lc.t out_str_reverse.t t/filter/TestFilter in_bbs_body.pm in_bbs_msg.pm out_bbs_basic.pm out_bbs_ctx.pm out_str_api.pm out_str_ctx.pm out_str_lc.pm out_str_reverse.pm Removed: t/filter context.t context_stream.t input_body.t input_msg.t lc.t reverse.t t/filter/TestFilter api.pm buckets.pm context.pm context_stream.pm input_body.pm input_msg.pm lc.pm reverse.pm Log: rename filter tests so it's easy to test what kind of filter is run from its name (also to tell the streaming interface from BBs.) Revision ChangesPath 1.1 modperl-2.0/t/filter/in_bbs_body.t Index: in_bbs_body.t === use strict; use warnings FATAL = 'all'; use Apache::Test; use Apache::TestRequest; plan tests = 2; my $location = '/TestFilter::in_bbs_body'; for my $x (1,2) { my $data = scalar reverse ok $x\n; print POST_BODY $location, content = $data; } 1.1 modperl-2.0/t/filter/in_bbs_msg.t Index: in_bbs_msg.t === use Apache::TestRequest; use Apache::Test (); use Apache::TestUtil; my $module = 'TestFilter::in_bbs_msg'; Apache::TestRequest::scheme('http'); #force http for t/TEST -ssl Apache::TestRequest::module($module); my $config = Apache::Test::config(); my $hostport = Apache::TestRequest::hostport($config); t_debug(connecting to $hostport); print GET_BODY(/input_filter.html); 1.1 modperl-2.0/t/filter/out_bbs_basic.t Index: out_bbs_basic.t === # WARNING: this file is generated, do not edit # 01: /home/stas/apache.org/modperl-2.0/t/../Apache-Test/lib/Apache/TestConfig.pm:696 # 02: /home/stas/apache.org/modperl-2.0/t/../Apache-Test/lib/Apache/TestConfig.pm:713 # 03: /home/stas/apache.org/modperl-2.0/t/../Apache-Test/lib/Apache/TestConfigPerl.pm:83 # 04: /home/stas/apache.org/modperl-2.0/t/../Apache-Test/lib/Apache/TestConfigPerl.pm:407 # 05: /home/stas/apache.org/modperl-2.0/t/../Apache-Test/lib/Apache/TestConfig.pm:407 # 06: /home/stas/apache.org/modperl-2.0/t/../Apache-Test/lib/Apache/TestConfig.pm:422 # 07: /home/stas/apache.org/modperl-2.0/t/../Apache-Test/lib/Apache/TestConfig.pm:1215 # 08: /home/stas/apache.org/modperl-2.0/t/../Apache-Test/lib/Apache/TestRun.pm:398 # 09: /home/stas/apache.org/modperl-2.0/t/../Apache-Test/lib/Apache/TestRunPerl.pm:32 # 10: /home/stas/apache.org/modperl-2.0/t/../Apache-Test/lib/Apache/TestRun.pm:569 # 11: /home/stas/apache.org/modperl-2.0/t/../Apache-Test/lib/Apache/TestRun.pm:569 # 12: t/TEST:19 use Apache::TestRequest 'GET_BODY'; print GET_BODY /TestFilter::out_bbs_basic; 1.1 modperl-2.0/t/filter/out_bbs_ctx.t Index: out_bbs_ctx.t === use strict; use warnings FATAL = 'all'; use Apache::Test; use Apache::TestRequest; use Apache::TestUtil; plan tests = 1; my $blocks = 33; my $invoked = 100; my $sig = join \n, received $blocks complete blocks, filter invoked $invoked times\n; my $data = # x $blocks . x x $blocks; my $expected = join \n, $data, $sig; { # test the filtering of the mod_perl response handler my $location = '/TestFilter::out_bbs_ctx'; my $response = GET_BODY $location; ok t_cmp($expected, $response, context filter); } 1.1 modperl-2.0/t/filter/out_str_api.t Index: out_str_api.t === # WARNING: this file is generated, do not edit # 01: /home/stas/apache.org/modperl-2.0/t/../Apache-Test/lib/Apache/TestConfig.pm:696 # 02: /home/stas/apache.org/modperl-2.0/t/../Apache-Test/lib/Apache/TestConfig.pm:713 # 03: /home/stas/apache.org/modperl-2.0/t/../Apache-Test/lib/Apache/TestConfigPerl.pm:83 # 04: /home/stas/apache.org/modperl-2.0/t/../Apache-Test/lib/Apache/TestConfigPerl.pm:407 # 05: /home/stas/apache.org/modperl-2.0/t/../Apache-Test/lib/Apache/TestConfig.pm:407 # 06: /home/stas/apache.org/modperl-2.0/t/../Apache-Test/lib/Apache/TestConfig.pm:422 # 07: /home/stas/apache.org/modperl-2.0/t/../Apache-Test/lib/Apache/TestConfig.pm:1215 # 08: /home/stas/apache.org/modperl-2.0/t/../Apache-Test/lib/Apache/TestRun.pm:398 # 09: /home/stas/apache.org/modperl-2.0/t/../Apache-Test/lib/Apache/TestRunPerl.pm:32 # 10:
Replication + Load Balancing
Hi, It's interesting to hear the experience with hardware load balancers. But I'm also interested to learn how everyone synchronises (replicates) the software on their load balanced servers cron, ftp, rsync? Also does anyone have a variation on the traditional design of a single dedicated database server sitting behind a bank of web servers? The plan at Turbo10 is not to replicate everything - so only the essential information is copied onto the search servers, and stored in MySQL heap tables - this avoids extra trips to the database, and disk seeks. All transactions are first recorded in 'heap' tables (e.g., searchbucket, clickbucket) on the search nodes, then siphoned off to master tables by a dedicated database machine. Nige -- Nigel Hamilton Turbo10 Metasearch Engine email: [EMAIL PROTECTED] tel:+44 (0) 207 987 5460 fax:+44 (0) 207 987 5468 http://turbo10.com Search Deeper. Browse Faster.
Re: Load balancers
On Mon, 13 Jan 2003, John Siracusa wrote: Thanks for all the info, and please feel free to send me more, especially if there's some gem of a software load balancer out there somewhere... :) mod_accel can do primitive load balancing (via DNS) and primitive fault tolerance. It connect to next backend 1) if connect() to current backend failed; 2) if it can not get HTTP header from backend (timeout or error); 3) if it received 5XX response from backend (it can be disabled). Nevertheless it does not remember any faults to future use so I called it primitive. You can find it at http://sysoev.ru/en/ If you use DNS-based load balancing then you should install local caching DNS server on the same computer to speed up DNS queries. Igor Sysoev http://sysoev.ru/en/
Re: OSCON ideas - more talk ideas
If its not too late to weigh in with ideas: 1) A large chunk how to on doing advanced types of XML processing with perl, I'm really interested in the idea that I can serve my content to PDA's (which is the up-and-coming killer platform for my market) and in AppML (Application Markup Language) for which I can find only dribs and draps of information (a description of a toy application, an X Schema, and not much more). 2) Tutorial on persistent objects stored in MySQL, with a view to encoding business rules. 3) Implementing a toy web application using Apache::PageKit -- Christopher L. Everett Chief Technology Officer The Medical Banner Exchange Physicians Employment on the Internet
Re: mod_perl 2.0 and print/send_http_header method SEGFAULT
On Tue, Jan 14, 2003 at 12:32:29PM +1100, Stas Bekman wrote: Location /plop/ SetHandler perl-script PerlHeaderParserHandler Apache::Plop /Location Well, this is not really what I want to do ... I would like to catch all the proxy request and apply modifications to the requested document before forwarding the answer back to the client. That's why I used the PerlTransHandler which is global and not tied to a particular directory. Now to your code: 1. You can't push_handlers when you are inside a response handler. Use PerlHeaderParserHandler instead 2. $r-headers_in-do() expects a return value and will abort on 0; see the attached code also it should be: $request-header( $_[0] = $_[1] ); instead of: $request-header( {$_[0]} = $_[1] ); have you looked at error_log? You'd have seen that error reported. 3. This is not good: my $request = HTTP::Request-new( $r-method, $r-uri); since you don't the whole url. Use this instead: my $request = HTTP::Request-new( $r-method, $r-construct_url); this requires 'use Apache::URI' 4. Finally I've used a special header: (which can be anything) $request-header( GetReal = 1 ); to know that now I'm inside the real request. Thanks for your remarks. I installed modperl-1.99_08 and I keep getting SEGFAULT with my original code ... I think I'll try to get it working first on mod_perl 1.x then get back to modperl 2 --
Re: Inserting a handler in stack of handlers.
SB Geoffrey Young wrote: Ruslan U. Zakirov wrote: Hello All! Short synopsis: How to push handler just after handler that working now? More about the problem. I've got main handler, that forms stack of handlers from query string by calling push_handlers(). Then each module doing his job. Some handlers needs to put another hook just after they end thier job. I do it with direct call to SomeModule::handler($r), it works for me, but it's rude back(as i think). I've tried to do the same with push_handlers, but this function push handlers only at the end of handler's list and content appears at the bottom of page :( Any suggestion? Best regards, Ruslan. you can't really do this now I don't think. generally, the way would be to use get_handlers() to get the current chain, then use set_handlers() to set it to what you want it to be (inserting logic to splice the added handler where you want it). unfortunately, you can't call set_handlers() for the current phase, so adding another handler right after the current one runs probably isn't possible. SB That should probably be possible in 2.0, but it's not implemented yet. SB Patches are welcome. Thanks. Sorry, but I don't have time to look in mod_perl/Apache code. Good product. I think it'll be better and hope that it'll be more flexible in some cases. Thanks, Ruslan.
Re: Writing to stdin of subprocess under modperl 1.0 fails :/
Use IPC::Run instead of the IPC::Open* family, it surely works and a much more flexible tool! Thanks for advice. Tried it and it worked! -- Antti Haapala
Re: Timestamp for Apache::Upload uploads.
Matthew Hodgson wrote: Hi, I could have sworn that at some point under Apache/1.3.27 and mod_perl/1.27 I had the ability to find a timestamp of some kind for uploaded files using Apache::Upload. To be precise, I thought that: $upload = $apr-upload; $filehandle = $upload-fh; $timestamp = (stat($filehandle))[9]; I would think that would work (on unix variants, at least) the other thing you can try is (stat($upload-tempname))[9] HTH --Geoff
Re: Timestamp for Apache::Upload uploads.
Geoffrey Young wrote: Matthew Hodgson wrote: Hi, I could have sworn that at some point under Apache/1.3.27 and mod_perl/1.27 I had the ability to find a timestamp of some kind for uploaded files using Apache::Upload. To be precise, I thought that: $upload = $apr-upload; $filehandle = $upload-fh; $timestamp = (stat($filehandle))[9]; I would think that would work (on unix variants, at least) the other thing you can try is (stat($upload-tempname))[9] Thanks for the suggestion, Geoff; trying the following code snippet... my $upload = $apr-upload; my $info = $upload-info; while (my($key, $val) = each %$info) { print STDERR Upload: $key: $val\n; } print STDERR stat(\$upload-fh) = .join(,,stat($upload-fh)).\n; print STDERR stat(\$upload-tempname) = .join(,,stat($upload-tempname)).\n; ...yields... Upload: Content-Disposition: form-data; name=sa_spec_upload; filename=G:\misc\test.jpg Upload: Content-Type: image/pjpeg stat($upload-fh) = 18438,17,33152,1,487,487,0,88534,1042551991,1042551995,1042551995,4096,184 stat($upload-tempname) = 18438,17,33152,1,487,487,0,88534,1042551991,1042551995,1042551995,4096,184 i.e. the atime, mtime and ctime fields of both stat()'s all give timestamps which describe the temporary file - rather than the source file's details as it was on the client machine before being uploaded - which is what I could have sworn I once had working. (The mtime field of the local file is 1020735075). It seems that the question is less to do with mod_perl, and more to do with whether any current browsers give Last-Modified or Modification-Date or similar information in the MIME headers for multipart/form-data uploads. Whilst I had convinced myself that I'd seen this working, I'm starting to doubt my memory. Any additional help would really be appreciated; thanks, Matthew.
Re: CGI.pm
On Tue, 14 Jan 2003 [EMAIL PROTECTED] wrote: I try this simple module: #!/usr/bin/perl package My; use strict; use warnings; use Apache::RequestRec (); use Apache::RequestIO (); use Apache::RequestUtil (); use Apache::Const -compile = qw(OK); use APR::Table; use CGI; sub handler { my $r = shift; my $query=CGI-new(); print $query-param('id'); } -- and see that in error.log: [Tue Jan 14 13:59:08 2003] [error] Can't locate Apache.pm in @INC [...] What I'm doing wrong? How to parse urlecnoded? Does an upgrade of CGI.pm to the latest version help? Earlier versions aren't mod_perl 2.0 aware -- best regards, randy kobes
unsubscribe modperl
unsubscribe modperl
Re: unsubscribe modperl
Try list-unsubscribe: mailto:[EMAIL PROTECTED] At 18:11 14/01/2003, [EMAIL PROTECTED] wrote: unsubscribe modperl Lee Goddard, BA(Hons), MSc(Sussex) http://www.LeeGoddard.com/ since 1997. Director: Little Bits Ltd - Perl / Java / XML / HTML Contractors Inc. in England #4006170; VAT #755-0139-42
unsubscribe modperl
unsubscribe modperl