Mailing List Archive

Plack::Middleware::ContentLength problem
Considering a possible option to remove code from Catalyst that inspects
the content length of the response body, I was looking the the code for
Plack::Middleware::ContentLength
<http://cpansearch.perl.org/src/MIYAGAWA/Plack-1.0030/lib/Plack/Middleware/ContentLength.pm>.
The meat is really in Plack::Util, and as a dependency of
HTTP::Server::PSGI there is no additional dependency for Catalyst. So it
could even be a default middleware, retaining (replacing) what Catalyst
already does.

While the implementation is similar to the Catalyst code there is a bit
more to it, mostly in Plack::Util::is_real_fh. The function does a
number of checks to determine whether the filehandle is real before
handing over to filestat -s
to get the size. There are noted problems with things that may look like
a filehandle but are not specifically a typical filehandle, so this is
valid. But there may be cases where you want to do so. My article today
actually (http://www.catalystframework.org/calendar/2013/21), even
though I'm actually talking here about the above case.

So I can play with the filehandle implementation class enough to get the
"is_real_fh" test to return true. But there seems to be a problem in
implementing the middleware.

From the test code I get the right result. But note the inclusion order
of Plack::Util. If that is loaded before the class
that does the required mucking around, the function passes, if not the
function will fail. This all revolves around overriding the built-in
"fileno" as this is used in "is_real_fh".

So it seems the same issue is happening with loading order when the
middleware is applied to a PSGI app. But I'm not sure how or whether
there is some other funny thing going on.

Any Ideas? Pointers?

Neil

Test case code. Also with another version of is_real_fh with extended
debugging.

#!/usr/bin/env perl
use Modern::Perl;

use Scalar::Util;
#use Plack::Util;
use MyApp::FunnyIO::Domain::GzipData;
use MyApp::FunnyIO::Domain::FunnyIO;
use Plack::Util;

my $comp = MyApp::FunnyIO::Domain::GzipData->new->getData();
my $body = MyApp::FunnyIO::Domain::FunnyIO->new( \$comp );

if ( -p $body or -c _ or -b _ ) {
say "nope";
} else {
say "yep";
}

my $reftype = Scalar::Util::reftype($body);
if ( $reftype eq 'IO' or $reftype eq 'GLOB' && *{$body}{IO} ) {
say "yep";
} else {
say "nope";
}

my $m_fileno = $body->fileno;
say "defined" if defined $m_fileno;
say "->fileno " . $m_fileno;

if ( Plack::Util::is_real_fh( $body ) ) {
say "yep i am real";
} else {
say "nope not real";
}

say ref( $body );
my $f_fileno = fileno( $body );
say "defined" if defined $f_fileno;
say "fileno " . $f_fileno;
say -s $body;

my $size = Plack::Util::content_length( $body );
say $size;

package MyTest;
use overload();

sub TRUE { 1==1 }
sub FALSE { !TRUE }

sub is_real_fh {
my $fh = shift;
{
no warnings 'uninitialized';
if ( -p $fh or -c _ or -b _ ) {
warn "do not like file test";
return FALSE;
}
}

my $reftype = Scalar::Util::reftype($fh) or return;
if ( $reftype eq 'IO'
or $reftype eq 'GLOB' && *{$fh}{IO}
) {
my $m_fileno = $fh->fileno;
unless( defined $m_fileno ) {
warn "m_fileno not defined";
return FALSE;
}

unless( $m_fileno >= 0 ) {
warn "m_fileno less than 0";
return FALSE;
}

my $f_fileno = fileno( $fh );
unless( defined $f_fileno ) {
warn "f_fileno not defined";
return FALSE;
}

unless( $f_fileno >= 0 ) {
warn "f_fileno less than 0";
return FALSE;
}

return TRUE;

} else {

warn "Don't like GLOB type";
return FALSE;

}


And the code for the Filehandle ('like') class:

package MyApp::FunnyIO::Domain::FunnyIO;
use Moose;
use Moose::Exporter;
use MooseX::NonMoose::InsideOut;
extends 'IO::Uncompress::Gunzip';
use IO::Scalar;
use namespace::sweep;

BEGIN {
*CORE::GLOBAL::fileno = sub {
my $fh = shift;
return 0 if ( ref $fh eq 'MyApp::FunnyIO::Domain::FunnyIO' );
return CORE::fileno($fh);
};
}

use overload
'bool' => sub {1},
'-X' => \&myFileTest;

Moose::Exporter->setup_import_methods(
as_is => ['fileno'],
);

has '_content' => ( is => 'ro' );

sub fileno {
my $fh = shift;
return fileno($fh);
}

sub myFileTest {
my ( $self, $arg ) = @_;

if ( $arg eq "s" ) {

my $io = IO::Scalar->new( $self->_content );
$io->seek( -4, 2 );
$io->read( my $buf, 4 );
return unpack( 'V', $buf );

} elsif ( $arg eq "p" ) {
return undef;
} else {
die "Got: $arg Only implementing a size operator at this time";
}

}

around BUILDARGS => sub {
my ( $orig, $class, $ref ) = @_;
return $class->$orig({ '_content' => $ref });
};


sub FOREIGNBUILDARGS {
my ( $class, $args ) = @_;
return $args;
}

no Moose;
__PACKAGE__->meta->make_immutable;
1;

And for a simple PSGI app:

use MyApp::FunnyIO::Domain::GzipData;
use MyApp::FunnyIO::Domain::FunnyIO;
use Plack::Builder;
#use Plack::Util;
#use Plack::Middleware::ContentLength;

builder {

enable 'Plack::Middleware::ContentLength';

my $app = sub {
my $env = shift;

my $comp = MyApp::FunnyIO::Domain::GzipData->new->getData();
my $body = MyApp::FunnyIO::Domain::FunnyIO->new( \$comp );

return [
'200',
[ 'Content-Type' => 'text/plain' ],
$body,
];

};

}









---
This email is free from viruses and malware because avast! Antivirus protection is active.
http://www.avast.com
Re: Plack::Middleware::ContentLength problem [ In reply to ]
On Fri, Dec 20, 2013 at 8:34 PM, neil.lunn <neil@mylunn.id.au> wrote:

> ....
>

My article today actually (http://www.catalystframework.org/calendar/2013/21),
> even though I'm actually talking here about the above case.
>

Just a note on the Advent article.

Thanks for writing that up. It's a well-written article and clearly
explains the issue I was facing and the fix you provided to me. One thing
I really like about the Advent articles is that I learn new ways to do
things. For example, I wasn't aware of namespace::sweep and never thought
about overriding the -X filetests. I just set the content length manually
now in the Controller along with the body.

I'm was also very happy to see you building this into a model at the end.
I sometimes wonder if that is not stressed enough when learning Catalyst.
I see a lot of code written into controllers at work that should really be
models. I will pass the link to the Advent article around.

In my specific situation for this problem I already had a model. The
gzipped files are stored on a distributed file system and I already had a
model class for fetching files. I just extended that to handle these
gzipped files. But, I think your solution is a bit more elegant and,
well, more correct because it can be used more widely.

Thanks,
Re: Plack::Middleware::ContentLength problem [ In reply to ]
The current HEAD of the runner branch actually has beta code that replaces the existing logic for calculating content length when its not set with this Plack middleware  (we also replace some custom logic to remove the content body when the request is HEAD with similar Plack middleware).  So this work is useful to help us shake out and improve the common middleware bits.

Over the coming time I plan to move more and more custom code into middleware when it makes sense.  The goal is to reduce the amount of custom code in Catalyst and move some of the burden of maintenance onto the broader Plack community.

However I am unclear what the failing cases is this example are...  Is is possible to contrive a failing case for the content length middleware we can bring to #plack / miyagawa?

I recommend anyone interested to start pulling from the HEAD of the runner branch if they want to play with it.  I want to ponder the best approach to using middleware for core app functionality (pondering how Rails middleware stack works, and looking at PlackX::MiddlewareStack for examples.)  Right now in HEAD the core middleware is just tacked onto the top of registered_middleware.  Thoughts on the best way to architect this are very welcome.  I see in the nearish future a good chuck of stuff that is in Catalyst.pm and related files moving into Middleware, possibly including the debugging screens, errors screens, etc.  In Rails and Django for example all that stuff is in middleware to make it easier for people to pull out and hack on it.

John



On Saturday, December 21, 2013 9:38 AM, Bill Moseley <moseley@hank.org> wrote:

On Fri, Dec 20, 2013 at 8:34 PM, neil.lunn <neil@mylunn.id.au> wrote:

....

My article today actually (http://www.catalystframework.org/calendar/2013/21), even though I'm actually talking here about the above case.
>

Just a note on the Advent article.

Thanks for writing that up.   It's a well-written article and clearly explains the issue I was facing and the fix you provided to me.  One thing I really like about the Advent articles is that I learn new ways to do things.   For example, I wasn't aware of namespace::sweep and never thought about overriding the -X filetests.   I just set the content length manually now in the Controller along with the body.

I'm was also very happy to see you building this into a model at the end.  I sometimes wonder if that is not stressed enough when learning Catalyst.   I see a lot of code written into controllers at work that should really be models.  I will pass the link to the Advent article around.


In my specific situation for this problem I already had a model.   The gzipped files are stored on a distributed file system and I already had a model class for fetching files.  I just extended that to handle these gzipped files.    But, I think your solution is a bit more elegant and, well, more correct because it can be used more widely.

Thanks,


_______________________________________________
List: Catalyst@lists.scsys.co.uk
Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst
Searchable archive: http://www.mail-archive.com/catalyst@lists.scsys.co.uk/
Dev site: http://dev.catalyst.perl.org/
Re: Plack::Middleware::ContentLength problem [ In reply to ]
On 22/12/2013 7:47 AM, John Napiorkowski wrote:
> The current HEAD of the runner branch actually has beta code that
> replaces the existing logic for calculating content length when its
> not set with this Plack middleware (we also replace some custom logic
> to remove the content body when the request is HEAD with similar Plack
> middleware). So this work is useful to help us shake out and improve
> the common middleware bits.

Was hoping that would be the case. Checked out the current HEAD of
runner to confirm tests
>
> Over the coming time I plan to move more and more custom code into
> middleware when it makes sense. The goal is to reduce the amount of
> custom code in Catalyst and move some of the burden of maintenance
> onto the broader Plack community.
And hopefully other frameworks do the same so the Plack parts remain common.
>
> However I am unclear what the failing cases is this example are... Is
> is possible to contrive a failing case for the content length
> middleware we can bring to #plack / miyagawa?
Still working on something that solves but with some work I got a
reproducible result on plain PSGI and also on the runner branch. The
good news being I can get the ContentLength middleware to correctly
report on the handle even under 'runner'.

The not so good news is that first suspicions were right. As I had in a
base test script, it is the order of Plack::Util loading that is the
problem. To make the 'is_real_fh' function work in this case, I am
overriding perl's built in 'fileno'. Problem being that the Plack::Util
is being pulled in before the code that overrides the built in is being
loaded. Thus the 'fileno' call within 'is_real_fh' is still pointing to
CORE.

The reason is Plack::Runner as Plack::Util is in it's imports before
parsing the content of a supplied *.psgi file in the arguments. If
instead this is manually scripted (ie plain script invoking
Plack::Runner) and the symbol table alteration is loaded first, well
then all is okay.

Most deployments will probably use the *.psgi file to setup. So trying
to find a way around this or otherwise have a different way to change
symbol table. But mostly looking like chicken and egg stuff :)

Neil

>
> I recommend anyone interested to start pulling from the HEAD of the
> runner branch if they want to play with it. I want to ponder the best
> approach to using middleware for core app functionality (pondering how
> Rails middleware stack works, and looking at PlackX::MiddlewareStack
> for examples.) Right now in HEAD the core middleware is just tacked
> onto the top of registered_middleware. Thoughts on the best way to
> architect this are very welcome. I see in the nearish future a good
> chuck of stuff that is in Catalyst.pm and related files moving into
> Middleware, possibly including the debugging screens, errors screens,
> etc. In Rails and Django for example all that stuff is in middleware
> to make it easier for people to pull out and hack on it.
>
> John
>
>
> On Saturday, December 21, 2013 9:38 AM, Bill Moseley
> <moseley@hank.org> wrote:
> On Fri, Dec 20, 2013 at 8:34 PM, neil.lunn <neil@mylunn.id.au
> <mailto:neil@mylunn.id.au>> wrote:
>
> ....
>
> My article today actually
> (http://www.catalystframework.org/calendar/2013/21), even though
> I'm actually talking here about the above case.
>
>
> Just a note on the Advent article.
>
> Thanks for writing that up. It's a well-written article and clearly
> explains the issue I was facing and the fix you provided to me. One
> thing I really like about the Advent articles is that I learn new ways
> to do things. For example, I wasn't aware of namespace::sweep and
> never thought about overriding the -X filetests. I just set the
> content length manually now in the Controller along with the body.
>
> I'm was also very happy to see you building this into a model at the
> end. I sometimes wonder if that is not stressed enough when learning
> Catalyst. I see a lot of code written into controllers at work that
> should really be models. I will pass the link to the Advent article
> around.
>
> In my specific situation for this problem I already had a model. The
> gzipped files are stored on a distributed file system and I already
> had a model class for fetching files. I just extended that to handle
> these gzipped files. But, I think your solution is a bit more elegant
> and, well, more correct because it can be used more widely.
>
> Thanks,
>
>
> _______________________________________________
> List: Catalyst@lists.scsys.co.uk <mailto:Catalyst@lists.scsys.co.uk>
> Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst
> Searchable archive:
> http://www.mail-archive.com/catalyst@lists.scsys.co.uk/
> Dev site: http://dev.catalyst.perl.org/
>
>
>
>
> _______________________________________________
> List: Catalyst@lists.scsys.co.uk
> Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst
> Searchable archive: http://www.mail-archive.com/catalyst@lists.scsys.co.uk/
> Dev site: http://dev.catalyst.perl.org/



---
This email is free from viruses and malware because avast! Antivirus protection is active.
http://www.avast.com
Re: Plack::Middleware::ContentLength problem [ In reply to ]
On 22/12/2013 3:26 PM, neil.lunn wrote:

Not jumping around on this any longer. Changing
Plack::Util::content_length seems to be the most sane answer.
'is_real_fh' does good for guarding against things that are not going to
return a valid file descriptor, as would be requried by IO::AIO functions.

Hopefully the proposed change gets some traction and is accepted.
https://github.com/plack/Plack/issues/439

> On 22/12/2013 7:47 AM, John Napiorkowski wrote:
>> The current HEAD of the runner branch actually has beta code that
>> replaces the existing logic for calculating content length when its
>> not set with this Plack middleware (we also replace some custom
>> logic to remove the content body when the request is HEAD with
>> similar Plack middleware). So this work is useful to help us shake
>> out and improve the common middleware bits.
>
> Was hoping that would be the case. Checked out the current HEAD of
> runner to confirm tests
>>
>> Over the coming time I plan to move more and more custom code into
>> middleware when it makes sense. The goal is to reduce the amount of
>> custom code in Catalyst and move some of the burden of maintenance
>> onto the broader Plack community.
> And hopefully other frameworks do the same so the Plack parts remain
> common.
>>
>> However I am unclear what the failing cases is this example are...
>> Is is possible to contrive a failing case for the content length
>> middleware we can bring to #plack / miyagawa?
> Still working on something that solves but with some work I got a
> reproducible result on plain PSGI and also on the runner branch. The
> good news being I can get the ContentLength middleware to correctly
> report on the handle even under 'runner'.
>
> The not so good news is that first suspicions were right. As I had in
> a base test script, it is the order of Plack::Util loading that is the
> problem. To make the 'is_real_fh' function work in this case, I am
> overriding perl's built in 'fileno'. Problem being that the
> Plack::Util is being pulled in before the code that overrides the
> built in is being loaded. Thus the 'fileno' call within 'is_real_fh'
> is still pointing to CORE.
>
> The reason is Plack::Runner as Plack::Util is in it's imports before
> parsing the content of a supplied *.psgi file in the arguments. If
> instead this is manually scripted (ie plain script invoking
> Plack::Runner) and the symbol table alteration is loaded first, well
> then all is okay.
>
> Most deployments will probably use the *.psgi file to setup. So trying
> to find a way around this or otherwise have a different way to change
> symbol table. But mostly looking like chicken and egg stuff :)
>
> Neil
>
>>
>> I recommend anyone interested to start pulling from the HEAD of the
>> runner branch if they want to play with it. I want to ponder the
>> best approach to using middleware for core app functionality
>> (pondering how Rails middleware stack works, and looking at
>> PlackX::MiddlewareStack for examples.) Right now in HEAD the core
>> middleware is just tacked onto the top of registered_middleware.
>> Thoughts on the best way to architect this are very welcome. I see
>> in the nearish future a good chuck of stuff that is in Catalyst.pm
>> and related files moving into Middleware, possibly including the
>> debugging screens, errors screens, etc. In Rails and Django for
>> example all that stuff is in middleware to make it easier for people
>> to pull out and hack on it.
>>
>> John
>>
>>
>> On Saturday, December 21, 2013 9:38 AM, Bill Moseley
>> <moseley@hank.org> wrote:
>> On Fri, Dec 20, 2013 at 8:34 PM, neil.lunn <neil@mylunn.id.au
>> <mailto:neil@mylunn.id.au>> wrote:
>>
>> ....
>>
>> My article today actually
>> (http://www.catalystframework.org/calendar/2013/21), even though
>> I'm actually talking here about the above case.
>>
>>
>> Just a note on the Advent article.
>>
>> Thanks for writing that up. It's a well-written article and clearly
>> explains the issue I was facing and the fix you provided to me. One
>> thing I really like about the Advent articles is that I learn new
>> ways to do things. For example, I wasn't aware of namespace::sweep
>> and never thought about overriding the -X filetests. I just set the
>> content length manually now in the Controller along with the body.
>>
>> I'm was also very happy to see you building this into a model at the
>> end. I sometimes wonder if that is not stressed enough when learning
>> Catalyst. I see a lot of code written into controllers at work that
>> should really be models. I will pass the link to the Advent article
>> around.
>>
>> In my specific situation for this problem I already had a model.
>> The gzipped files are stored on a distributed file system and I
>> already had a model class for fetching files. I just extended that
>> to handle these gzipped files. But, I think your solution is a bit
>> more elegant and, well, more correct because it can be used more widely.
>>
>> Thanks,
>>
>>
>> _______________________________________________
>> List: Catalyst@lists.scsys.co.uk <mailto:Catalyst@lists.scsys.co.uk>
>> Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst
>> Searchable archive:
>> http://www.mail-archive.com/catalyst@lists.scsys.co.uk/
>> Dev site: http://dev.catalyst.perl.org/
>>
>>
>>
>>
>> _______________________________________________
>> List:Catalyst@lists.scsys.co.uk
>> Listinfo:http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst
>> Searchable archive:http://www.mail-archive.com/catalyst@lists.scsys.co.uk/
>> Dev site:http://dev.catalyst.perl.org/
>
>
>
> ------------------------------------------------------------------------
> <http://www.avast.com/>
>
> This email is free from viruses and malware because avast! Antivirus
> <http://www.avast.com/> protection is active.
>
>
>
>
> _______________________________________________
> List: Catalyst@lists.scsys.co.uk
> Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst
> Searchable archive: http://www.mail-archive.com/catalyst@lists.scsys.co.uk/
> Dev site: http://dev.catalyst.perl.org/



---
This email is free from viruses and malware because avast! Antivirus protection is active.
http://www.avast.com
Re: Plack::Middleware::ContentLength problem [ In reply to ]
On 22/12/2013 2:36 AM, Bill Moseley wrote:
> On Fri, Dec 20, 2013 at 8:34 PM, neil.lunn <neil@mylunn.id.au
> <mailto:neil@mylunn.id.au>> wrote:
>
> ....
>
> My article today actually
> (http://www.catalystframework.org/calendar/2013/21), even though
> I'm actually talking here about the above case.
>
>
> Just a note on the Advent article.
>
> I'm was also very happy to see you building this into a model at the
> end. I sometimes wonder if that is not stressed enough when learning
> Catalyst. I see a lot of code written into controllers at work that
> should really be models. I will pass the link to the Advent article
> around.
Was mostly intending to work on the current quest tasks for 'Catalyst
runner'. But there is a valid side point.

Just a note from me, and possibly a re-post and blogging (much needed).
It's not only just the abstraction to 'Model' that is important 'IMHO'
but the full abstraction of Domain logic away from the 'Web framework'.

As implied, there is too much of 'how an application works' applied at
the controller level, in many occasions, which is what many of us see.
So not only is promoting MVC concepts a boon to most development cycles,
but promoting true Dependency injection concepts ( i.e Currently
'Model::Adaptor' / 'Model::Factory::*' in a Catalyst sense ) to further
pull in the Domain logic that 'should just work' outside of the 'web
framework' is again IMHO the way things should be done.

There was a further concept (re: DI concepts) hidden in the codebase
where 'Config::Loader' is ditched for a class that can be used outside
of Catalyst.

Hope that all had fun and hope that some picked up something new or
otherwise from the above. Which is why we take the time to write such
things :)

Neil



---
This email is free from viruses and malware because avast! Antivirus protection is active.
http://www.avast.com
Re: Plack::Middleware::ContentLength problem [ In reply to ]
On Sunday, December 22, 2013 12:33 AM, neil.lunn <neil@mylunn.id.au> wrote:

On 22/12/2013 3:26 PM, neil.lunn wrote:

Not jumping around on this any longer. Changing
      Plack::Util::content_length seems to be the most sane answer.
'is_real_fh' does good for guarding against things that are not
      going to return a valid file descriptor, as would be requried by
      IO::AIO functions.

Hopefully the proposed change gets some traction and is accepted.
https://github.com/plack/Plack/issues/439


On 22/12/2013 7:47 AM, John Napiorkowski wrote:

The current HEAD of the runner branch actually has beta code that replaces the existing logic for calculating content length when its not set with this Plack middleware  (we also replace some custom logic to remove the content body when the request is HEAD with similar Plack middleware).  So this work is useful to help us shake out and improve the common middleware bits.
Was hoping that would be the case. Checked out the current HEAD of
      runner to confirm tests


>
>Over the coming time I plan to move more and more custom code into middleware when it makes sense.  The goal is to reduce the amount of custom code in Catalyst and move some of the burden of maintenance onto the broader Plack community.
And hopefully other frameworks do the same so the Plack parts remain common.


>
>However I am unclear what the failing cases is this example are...  Is is possible to contrive a failing case for the content length middleware we can bring to #plack / miyagawa?
Still working on something that solves but with some work I got a reproducible result on plain PSGI and also on the runner branch. The good news being I can get the ContentLength middleware to correctly report on the handle even under 'runner'.

The not so good news is that first suspicions were right. As I had
      in a base test script, it is the order of Plack::Util loading that
      is the problem. To make the 'is_real_fh' function work in this
      case, I am overriding perl's built in 'fileno'. Problem being that
      the Plack::Util is being pulled in before the code that overrides
      the built in is being loaded. Thus the 'fileno' call within
      'is_real_fh' is still pointing to CORE.

The reason is Plack::Runner as Plack::Util is in it's imports
      before parsing the content of a supplied *.psgi file in the
      arguments. If instead this is manually scripted (ie plain script
      invoking Plack::Runner) and the symbol table alteration is loaded
      first, well then all is okay.

Most deployments will probably use the *.psgi file to setup. So
      trying to find a way around this or otherwise have a different way
      to change symbol table. But mostly looking like chicken and egg
      stuff :)

Neil


___
Niel,

I'm reviewing the plack issue you created.  One thing though, in the future it should not be so important for a catalyst application to run via *.psgi since you can configure middleware and mount other applications directly.  The only cases where having a psgi file would be useful is when you want to tie together applications with shared behaviors when the applications are not really part of each other.  So if we have this working correctly under runner, that's pretty good I think!  Base on that I think this issue could belong to plack and we can hack on it over there.  Which is ultimately my goal, which is to reduce the amount of custom behavior in Catalyst so that we can share the development load.

John



>
>I recommend anyone interested to start pulling from the HEAD of the runner branch if they want to play with it.  I want to ponder the best approach to using middleware for core app functionality (pondering how Rails middleware stack works, and looking at PlackX::MiddlewareStack for examples.)  Right now in HEAD the core middleware is just tacked onto the top of registered_middleware.  Thoughts on the best way to architect this are very welcome.  I see in the nearish future a good chuck of stuff that is in Catalyst.pm and related files moving into Middleware, possibly including the debugging screens, errors screens, etc.  In Rails and Django for example all that stuff is in middleware to make it easier for people to pull out and hack on it.
>
>
>John
>
>
>
>On Saturday, December 21, 2013 9:38 AM, Bill Moseley <moseley@hank.org> wrote:
>
>On Fri, Dec 20, 2013 at 8:34 PM, neil.lunn <neil@mylunn.id.au> wrote:
>
>....
>> 
>My article today actually (http://www.catalystframework.org/calendar/2013/21), even though I'm actually talking here about the above case.
>>
>
>
>Just a note on the Advent article.
>
>
>Thanks for writing that up.   It's a well-written article and clearly explains the issue I was facing and the fix you provided to me.  One thing I really like about the Advent articles is that I learn new ways to do things.   For example, I wasn't aware of namespace::sweep and never thought about overriding the -X filetests.   I just set the content length manually now in the Controller along with the body.
>
>
>I'm was also very happy to see you building this into a model at the end.  I sometimes wonder if that is not stressed enough when learning Catalyst.   I see a lot of code written into controllers at work that should really be models.  I will pass the link to the Advent article around.
>
>
>
>In my specific situation for this problem I already had a model.   The gzipped files are stored on a distributed file system and I already had a model class for fetching files.  I just extended that to handle these gzipped files.    But, I think your solution is a bit more elegant and, well, more correct because it can be used more widely.
>
>
>Thanks,
>
>
>
>_______________________________________________
>List: Catalyst@lists.scsys.co.uk
>Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst
>Searchable archive: http://www.mail-archive.com/catalyst@lists.scsys.co.uk/
>Dev site: http://dev.catalyst.perl.org/
>
>
>
>
>
>_______________________________________________
List: Catalyst@lists.scsys.co.uk Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@lists.scsys.co.uk/ Dev site: http://dev.catalyst.perl.org/


________________________________

   This email is free from viruses and malware because avast! Antivirus protection is active.  




_______________________________________________
List: Catalyst@lists.scsys.co.uk Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@lists.scsys.co.uk/ Dev site: http://dev.catalyst.perl.org/


________________________________

   This email is free from viruses and malware because avast! Antivirus protection is active.  


_______________________________________________
List: Catalyst@lists.scsys.co.uk
Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst
Searchable archive: http://www.mail-archive.com/catalyst@lists.scsys.co.uk/
Dev site: http://dev.catalyst.perl.org/

_______________________________________________
List: Catalyst@lists.scsys.co.uk
Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst
Searchable archive: http://www.mail-archive.com/catalyst@lists.scsys.co.uk/
Dev site: http://dev.catalyst.perl.org/