Re: httpd-2.x servertype inetd

2005-08-09 Thread Jan Kratochvil
Hi,

standalone running and only occasionally used server for testing is a bit
costly for me and as suggested by Nick Kew its inetd-spawning each time during
a testing session would be possibly even worse than the former case.

Just FYI attached 'caching' method by xinetd(8) handled connections forwarding
with on-demand server spawning and crond(8) handled idle server shutdowns.
(C used to avoid for this trivia task as any scripting language interpreters
startup is not wised in possibly server overloaded conditions.)


Regards,
Lace


On Fri, 05 Aug 2005 17:20:10 +0900, Nick Kew wrote:
...
> Apache's high startup cost is self-reinforcing.  We know it's a once-only
> thing,
...
On Fri, 05 Aug 2005 17:39:02 +0900, Jan Kratochvil wrote:
...
> External people with mobile devices should be able to use 'production' or
> 'testing' server. The 'testing' server will not be used in common case, 
> though.
> Machine is unfortunately low on memory and currently this unused 'testing'
> server eats 25844KB of memory (free(1),kill(1),free(1),subtract w/o buffers,
> running minimal set - 1 listen httpd, 2 children httpd; mod_perl in use).
...
service httpd-stage-perl-xinetd
{
disable = no
port= 82
type= UNLISTED
socket_type = stream
protocol= tcp
wait= no
user= root
server  = /root/src/inetdmx
server_args = --start --start-command-timeout 60 --lock 
/var/lock/httpd-stage-perl-inetdmx.lock --syslog --port 83 
/etc/init.d/httpd-stage-perl start;true
}
#! /bin/bash
# See also: /etc/xinetd.d/httpd-stage-perl-xinetd
exec /root/src/inetdmx --stop \
--idle-server-timeout $[30*60] \
--lock /var/lock/httpd-stage-perl-inetdmx.lock \
--syslog \
/etc/init.d/httpd-stage-perl stop
/*
 * $Id: inetdmx.c,v 1.7 2005/08/09 11:08:12 short Exp $ */
 * Latest:
 *  
http://cvs.jankratochvil.net/viewcvs/*checkout*/nethome/src/inetdmx.c?rev=HEAD
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; you must use version 2 of the License.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */


#define _GNU_SOURCE 1
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 


#define CONNECT_RETRY_MSEC 100
#define DEFAULT_START_COMMAND_TIMEOUT 60
#define DEFAULT_IDLE_SERVER_TIMEOUT (90*60)
#define FLOCK_TIMEOUT_OVER_START_TIMEOUT 2
#define SESSION_BUFFER_SIZE 0x1000
#define SYSTEM_CHECKED_BUFFER_SIZE_MIN 0x1000
#define SYSTEM_CHECKED_BUFFER_SIZE (LINE_MAX > SYSTEM_CHECKED_BUFFER_SIZE_MIN ? 
LINE_MAX : SYSTEM_CHECKED_BUFFER_SIZE_MIN)


/* /usr/include/glib-2.0/glib/gmacros.h */
#ifndef G_GNUC_PRINTF
#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ > 4)
#define G_GNUC_PRINTF( format_idx, arg_idx )\
  __attribute__((__format__ (__printf__, format_idx, arg_idx)))
#else   /* !__GNUC__ */
#define G_GNUC_PRINTF( format_idx, arg_idx )
#endif  /* !__GNUC__ */
#endif /* !G_GNUC_PRINTF */

/* /usr/include/glib-2.0/glib/gmacros.h */
#ifndef G_GNUC_NORETURN
#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ > 4)
#define G_GNUC_NORETURN \
  __attribute__((__noreturn__))
#else   /* !__GNUC__ */
#define G_GNUC_NORETURN
#endif  /* !__GNUC__ */
#endif /* !G_GNUC_NORETURN */

/* /usr/include/glib-2.0/glib/gmacros.h */
/* Count the number of elements in an array. The array must be defined
 * as such; using this with a dynamically allocated array will give
 * incorrect results.
 */
#define G_N_ELEMENTS(arr)   (sizeof (arr) / sizeof ((arr)[0]))


static const char *program_name;

static int opt_start;
static int opt_stop;
static long opt_start_command_timeout=DEFAULT_START_COMMAND_TIMEOUT;
static long opt_idle_server_timeout=DEFAULT_IDLE_SERVER_TIMEOUT;
static int opt_port;
static int opt_syslog;
static int opt_stderr;
static const char *opt_lock;
static int opt_ignore_spawned_command_output;
static char *opt_command;


static void fatal(const char *fmt,...) G_GNUC_PRINTF(1,2) G_GNUC_NORETURN;

/* for atexit(3) function */
static int verror_quiet;

static void verror(const c

Re: httpd-2.x servertype inetd

2005-08-05 Thread Jan Kratochvil
Hi Nick,

On Fri, 05 Aug 2005 17:20:10 +0900, Nick Kew wrote:
> Jan Kratochvil wrote:
> > Hi,
> > 
> > is there still no httpd-1.3 "servertype inetd" style MPM for httpd-2.x?
> > 
> > It would be useful for low-cost "config-reloading" testing/staging daemon.
> 
> In what sense low-cost?

External people with mobile devices should be able to use 'production' or
'testing' server. The 'testing' server will not be used in common case, though.
Machine is unfortunately low on memory and currently this unused 'testing'
server eats 25844KB of memory (free(1),kill(1),free(1),subtract w/o buffers,
running minimal set - 1 listen httpd, 2 children httpd; mod_perl in use).


> Apache's high startup cost is self-reinforcing.  We know it's a once-only
> thing, so we have every module do expensive things at startup rather than
> per-request.  I don't see how inetd would affect that.

I care primarily of the not-in-use case. 'testing' server can get swapped out
but Linux kernel does not swap out inactive processes too much actively.

...
> > Do you see it as a separate MPM or some option to prefork.c would be enough?
> > There is already the "-X"/"DEBUG" hack.
> 
> Well, in principle I guess it could be an MPM.

It could be MPM but it could be also patch for prefork.c.
Asking what would get accepted to not to later have to code it second time.

 * patch con: Increased prefork.c conditions-complexity a bit.
 * MPM   con: Mostly duplicite code with prefork.c.
 * MPM   con: Increased codebase.


Thanks for reply,
Lace



httpd-2.x servertype inetd

2005-08-04 Thread Jan Kratochvil
Hi,

is there still no httpd-1.3 "servertype inetd" style MPM for httpd-2.x?

It would be useful for low-cost "config-reloading" testing/staging daemon.

Do you see it as a separate MPM or some option to prefork.c would be enough?
There is already the "-X"/"DEBUG" hack.


Regards,
Lace


Re: C-L or T-E: chunked for proxied request bodies

2004-12-30 Thread Jan Kratochvil
Hi,

On Thu, 30 Dec 2004 19:54:05 +0100, Jeff Trawick wrote:
> On Thu, 30 Dec 2004 18:47:48 +0100, Jan Kratochvil
> <[EMAIL PROTECTED]> wrote:
...
> An interesting issue is that what is in 2.0 now is optimal when it
> works, and it works in a common real-world scenario (client sends C-L
> and no filters modify the request body size).

Sorry for chatting without code sample etc.

* If no active filters are detected after headers parsing pass the
  single request unchanged through this connection by its C-L despite
  its possible "keepalive".
* Use currently 2.1-implemented C-E "chunked" as fallback.

Will there really remain no active filters in the common case?
At least ap_byterange_filter() gives up but chunk_filter() never does.
Is it possible to patch such filters? It would be performance wise. :-)


Regards,
Lace


Re: C-L or T-E: chunked for proxied request bodies

2004-12-30 Thread Jan Kratochvil
Hi Jeff,

On Thu, 30 Dec 2004 14:05:30 +0100, Jeff Trawick wrote:
> On 29 Dec 2004 20:39:47 -, [EMAIL PROTECTED] <[EMAIL PROTECTED]> wrote:
...
> Any agreement to use the non-DOS-able and protocol-compliant
> implementation by default, and allow the C-L method to be enabled by a
> special setting?

Is it going to be backported to 2.0 or it waits for 2.2?


Thanks,
Lace


Re: Showstopper for 1.3.33

2004-10-27 Thread Jan Kratochvil
On Wed, 27 Oct 2004 11:38:14 +0200, Joe Orton wrote:
> On Wed, Oct 27, 2004 at 11:11:44AM +0200, Jan Kratochvil wrote:
...
> > http://issues.apache.org/bugzilla/show_bug.cgi?id=14518
...
> > The patch during testing appears to me as inappropriate for 1.3.x; backout
> > is IMO appropriate.
> > The patch was right for 2.0.x (hopefully the backport to 1.3.x is not mine...).
> 
> Why do you think it's appropriate for 2.0.x?  The patch also breaks [P]
> with a query string in 2.0.x; at least in configurations which work
> working fine previously by my testing.

In such case going to more thoroughly test the 2.0.x behavior. It fixed
my mod_rewrite+mod_proxy case of use shown in my Bug comment 2004-10-25 00:52.

I think the real bug is in proxy_http_canon() and mod_rewrite() is just
a workaround of it. Unfortunately I am not sure what are the right inputs and
outputs of proxy_http_canon().


Regards,
Lace


Re: Showstopper for 1.3.33

2004-10-27 Thread Jan Kratochvil
Hi,

On Tue, 26 Oct 2004 14:13:08 +0200, Jim Jagielski wrote:
> There is currently one showstopper holding up release of 1.3.33.

http://issues.apache.org/bugzilla/show_bug.cgi?id=14518

> It has 2 votes for and none against, and it's for backing out
> a patch recently applied in mod_rewrite...

The patch during testing appears to me as inappropriate for 1.3.x; backout
is IMO appropriate.
The patch was right for 2.0.x (hopefully the backport to 1.3.x is not mine...).


Still it is just a test by heuristics as I cannot check the code itself.
I am clueless what is the expected value of URI-parsing fields of
"struct request_rec":
unparsed_uri, uri, filename, canonical_filename, path_info, args, parsed_uri.

All these items I consider undocumented - both in 1.3 and in 2.1 trees
(comments in 2.1 are still very ambiguous - URI examples would be perfect).

Unfortunately this behavior is pretty hot for modules compatibility.
What about cleaning it out before 2.2?
Signature of proxy_http_canon() looks broken to me:
 * Its "url" argument type is undocumented as in the cases above.
 * Argument "url" relation to "r" is also undocumented.
 * The function modified its "url" argument content - IMO a bit unusual.
 * The 'r->uri == r->unparsed_uri' code path condition looks unclear to me,
   there should be at least macro for such condition defined around
   "struct request_rec".

I would not say anything regarding undocumented URL code/structures if these
URL parsing issues would be handled fine by the code aware httpd coders;
unfortunately they look to have the same problems as httpd newbie like me.


Regards,
Lace


[patch] mod_rewrite args + "qsa"

2004-08-28 Thread Jan Kratochvil
Hi,

Two mod_rewrite patches:

attached "httpd-2.0.50-rewrite-args.patch" will no longer omit $QUERY_STRINGs
of [P]-proxypassed requests after their rewriting and [QSA] possibly merging
a new QUERY_STRING.
.conf:
ServerName 10.10.145.100
RewriteEngine on
RewriteRule ^/ http://mms2.org/mms-off?operator=oskarmobil.cz [QSA,P]
Before patch:
213.220.235.217 - - [27/Aug/2004:11:45:59 +0200] "GET 
http://10.10.145.100/?message-id=8326039 HTTP/1.0" 500 659
195.122.208.84 - - [27/Aug/2004:11:45:59 +0200] "GET /mms-off HTTP/1.1" 500 659
(2) init rewrite engine with requested uri /
(3) applying pattern '^/' to uri '/'
(2) rewrite '/' -> 'http://mms2.org/mms-off?operator=t-mobile.cz'
(3) split uri=http://mms2.org/mms-off?operator=t-mobile.cz -> 
uri=http://mms2.org/mms-off, args=operator=t-mobile.cz&message-id=8326039
(2) forcing proxy-throughput with http://mms2.org/mms-off
(1) go-ahead with proxy request proxy:http://mms2.org/mms-off [OK]

After patch:
213.220.235.217 - - [27/Aug/2004:13:52:20 +0200] "GET 
http://10.10.145.100/?message-id=8326039 HTTP/1.0" 200 221
195.122.208.84 - - [27/Aug/2004:13:52:20 +0200] "GET 
/mms-off?operator=oskarmobil.cz&message-id=8326039 HTTP/1.1" 200 221
(2) init rewrite engine with requested uri /
(3) applying pattern '^/' to uri '/'
(2) rewrite '/' -> 'http://mms2.org/mms-off?operator=oskarmobil.cz'
(3) split uri=http://mms2.org/mms-off?operator=oskarmobil.cz -> 
uri=http://mms2.org/mms-off, args=operator=oskarmobil.cz&message-id=8326039
(2) forcing proxy-throughput with http://mms2.org/mms-off
(1) go-ahead with proxy request 
proxy:http://mms2.org/mms-off?operator=oskarmobil.cz&message-id=8326039 [OK]

The fix just follows the suggested /* see proxy_http:proxy_http_canon() */.
Patch applies both to httpd-2.0.50 and httpd-2.1 CVS.


The other patch - attached "mod_rewrite-qsa.patch" is just a fatal typo in the
current httpd-2.1 CVS.


Regards,
Lace

-- 
Jan Kratochvil; Captive: free r/w NTFS Filesystem; http://www.jankratochvil.net/
Index: modules/mappers/mod_rewrite.c
===
RCS file: /home/cvspublic/httpd-2.0/modules/mappers/mod_rewrite.c,v
retrieving revision 1.257
diff -u -p -r1.257 mod_rewrite.c
--- modules/mappers/mod_rewrite.c   17 May 2004 23:36:15 -  1.257
+++ modules/mappers/mod_rewrite.c   27 Aug 2004 11:27:01 -
@@ -4274,7 +4274,7 @@ static int hook_uri2file(request_rec *r)
   r->path_info, NULL);
 }
 if (r->args != NULL &&
-r->uri == r->unparsed_uri) {
+r->uri != r->unparsed_uri) {
 /* see proxy_http:proxy_http_canon() */
 r->filename = apr_pstrcat(r->pool, r->filename,
   "?", r->args, NULL);
Index: modules/mappers/mod_rewrite.c
===
RCS file: /home/cvspublic/httpd-2.0/modules/mappers/mod_rewrite.c,v
retrieving revision 1.257
diff -u -p -r1.257 mod_rewrite.c
--- modules/mappers/mod_rewrite.c   17 May 2004 23:36:15 -  1.257
+++ modules/mappers/mod_rewrite.c   27 Aug 2004 11:27:01 -
@@ -3293,8 +3293,8 @@ static const char *cmd_rewriterule_setfl
 
 case 'q':
 case 'Q':
-if (   !strcasecmp(key, "QSA")
-|| !strcasecmp(key, "qsappend")) { /* qsappend */
+if (   !strcasecmp(key, "SA")
+|| !strcasecmp(key, "sappend")) { /* qsappend */
 cfg->flags |= RULEFLAG_QSAPPEND;
 }
 else {


Re: POST without Content-Length

2004-08-07 Thread Jan Kratochvil
Hi,

On Sun, 08 Aug 2004 00:07:24 +0200, Roy T. Fielding wrote:
...
> An HTTP request with no content-length and no tranfer-encoding has no body,
> period:

OK. Now just a question whether to not to implement HTTP-request sanity check
as is implemented in squid clientCheckContentLength():

PUT+POST:
require a request entity: HTTP_LENGTH_REQUIRED = 411
GET+HEAD:
forbid a request entity if !$request_entities: HTTP_LENGTH_REQUIRED = 
411

configurable $request_entities:
allow GET/HEAD requests with request entities, even if such
entites are "undefined" in the HTTP specification.

Unfortunately there is no HTTP specification which methods
MUST/MUST NOT/etc. (RFC 2119) include HTTP request bodies.


Lace

-- 
Jan Kratochvil; Captive: free r/w NTFS Filesystem; http://www.jankratochvil.net/


Re: POST without Content-Length

2004-08-07 Thread Jan Kratochvil
Hi,

On Sun, 08 Aug 2004 00:24:15 +0200, Nick Kew wrote:
...
> > Therefore it should be safe to assume if no Content-Length and no "chunked"
> > headers are present there MUST follow an optional body with the
> > connection-close afterwards as 'persistent connection' MUST NOT be present.
> 
> Nope.  GET requests routinely have keep-alive, but don't have bodies.

Just FYI squid-3.0 release notes:
request_entities
New squid.conf directive "request_entities on/off".If set to
"on" then Squid will allow GET/HEAD requests with request
entities, even if such entites are "undefined" in the HTTP
specification. (Henrik Nordstrom)

Anyway I have no longer standards compliance complaints as httpd-2.1 looks OK:

On Sun, 08 Aug 2004 00:07:24 +0200, Roy T. Fielding wrote:
...
> An HTTP request with no content-length and no tranfer-encoding has no body,
> period:
> 
>The presence of a message-body in a request is signaled by the
>inclusion of a Content-Length or Transfer-Encoding header field in
>    the request's message-headers.


Oops, with the greatest regards to RFC author :-),
Lace

-- 
Jan Kratochvil; Captive: free r/w NTFS Filesystem; http://www.jankratochvil.net/


Re: POST without Content-Length

2004-08-07 Thread Jan Kratochvil
Hi,

On Sun, 08 Aug 2004 00:50:13 +0200, Roy T. Fielding wrote:
> > On the contrary!  I myself have done a great deal of work on a proxy
> > for mobile devices, for a household-name Client.  The client software
> > makes certain assumptions of the proxy that would not be valid on the
> > Web at large.  But the backend *is* the web at large.
> 
> But then the client is either using non-standard HTML forms or
> non-standard HTTP, neither of which is our concern.

This whole thread started due to a commercial GSM mobile phone:
User-Agent: SonyEricssonP900/R102 Profile/MIDP-2.0 Configuration/CLDC-1.0 
Rev/MR4

, it sends HTTP/1.1 "chunked" requests to its HTTP proxy although you will
access general web sites. The "chunked" body is apparently created on the fly,
each "chunk" as a specific body element generated by a part of P900 code.


Lace

-- 
Jan Kratochvil; Captive: free r/w NTFS Filesystem; http://www.jankratochvil.net/


Re: POST without Content-Length

2004-08-07 Thread Jan Kratochvil
On Sat, 07 Aug 2004 21:38:19 +0200, Nick Kew wrote:
> On Sat, 7 Aug 2004, Jan Kratochvil wrote:
...
> > Current CVS snapshot I Bugzilled them as
> > https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=129391
> >
> > FYI backport of current mod_proxy is technically trivia - just copying raw
> > mod_proxy.c
> > mod_proxy.h
> > proxy_http.c
> 
> It would also need proxy_util.c.  Not sure about ftp or connect.

It is not about "would" - it WORKS4ME fine with just those 3 files in the
Bugzilla post above.

...
> Maybe we should infer a body (and hence apply the above logic) in any
> POST or PUT request?  If we do that, it begs the question of how to treat
> unknown HTTP/extension methods (cf DAV), and suggests perhaps
> RequireRequestBody should be made a configuration directive.

What would happen in this case httpd would infer a body while no body would be
found there?
 * In the case of a 'connection close' nothing, empty body would be found.
 * In the case of a 'persistent connection':
   * RFC2616 section 8.1.2.1:
   In order to remain persistent, all messages on the connection MUST
   have a self-defined message length (i.e., one not defined by closure
   of the connection), as described in section 4.4.
 Therefore 'persistent connection' is not allowed in this case.

Therefore it should be safe to assume if no Content-Length and no "chunked"
headers are present there MUST follow an optional body with the
connection-close afterwards as 'persistent connection' MUST NOT be present.


Regards,
Lace

-- 
Jan Kratochvil; Captive: free r/w NTFS Filesystem; http://www.jankratochvil.net/


Re: POST without Content-Length

2004-08-07 Thread Jan Kratochvil
Hi,

On Sat, 07 Aug 2004 09:35:40 +0200, Justin Erenkrantz wrote:
...
> At this date (about 20 months later), I have no earthly idea what was 
> wrong.  But, I'd suggest trying httpd-2.0 HEAD (aka httpd-2.1) and see if 
> that fixes it.

Thanks for the great support - httpd-2.0 HEAD 2004-08-07 really fixes it.
It even provides env variable "proxy-sendchunks" to select between compatible
"Content-Length" (default) and performance-wise "chunked".


On Sat, 07 Aug 2004 19:14:37 +0200, Nick Kew wrote:
> On Sat, 7 Aug 2004, Justin Erenkrantz wrote:
> 
> > That's a slightly different story.  2.1 has the fix for this (proxy_http.c
> > r1.166), but it never got back ported to 2.0.
> 
> We have a lot of proxy updates in 2.1, which are presumably getting
> test-driven over time.  How would one go about proposing a wholesale
> backport?

FYI Fedora Core 2 httpd already backports httpd-2.1 version of proxy_http.c
although it was not so new snapshot to include resolving of my issues.
Current CVS snapshot I Bugzilled them as
https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=129391

FYI backport of current mod_proxy is technically trivia - just copying raw
mod_proxy.c
mod_proxy.h
proxy_http.c

although it brings new domain-remapping functionality there.

...
> This is basically the same as an output filter changing the
> content-length.  In the 2.0 architecture, the filter must take
> responsibility for not sending a bogus length.  The only difference
> is that Connection: close is an option in output.

Although the proxy is OK now there still remains one problem:

I think HTTP server MUST accept the request:
POST ... HTTP/1.0 or HTTP/1.1
[ no Content-Length ]
[ no Transfer-Encoding ]
Connection: close [ or even no Connection header at all]
\r\n
DATA

according to RFC2616 section 4.4. Even httpd-2.1/CVS just assumes empty body.
squid up to squid/2.5.STABLE5 at least responds by "411 Length Required".


Regards,
Lace

-- 
Jan Kratochvil; Captive: free r/w NTFS Filesystem; http://www.jankratochvil.net/


Re: POST without Content-Length

2004-08-07 Thread Jan Kratochvil
On Sat, 07 Aug 2004 09:06:18 +0200, Justin Erenkrantz wrote:
...
> Um, Apache HTTP Server 2.0 (and higher) certainly reads chunked input.  Our 
> httpd-test perl-framework explicitly checks for this behavior.  -- justin

Oops, OK, my mistake during summarizing the bugreport today.
That request in the previous mail is OK as it is yet "chunked" encoded.

Unfortunately httpd proxy will forward it de"chunked" although it will not
fill-in any "Content-Length". httpd is no longer to handle it on its input
afterwards.
The sniffed forwarded request is at:
http://www.jankratochvil.net/priv/SonyEricssonP900-forwarded.HTTPrequest.gz

(tested in Red Hat Fedora Core 2 httpd-2.0.50-2.1)


Thanks,
Lace

-- 
Jan Kratochvil; Captive: free r/w NTFS Filesystem; http://www.jankratochvil.net/


POST without Content-Length

2004-08-06 Thread Jan Kratochvil
Hi,

according to RFC2616 (HTTP/1.1) section 4.4 it is valid to do POST method
without specifying Content-Length. Mobile phone SonyEricsson P900 sends such
requests to its specified WAP proxy (behaving in HTTP way - I assume a bug):
http://www.jankratochvil.net/priv/SonyEricssonP900.HTTPrequest.gz

Unfortunately no httpd/apache or squid versions support such requests.
* httpd assumes no body at all and tries to interpret the message body as
  another HTTP request.
* squid complains with 411 (length required)

I tried to workaround it by the attached mod_perl input handler but it has some
issues. I expect httpd C core should be fixed instead. Will be the patch
accepted? Is anyone willing to patch it? :-)


Regards,
Lace

-- 
Jan Kratochvil; Captive: free r/w NTFS Filesystem; http://www.jankratochvil.net/
# $Id: ApacheInputFilterAddContentLength.pm,v 1.3 2004/08/07 06:48:02 short Exp $

package MMS2::ApacheInputFilterAddContentLength;
use strict;
use warnings;

use base qw(Apache::Filter);

use APR::Brigade ();
use APR::Bucket ();
use Apache::Const;
use APR::Const;
#use Data::Dumper;


# Do not:
# as it will read the input line-by-line [check/FIXME:] with stucking at the end.
#sub handler:FilterConnectionHandler
#{
#my($f)[EMAIL PROTECTED];
#
#warn "in";
#my $buf;
#while ($f->read($buf,0x1000)) {
#warn $buf;
#$f->print($buf);
#}
#Apache::OK;
#}


sub handler:FilterConnectionHandler
{
my($f,$bb,$mode,$block,$readbytes)[EMAIL PROTECTED];

my $ctx=$f->ctx();
$ctx->{"data"}="" if !exists $ctx->{"data"};

my $got;
if (!$ctx->{"done"}) {
$ctx->{"done"}=1;

# Prevent calling &get_brigade for the second time as it would get 
stuck.
#   my $rv=$f->next->get_brigade($bb,$mode,$block,$readbytes);
my 
$rv=$f->next->get_brigade($bb,Apache::MODE_READBYTES,APR::BLOCK_READ,0x100);
return $rv if $rv!=APR::SUCCESS;

# Do not: $bb->flatten($data)
# as &flatten is from mod_perl-1.99_13 while Fedora Core 2 has 
mod_perl-1.99_12.
for (my $b=$bb->first;$b;$b=$bb->next($b)) {
my $data;
$b->read($data);
$ctx->{"data"}.=$data if length $data;
$b->remove();
}
# Do not: $bb->cleanup();
# as &cleanup is from mod_perl-1.99_15 while Fedora Core 2 has 
mod_perl-1.99_12.

if ($ctx->{"data"}=~/^(.*?\r\n)\r\n(.*)$/s) {
my($headers,$body)=($1,$2);
$headers=~/^Content-Length\b/im
or $headers.="Content-Length: 
".length($body)."\r\n";
$ctx->{"data"}=$headers."\r\n".$body;
die "Invalid Transfer-Encoding $1" if 
$headers=~/^Transfer-Encoding\b([^\r\n]*)/im;
#   warn Dumper \%headers;
#   warn Dumper "data=",$ctx->{"data"};
}
}

my $result;
# FIXME: Check $mode here.
($result,$ctx->{"data"})=split /\r\n/,$ctx->{"data"},2;
if (defined $result) {
$result.="\r\n" if defined $ctx->{"data"};
my $bn=APR::Bucket->new($result);
$bb->insert_tail($bn);
}
#   warn Dumper "result=",$result;

$f->ctx($ctx);
Apache::OK;
}

1;