Re: [Catalyst] Why no extra attributes on Private actions?

2009-08-17 Thread Bill Moseley
On Mon, Aug 17, 2009 at 8:14 AM, Eden Cardim edencar...@gmail.com wrote:


 I don't understand your obsession over :Private. A method tagged with
 :Action, or any other attribute that doesn't make it use one of the
 available dispatch types is effectively *the same thing* as a Private
 action, except it doesn't restrict the use of other attributes, is
 this not what you want? Personally, I've dumped most uses of method
 attributes altogether, in favor of the config-based scheme, except for
 a few cases of chaining, so I'd vouch for dumping :Private as well.


Sorry, it does sound like an obsession.  And yes you are right there are
other approaches.  It's not a big deal.


Obviously, the intent of Private is to have a forward-able action that
cannot be dispatched directly. It's a pretty basic part of Catalyst to have
actions that cannot be dispatched directly, so Private (or a way to express
the same thing) is useful. The implementation enforces this by prohibiting
any additional attributes instead of just prohibiting attributes handled by
different dispatch types.:Action just takes advantage of the
implementation details -- it's not a real action attribute at this time I
believe.

The issue that came up was I knew I could simply avoid using :Private to use
additional attributes, but then I didn't want to create an action for every
method that had attributes, either.

We are just investigating different approaches at this time, so it may turn
out that we go for the config-based approach as you noted.  The people with
java experience seem to favor the config-based approach.

Anyway, I've moved on to obsessing about other things.


-- 
Bill Moseley
mose...@hank.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/


Re: [Catalyst] Inconsistent hierarchy....

2009-08-18 Thread Bill Moseley
On Tue, Aug 18, 2009 at 3:59 AM, mrchips mailli...@aspiretools.co.ukwrote:



 Lucky me :)
 I downgraded to 5.7015 and everything is fine (no surprise there)..so it
 seems CDBI just doesn't work with 5.8


I have two old application using CDBI and they run fine with Catalyst 5.8.
I had the standard NEXT warnings, but that was easy to suppress.

I'm very impressed what a good job the Cat developers did making the 5.8
move smooth.


-- 
Bill Moseley
mose...@hank.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/


Re: [Catalyst] use base vs use parent

2009-08-25 Thread Bill Moseley
On Tue, Aug 25, 2009 at 11:55 AM, Evan Carroll li...@evancarroll.comwrote:



 When should be use parent be used and not use base or it really
 doesn't matter which one is used?


 parent.pm when you can use cpan, base.pm when you can't.


If it's a Moose class should you always use extends over both?

Hum, the CatalystAndMoose manual doesn't even show the application base
class inheriting:

http://search.cpan.org/~hkclark/Catalyst-Manual-5.8000/lib/Catalyst/Manual/CatalystAndMoose.pod#THE_CONTEXT_CLASS

Unlike in the Intro which shows use parent.

(The CatAndMoose page also shows $app, which isn't defined).

Not sure if this is by design or not, but the application base class
automatically inherits from Catalyst and Catalyst::Controller.




-- 
Bill Moseley
mose...@hank.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/


Re: [Catalyst] Handling configuration outside the Catalyst application

2009-08-27 Thread Bill Moseley
On Thu, Aug 27, 2009 at 7:10 PM, Daniel Austin daniel.aus...@gmail.com wrote:

 Hello

 How are you handling configuration for applications or code that run
 outside of Catalyst?

 For example, in my model tests, I have code like this:

    use MyCompany::CatApp;
    my $app = MyCompany::CatApp-new();
    my $model = $app-model('DB::Model')-new({});
    ok( $model-insert );

 etc.

 This way the model tests are talking to the right database as
 configured for that environment. But it seems slow to run and it's not
 the right coupling if I have, say, a cronjob that wants to use the
 same models.

 Are there any patterns anyone can recommend?

I have a config module that I use everywhere.  I specify a running
mode, such as testing, staging, and production so that the correct
config is pulled.

$ script/dump_config.pl --mode=production log4perl
{
  enable = 1,
  level = info,
}

$ script/dump_config.pl --mode=development log4perl
{
  enable = 1,
  level = debug,
}

Catalyst uses a plugin for that module.  I also have another module
that uses that configuration class.  It makes it easy to write cron
scripts.

#!/usr/bin/perl
use App::ConfigUtil;

# define options for this script
my %options = (
minutes_old = {
help = 'Items must be minutes_old to be removed
format = '=i',
default = 60,
},
);


my $app= App::ConfigUtil-new( \%options );
my $config = $app-config;  # same config Catalyst sees
my $db  = $app-database;

$app-lock(20); # lock this cron job for 20 seconds (since running on
multiple servers)

$db-model( 'Foo' )-remove_old;

Then it's just ./clean_foo --mode=production --minutes_old=120



But, now I'm thinking about making all access go through Catalyst.
That is, a cron job would log in via the API and then use and API
method to do its work.  Wouldn't need to be a web request, of course.
Then I've got one access layer to the application and can have ACL
rules for the cron user and unified logging.


--
Bill Moseley
mose...@hank.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/


Re: [Catalyst] Splitting up a large application: Shared config and templates for multiple applications

2009-08-28 Thread Bill Moseley
On Fri, Aug 28, 2009 at 6:41 AM, Matt Whipple m...@mattwhipple.com wrote:



 Anyone building applications out of multiple small Catalyst applications
 like this?  How do you set up the apps to share templates and a config?
  Anything more interesting than passing in paths?
 One downside of this approach is we end up with a handful of very similar
 looking applications (same set of plugins, etc.), not to mention have to be
 careful about how session data is shared, and so on.  I wounder if it would
 be difficulst to customize the catalyst.pl script to include a standard set
 of plugins/roles that we use in every application -- e.g. have a skeleton
 app.

  Subclass.  This could probably take care of sharing the template/config
 resources also, but otherwise I'd probably lean towards symlinking over
 modifying each app.


Subclass what?

I was thinking that I'd have to use an environment variable to point to the
location of the base application (the one with the base tempates and
app-wide config) and then add to the template INCLUDE_PATH.  Or maybe have
the applications look at $app_home/../$base_app/.

Seems there was some discussion not too long ago of drop-in modules for
application, similar to what many CMSs have.



-- 
Bill Moseley
mose...@hank.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/


[Catalyst] ActionClass vs. Moose Role?

2009-08-28 Thread Bill Moseley
I was starting to implement a custom ActionClass (similar to RenderView) and
then wondered if it would be better written as a Moose role.
Is there a reason to use one over another?

Last I looked, an action is limited to a single ActionClass (although it's
easy to deal with that), but depending on how it's done, could apply
multiple roles.

That is, one way would be to define the end() method in the role and not
even have it in the consuming controller class, or another would be to have
a end() stub
in the controller and and then use before 'end' in the role.  That way
multiple roles could be applied.

Any guidance here?

Is everything going to be a role at some point? ;)

-- 
Bill Moseley
mose...@hank.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/


Re: [Catalyst] ActionClass vs. Moose Role?

2009-08-28 Thread Bill Moseley
On Fri, Aug 28, 2009 at 10:29 AM, Tomas Doran bobtf...@bobtfish.net wrote:


 On 28 Aug 2009, at 18:25, Bill Moseley wrote:

  I was starting to implement a custom ActionClass (similar to RenderView)
 and then wondered if it would be better written as a Moose role.


 Maybe - depends what you're doing. They're doing different things really,
 and I'd need more details to make a recommendation.


Well, if you were going to write something like RenderView now would you
still write it as an ActionClass?

The purpose is to have a standard end() that I use in multiple applications
-- similar to RenderView as I mentioned.

I guess the difference is if you want to apply code to any action vs. a
specific action.  RenderView is typically applied just to the end() method
(or a method forwarded to from end() ), so maybe it's really better as a
role since it would always alter end().

But if I want to apply code to different (and specific) actions then
ActionClass is probably better since it can be set per action.

Anyway, using before 'end' is probably the way to go in the role instead
of sub end.


BTW -- will the helpers for catalyst.pl start generating Moose-ified context
and controller classes at some point soon?



-- 
Bill Moseley
mose...@hank.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/


[Catalyst] Class data in a Moose::Role plugin

2009-09-02 Thread Bill Moseley
I also tried with Catalyst::ClassData.  Must be missing something.

All modules up to date.  On Perl 5.10.0.

$ catalyst.pl MyApp



$ cat lib/Catalyst/Plugin/Role.pm
package Catalyst::Plugin::Role;
use Moose::Role;
use MooseX::ClassAttribute;

class_has 'Cache' =
( is  = 'rw',
  isa = 'HashRef',
  default = sub { {} },
);
1;

$ script/myapp_server.pl
Could not load class (Catalyst::Plugin::Role) because :
Catalyst::Plugin::Role already has a metaclass, but it does not
inherit Moose::Meta::Class (Moose::Meta::Role=HASH(0xa38ff10)) at
/usr/local/share/perl/5.10.0/Moose.pm line 162
Moose::init_meta('Moose', 'metaclass', undef, 'for_class',
'Catalyst::Plugin::Role') called at
/usr/local/share/perl/5.10.0/MooseX/ClassAttribute.pm line 22
MooseX::ClassAttribute::init_meta('MooseX::ClassAttribute',
'for_class', 'Catalyst::Plugin::Role', 'metaclass', undef) called at
/usr/local/share/perl/5.10.0/Moose/Exporter.pm line 405
Moose::Exporter::__ANON__('MooseX::ClassAttribute') called at
/home/moseley/MyApp/script/../lib/Catalyst/Plugin/Role.pm line 3
Catalyst::Plugin::Role::BEGIN() called at
/usr/local/share/perl/5.10.0/MooseX/ClassAttribute.pm line 3
eval {...} called at
/usr/local/share/perl/5.10.0/MooseX/ClassAttribute.pm line 3
require Catalyst/Plugin/Role.pm called at
/usr/local/lib/perl/5.10.0/Class/MOP.pm line 134
eval {...} called at /usr/local/lib/perl/5.10.0/Class/MOP.pm line 134
Class::MOP::_try_load_one_class('Catalyst::Plugin::Role')
called at /usr/local/lib/perl/5.10.0/Class/MOP.pm line 95
Class::MOP::load_first_existing_class('Catalyst::Plugin::Role')
called at /usr/local/lib/perl/5.10.0/Class/MOP.pm line 140
Class::MOP::load_class('Catalyst::Plugin::Role') called at
/usr/local/share/perl/5.10.0/Catalyst.pm line 2563
Catalyst::setup_plugins('MyApp', 'ARRAY(0xa2d1598)') called at
/usr/local/share/perl/5.10.0/Catalyst.pm line 1028
Catalyst::setup('MyApp') called at
/home/moseley/MyApp/script/../lib/MyApp.pm line 35
require MyApp.pm called at script/myapp_server.pl line 66
main::__ANON__() called at script/myapp_server.pl line 107
BEGIN failed--compilation aborted at
/home/moseley/MyApp/script/../lib/Catalyst/Plugin/Role.pm line 3.
Compilation failed in require at
/usr/local/lib/perl/5.10.0/Class/MOP.pm line 134.
 at /usr/local/lib/perl/5.10.0/Class/MOP.pm line 119
Class::MOP::load_first_existing_class('Catalyst::Plugin::Role')
called at /usr/local/lib/perl/5.10.0/Class/MOP.pm line 140
Class::MOP::load_class('Catalyst::Plugin::Role') called at
/usr/local/share/perl/5.10.0/Catalyst.pm line 2563
Catalyst::setup_plugins('MyApp', 'ARRAY(0xa2d1598)') called at
/usr/local/share/perl/5.10.0/Catalyst.pm line 1028
Catalyst::setup('MyApp') called at
/home/moseley/MyApp/script/../lib/MyApp.pm line 35
require MyApp.pm called at script/myapp_server.pl line 66
main::__ANON__() called at script/myapp_server.pl line 107
Compilation failed in require at script/myapp_server.pl line 66.


With Catalyst::ClassData:

mose...@bumby2:~/MyApp$ cat lib/Catalyst/Plugin/Role.pm
package Catalyst::Plugin::Role;
use Moose::Role;
use Catalyst::ClassData;

__PACKAGE__-mk_classdata( 'foo' );
1;

mose...@bumby2:~/MyApp$ script/myapp_test.pl /
Could not load class (MyApp) because : Could not load class
(Catalyst::Plugin::Role) because : Can't locate object method
mk_classdata via package Catalyst::Plugin::Role at
/home/moseley/MyApp/script/../lib/Catalyst/Plugin/Role.pm line 5.
Compilation failed in require at
/usr/local/lib/perl/5.10.0/Class/MOP.pm line 134.
...

-- 
Bill Moseley
mose...@hank.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/


[Catalyst] Where to add access control? Override execute() or dispatch()?

2009-09-02 Thread Bill Moseley
I'm in the process of adding custom access control for actions.

I've been looking over C::P::Authorization::ACL.  It overrides
execute() which is run for every method called by the dispatcher,
which includes begin, auto, the action itself, and end.  Depending on
how the ACLs are specified, the plugin wll block access to the actual
action, but begin, auto, and end will still run.

I'm trying to decide if this is the best approach, or if would be
better to test the ACL before dispatching.  The issue is if the
request is for /foo/bar, and an ACL rule blocks that, should
Foo::(begin|end|auto) still run?  Or should it act as if the /foo/bar
action doesn't exist and not run any begin, auto, or end in the Foo
controller?

-- 
Bill Moseley
mose...@hank.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/


Re: [Catalyst] selectively using the wrapper

2009-09-16 Thread Bill Moseley
On Wed, Sep 16, 2009 at 9:11 AM, Ascii King t...@swattermatter.com wrote:

 Bill Moseley wrote:


 In my mind the wrapper is a view issue, so I set the wrapper in the
 template not in the controller.  I have a wrapper that is called for *every*
 page that is used to build the page.

 META is compile time, IIRC, so I use [% page.layout = 'foo' %] then in
 wrapper.tt http://wrapper.tt I have a CASE statement that
 sets the wrappers based on page.layout set in the base template.

 IIRC, I use page.layout (instead of say just layout) because WRAPPER
 does a shallow localization of the stash.


 Thanks again, guys.  It took me a few reads to figure out what this meant,
 but I'm glad I understand it now. I agree that the wrapper should be called
 from the template. I suspect it will make my life a little easier.


Not sure what you mean by template there, but maybe this makes it clearer:

 View::TT:
COMPILE_DIR: __TEMPDIR(templates)__
WRAPPER: page/wrapper.tt
PRE_PROCESS: config.tt
PRE_CHOMP: 0
POST_CHOMP: 0
TIMER: 0
STAT_TTL: 60
ENCODING: UTF-8

Template Toolkit then will call page/wrapper.tt for template passed to
process().  Then the template sets the page.layout and
page/wrapper.ttdecides how to build the entire page based on that
layout.





-- 
Bill Moseley
mose...@hank.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/


Re: [Catalyst] Re: Calling Controller Methods from inside begin or auto.

2009-09-30 Thread Bill Moseley
On Wed, Sep 30, 2009 at 5:23 AM, Derek Wueppelmann dwuep...@gmail.comwrote:

 On Tue, 2009-09-29 at 14:39 +0200, Aristotle Pagaltzis wrote:
  * monkey dwuep...@gmail.com [2009-09-29 14:35]:
   Is there another way to do the above without having to write
   the auth handling at the top of every method used to display
   pages?
 
  Chained dispatch. Do an auth check early in the chain, then the
  actions down the chain don’t need to do it.

 So I found a different way to do this. It's pretty close to my original
 method I had mentioned, but instead of calling $self-auth_required I
 changed it to:

$c-action-class-auth_required()

 Which has the desired effect. Now all I need to do is if a controller
 does not require authentication in order to be viewed I override the
 auth_required method in that controller to return 0 instead of the
 default 1.


Does that approach provide you with enough fine-grained access control?
I suppose you can check the action name in auth_required().

There are a number of existing modules to consider, for example:

Catalyst::Action::Role::ACL
Catalyst::Plugin::Authorization::ACL

I've also used an approach where I check for roles in each controller's auto
method, and I've also used method attributes to indicate the access level
required for each action (which has the benefit where I can require *every*
dispatched action to have an access level specified or be blocked).

I also do not detach to a login page, rather I always redirect.  Not sure I
remember the details of that choice, but one reason might have been I didn't
want a URL for one resource to return a 200 yet not return the response for
that URL and instead return a login form.



-- 
Bill Moseley
mose...@hank.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/


Re: [Catalyst] Re: Calling Controller Methods from inside begin or auto.

2009-09-30 Thread Bill Moseley
On Wed, Sep 30, 2009 at 7:30 AM, Derek Wueppelmann dwuep...@gmail.comwrote:

 I'm actually doing forwards to my login page right now. So that when a
 user logs in they can still see the page they were originally trying to
 view. I capture the URL they were attempting to view in the login
 process.


And then redirect back to that original page after login?

I pass that data via the cache or session.

$c-cache-set( $key, {
orig_url = $url,
message = 'Auhorization is required',
 });

$c-res-redirect( $c-uri_for( '/login', { info = $key } ) );


Catalyst docs show an example using auto.  BTW - shouldn't the redirect be
an absolute-URI?

   sub auto : Private {
   my ( $self, $c ) = @_;
   if ( !$c-user_exists ) { # Catalyst::Plugin::Authentication
   $c-res-redirect( '/login' ); # require login
   return 0; # abort request and go immediately to end()
   }
   return 1; # success; carry on to next action
   }

RFC3986 has:
absolute-URI = scheme : hier-part [ ? query ]

And 2616:
Location = Location : absoluteURI


-- 
Bill Moseley
mose...@hank.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/


Re: [Catalyst] Re: Calling Controller Methods from inside begin or auto.

2009-09-30 Thread Bill Moseley
On Wed, Sep 30, 2009 at 10:13 AM, Aristotle Pagaltzis pagalt...@gmx.dewrote:




 I detach. My login action sets status 403 and pragma no-cache
 (etc) when it’s not requested directly. I’d love to be able to
 just send 401 instead and let the user agent take care of
 everything (which would transparently and securely deal with
 POSTs sent with expired auth credentials) – unfortunately the
 HTTP Auth UI in browsers is universally shoddy. If I felt the
 need, I could also check for browser vs automated agent and send
 either form + 403 to browsers and just a 401 to other clients.


Looking at my code I also return 401 for API requests.  I have a note in the
code that there was problems returning 403 on some browsers although maybe
that was just old IE when the content body was too short and it would
display its own message.

And looking at old svn logs I found another reason I redirect -- which might
be how my code grew over time.

At one point I added a remember me feature.  So I have code in the
controller's auto() which is basically return unless $c-test_role( @roles
); That test_role() method first checks if logged in, and if not logged in
then does the redirect.  But, before doing the redirect it attempts an
automatic login via the remember me feature.

The problem there was then the action's auto() and begin() methods were not
run with the user logged in, which was important for other reasons.

I would have expected to do the remember me login earlier (e.g. in root's
auto() ) and avoided that issue, but mabye I had a reason otherwise.
Anyway, the redirect does allow the login action to be called as a normal
request (with login's auto and begin methods run).

Granted, now there's $c-go to do a full dispatch, but redirect seems
cleaner at the expense of a redirect.




-- 
Bill Moseley
mose...@hank.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/


Re: [Catalyst] Deployment in practice

2009-10-10 Thread Bill Moseley
2009/10/9 Octavian Râşniţă orasn...@gmail.com

 Hi,

 I've recently started to use Mercurial for revision control and the pages
 regarding the deployment of a Catalyst app from the Catalyst wiki also help
 me very much, but I still don't know what would be the best method for
 uploading the files to the server.

 How do you do it?
 Archive the entire app an dupload to the server then change the permissions
 of the files and folders there?
 Or upload the modified files one by one?
 Or generate a tarball on each revision and unarchive and make, make test it
 on the server?


I have a script on a build server that does an svn export of a specific
branch and version  (or latest trunk if no version specified).  The script
then runs the test suite, runs the build scripts that generate minified
css, javascript, and anything else that prepares the package such as create
a meta file with build info, and then builds a tarball named after the
reversion.  Also, a symlink is created as latest on the build server.

Then on target machines (testing, staging, and production) I have a push
script that fetches the tarball (based on a specific version or latest),
untars it on the machine.  It's untarred into a directory named after the
revision it came from.  Tests are run that verify that it can talk to
whatever it needs (database, services).  Then do a graceful stop of the
existing server, move symbolic links, start the server back up and then use
wget to validate a number of test URLs.  Depending on the update some
servers may get pulled out of the balancer before upgrading to do it in
stages.

Pushing a previous version will just update the symlinks if they revesion
exists.

Not perfect but seems to work ok for now.



-- 
Bill Moseley
mose...@hank.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/


Re: [Catalyst] Choosing the language

2009-10-12 Thread Bill Moseley
2009/10/12 Octavian Râşniţă orasn...@gmail.com

 Hi,

 Is there a recommendation for storing the language ID in the URL in order
 to be as easy to get it from there?

 I want to have unique links for each URL, so I can't just put it in the
 cookies. Using ?lang=EN seems to be the easiest way, although it doesn't
 look nice.


My other post about passing around query parameters is related.  Happens
that one of the parameters is a lang setting.  I've always preferred using a
path prefix instead of a query parameter.  For one things it make relative
urls work.  Another is that, IIRC, there were proxies that would not cache
content with query parameters.  I'm not sure if that's a real concern any
more -- or if there's any other reasons to avod the query parameter
approach.

Another parameter that might be passed, in my case, is a session id.  I'm
not a fan of that, but apparently there's some cases where it's needed (site
in an iframe??).  At one time I also put that into a path prefix.


 Putting it as the first element in the path info looks nice, but I don't
 know how to get it from there in a single controller/action and not in every
 action separately.


The wiki article Larry posted is very close to what I do.



-- 
Bill Moseley
mose...@hank.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/


[Catalyst] Validating single arg id

2009-10-16 Thread Bill Moseley
I have a number of methods that start something like this:

sub view : Local Args(1) {
my ( $self, $c, $id ) = @_;

my $obj = $c-model( 'DB::Foo' )-find( $id )
   || return $c-res-status( 404 );

If $id is not valid then I might, as in that example, return with a 404
status.

Of course, if $id is suppose to be an integer and a non-integer or an
integer out of range is provided then the the database will throw an
exception, which I want to prevent.  I want valid ids to return an object
and *anything* else to return undef before hitting the database.

This is pretty low-level validation -- just validating primary key.  For
more complex validation I use a form validation module.

Obviously, I could do something like

return $c-res-status(404) unless $c-model('DB::Foo')-is_valid_id( $id )

in every method, but that's not very DRY.

What I've done in the past is override the find() or search() method in my
model base class so that whatever $id is passed it is validated.  Specific
model classes can override the is_valid_id()  method if they use keys that
are not a common key format (i.e. different integer range or non-integer
key).

What's you approach to validating that $id in situations like this where
there's a single id?

Do you just let the database throw the exception?  I prefer to return 404s
for invalid ids, regardless of their format (and likewise for ids that point
to valid object, but are not owned by the current user instead of a 403).




-- 
Bill Moseley
mose...@hank.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/


Re: [Catalyst] Validating single arg id

2009-10-17 Thread Bill Moseley
On Fri, Oct 16, 2009 at 7:31 AM, J. Shirley jshir...@gmail.com wrote:


 What database do you use?  In MySQL and SQLite I get no exception at all:


Postgresql.



 $ perl -Ilib -e 'use MyApp; my $obj =
 MyApp-model('Schema::User')-find(bogus); print defined?  . ( defined
 $obj ? yes : no ) . \n';
  no


 DBIx::Class::ResultSet::find(): DBI Exception: DBD::Pg::st execute failed:
ERROR:  invalid input syntax for integer: bogus [for Statement SELECT
me.id ...

sub safe_find {
 my ( $self, $id ) = @_;
 if ( $id =~ /^(\d+)$/ ) {
  return $self-find($1);
 }
 die I pity the fool;
 }


Yes, that's one approach.But, I'm not sure I can think of a reason why I
would not want to always do that, so might as well just override find (or
really search_rs, as that is what is called by find) and check id (or ids)
there.  But, there need to think about where, columns, and so on.



-- 
Bill Moseley
mose...@hank.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/


Re: [Catalyst] Re: Validating single arg id

2009-10-17 Thread Bill Moseley
On Sat, Oct 17, 2009 at 12:50 PM, Aristotle Pagaltzis pagalt...@gmx.dewrote:

 * iain iainhubb...@googlemail.com [2009-10-16 17:30]:
  until we did this we had boilerplate validation at the top of
  all the local actions.

 ++

 Bill, in another thread you asked me for an example of how
 Chained helps make things like complex auth checks more DRY. I’ve
 been meaning to respond with an example out of my $job codebase,
 but until I get around to it, here’s your hands-on example of
 something it’d buy your codebase immediately. :-)


I meant to respond about that.  Perhaps I'm missing something, but the
chained example works great if there multiple actions that need to get at
that Foo object.  They can all chain back to the same root which validates
the id and then fetches the Foo object with that id and stuffs it into the
stash.

But, its often the case (well, my case) that there's only *one* action that
fetches Foo, but there's also single actions for find()ing a number of other
objects.  If I'm following the chained example correctly, then there would
be root for each -- Foo, Bar, Baz, and so on each running basically the same
validation.  I suppose the root can be written in a way to fetch many
different object types by inspecting the current action and thus the fetch
for Foo, Bar, Baz, etc. objects could all have the same root of the chain.

If I have many actions that do $c-model( $whatever )-find( $id ) and I
want to validate id doesn't it seems like find() (or really search_rs() )
would be the method to override?

Perhaps a better approach would be add a safe_find() as J. Shirley
suggested, but what good are methods if you don't override them. ;)



-- 
Bill Moseley
mose...@hank.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/


Re: [Catalyst] Re: Adding default query parameters to generated links.

2009-10-17 Thread Bill Moseley
On Sat, Oct 17, 2009 at 12:42 PM, Aristotle Pagaltzis pagalt...@gmx.dewrote:

 * Tomas Doran bobtf...@bobtfish.net [2009-10-13 00:00]:
  I'd very likely go with this myself.
 
  You can apply it as a role, and then trivially remove it later,
  it's wrapping one method and so low impact, and there are no
  negative consequences if your session goes away for any
  reason..
 
  Just feels like less moving parts to me...

 Less implicit state on the server = better HTTP style:


I agree with you here.


 • Easier to scale: at the app level, no session to replicate
  between web servers or communicate via the DB; above the app
  level, easier to use proxies to selectively route/cache stuff
  by inspecting URIs


I wish that was possible, but in this case the session data structure is a
beast.
I'm currently pulling data from the existing app's session and populating
$c-session for the data
that needs to be used.



 • Better user experience: allows multiple tabs with different
  interaction state in each


This is something you have mentioned before, and I'm on board with this.  I
assume you mean a session id in the URL, right?

http://en.wikipedia.org/wiki/Session_fixation#Do_not_accept_session_identifiers_from_GET_.2F_POST_variables

recommends not having a session id in the URL.  One way to mitigate risks is
by changing session ids often (as recommended by the article).  But, assumes
web requests are serial in nature, which they are not.  So, it's not that
simple to just send back a new session id every request or ever few minutes.



-- 
Bill Moseley
mose...@hank.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/


Re: [Catalyst] Re: Validating single arg id

2009-10-21 Thread Bill Moseley
On Wed, Oct 21, 2009 at 6:52 AM, Aristotle Pagaltzis pagalt...@gmx.dewrote:

 * Zbigniew Lukasiak zzb...@gmail.com [2009-10-21 14:15]:
  What is the advantage of this over:
 
  sub view : Local {
   my ( $self, $c, $id ) = @_;
   $self-start( $c, $id );
   # do something with $c-stash-{obj}
   return 1;
  }

 Consider `/forum/7/topic/13/post/4/editform`. The end point in
 that chain would be

sub editform : Chained('post') {
my ( $self, $c ) = @_;
# ...
}

 The equivalent URI with Local would be `/editpost/7/13/4` and the
 action would look like this:

sub editform : Local {
my ( $self, $c, $forum, $topic, $post ) = @_;
$self-load_post( $forum, $topic, $post );
# ...
}


I think that depends on your data.  If $forum, $topic, and $post make up a
path on disk then yes, the chain is really useful.
If $post is a primary key and there's a relationship $post-topic-forum
then there's no need for those, of course, and confusion if $post-topic is
not the same id as passed in the URL for the forum.

Perhaps a good use for the chain there is for access control -- the current
user might only have access to some forums so a chain makes it easy to do
that kind of validation early in the chain and then detach if access fails.

The chain also allows fetching the $forum and $topic objects and place them
in the stash.  But, again if they are related can load the $post with a join
and avoid separate calls to the database.  (But, it may be the case that
caching the $forum and $topic individually make sense.)

Anyway, my actions often look like this: (a bit oversimplified)

package MyApp::Forum::Post;
sub view : Local {
my ( $self, $c, $post_id ) = @_;

$c-stash-{post} = $c-user-fetch_post( $id ) || return
$c-res-status( 404 );
}

Kind of ugly calling that on the user object, but it's just an example.
That method, for example, might do a join with the forum and topic tables
and also with a permissions table to make sure the user can access the post.

I do prefer the /forum/post/334/view type of URLs, though, but my CRUD
actions often end up like this:

   /forum/post - list
   /forum/post/edit  - create (POST)
   /forum/post/edit/22 - view (GET) update (PUT/POST)
   /forum/post/delete/22

And it's very DRY because there's separate model method for each.

The create method may have a different URL structure to specify the topic,
or it might be ?topic=123, or it might be part of the post parameters.





-- 
Bill Moseley
mose...@hank.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/


Re: [Catalyst] Question about C:P:Unicode(::Encoding)

2009-10-24 Thread Bill Moseley
On Sat, Oct 24, 2009 at 1:26 PM, Bernhard Graf cataly...@augensalat.dewrote:

 These plugins hook into prepare_parameters() to decode data.

 Why does it leave query_- and body_parameters untouched?


Always seemed like a bug to me.


http://www.mail-archive.com/catalyst@lists.scsys.co.uk/msg02350.html
http://www.mail-archive.com/catalyst@lists.scsys.co.uk/msg05312.html
http://www.mail-archive.com/catalyst@lists.scsys.co.uk/msg04321.html

I wonder about something like this, although might be cases where there's
something in there that should not be decoded.

after 'prepare_body_parameters' = sub {
my $c = shift;

my $v = Data::Visitor::Callback-new(
ignore_return_values = 1,
value= sub {
$_ = decode_utf8( $_, $CHECK ) unless Encode::is_utf8( $_ );
},
);

$v-visit( $c-req-body_parameters );

return;
};

Although I have cryptic notes elsewhere where I had problems with
Data::Visitor.  Hum, should have taken better notes.






-- 
Bill Moseley
mose...@hank.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/


[Catalyst] Suppressing exceptions in Engine / UploadProgress

2009-11-08 Thread Bill Moseley
I'm running under mod_perl, and when a user aborts an upload I get an error
in the log.

[error] Caught exception in engine Apache2::RequestIO::read: (70014)
End of file found at /usr/local/share/perl/5.10.0/Catalyst/Engine/Apache.pm
line 187

I don't see that it's possible, but is there any way to ignore some
exceptions (similar to how execute() can ignore a detach)?   Not sure
there's a good case for it, other than to simply ignore the above.  (I can
modify my log monitoring to ignore those, for example).  But, there doesnt's
seen to be any way to get out of that block without generating an error
message.

eval {
if ($class-debug) {
my $secs = time - $START || 1;
my $av = sprintf '%.3f', $COUNT / $secs;
my $time = localtime time;
$class-log-info(*** Request $COUNT ($av/s) [$$] [$time] ***);

}

my $c = $class-prepare(@arguments);
$c-dispatch;
$status = $c-finalize;
};

if ( my $error = $@ ) {
chomp $error;
$class-log-error(qq/Caught exception in engine $error/);

}



Maybe I could override prepare() and return a different $c object with dummy
dispatch and finalize methods, but I suspect another prepare() and that
approach would break.

BTW -- I was looking at this along with the UploadProgress plugin.  It does
this to catch aborted uploads.
The plugin is a bit old, but doesn't seem like overriding croak is a good
way to catch exceptions.  Is there any reason not to wrap prepare_body in an
eval?   Yep, I just tried and under mod_perl2 this doesn't catch aborted
uploads.

my $croaked;

{
no warnings 'redefine';
local *Carp::croak = sub {
$croaked = shift;
};

$c-NEXT::prepare_body(@_);

}

if ( $croaked ) {
if ( my $id = $c-req-query_parameters-{progress_id} ) {
$c-log-info( UploadProgress: User aborted upload $id );


# Update progress to flag this so javascript will stop polling
my $progress = $c-cache-get( 'upload_progress_' . $id ) || {};

$progress-{aborted} = 1;


$c-cache-set( 'upload_progress_' . $id, $progress );
}

# rethrow the error
Catalyst::Exception-throw( $croaked );
}







-- 
Bill Moseley
mose...@hank.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/


[Catalyst] Request: Wrong Content-Length value: 2628941

2009-11-15 Thread Bill Moseley
I see this error every once in a while.  It does not seem like an aborted
connection (I get a different error for that).  Is there any other reason
why the read() method might returning false before done.

   while ( my $buffer = $self-read($c) ) {
$c-prepare_body_chunk($buffer);
}

I suppose if $buffer just happened to be zero.  Probably should be checking
defined there.


Could this message be updated to report the length of the body read, too?
And maybe display the last X bytes of data read might be useful in some
cases.

-- 
Bill Moseley
mose...@hank.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/


Re: [Catalyst] Re: Language selection in URLs

2009-11-18 Thread Bill Moseley
On Wed, Nov 18, 2009 at 9:55 AM, Aristotle Pagaltzis pagalt...@gmx.dewrote:

 * Joel Bernstein j...@fysh.org [2009-11-15 16:30]:
  No no no! Allow the client and server to negotiate what content
  to serve for the resource identified. As a URI to a resource
  which may vary according to many dimensions,
  /path/to/some/content is fine.
 
  GET /path/to/content HTTP/1.1
  Accept-Language: en
  Accept: text/html

 Conneg sucks. It’s a good idea for non-human-readable content
 served in a variety of formats, but for variants of anything
 that’s like a “page” you should have separate URIs, so that
 people can reliably bookmark one of them, or send someone else
 a link to talk about it and not have the other person see
 a completely different page (or file or whatever), etc.

 It’s OK to accept conneg on neutral URIs and then *redirect* to
 specific URIs based on the Accept-* headers. But don’t make
 conneg the *only* way to pick a specific version of a resource.


I think this is very good advice.




  If you really must stick it in the URL, I'd go for something like:
  /path/to/content/en
  /path/to/content/pt_BR
  etc

 Worst of all worlds, IMO. The query parameter is easiest to
 implement for the server, while the path prefix allows the user
 to hack the URI conveniently (so the latter is what I would do).
 Your suggestion is harder to implement than both and makes URIs
 annoying to hack.


I think Catalyst makes the path prefix the easiest.  WIth the query
parameter (which I'm doing now to be compliant with a legacy app) it's
trivial to by using around uri_for, but I'd much rather do something once
(modify $-req-base) than override every uri_for.

I do have a slight fear of the query parameter messing with caching.  I
doubt it's much of an issue these days, though.


-- 
Bill Moseley
mose...@hank.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/


Re: [Catalyst] Avoiding UTF8 in Catalyst

2009-11-21 Thread Bill Moseley
On Sat, Nov 21, 2009 at 2:22 PM, Marc SCHAEFER schae...@alphanet.ch wrote:

 Hi,

 my goal: no UTF8, in short:


Can you explain why?  That sounds like something to regret later down the
road.
Even if your templates have latin1 characters you can still output utf8.
Less to to worry about with entity encoding, I guess.




   - all the perl code, all the data files, all the template files and
 the UNIX locale are all in ISO-8859-1


Hopefully you don't have much text in your perl code.  Get the database into
utf8 will be a win long term.




   - the HTML result should be in ISO-8859-1
 (Content-Type: text/html; charset=iso-8859-1)


You need to encode the body, too. Plugin: Unicode::Encoding was just updated
by Tom, IIRC.




   - the Content-Length: should be correct.

 First, I modified lib/MyApp/View/TT.pm as follows:

   __PACKAGE__-config(TEMPLATE_EXTENSION = '.tt',
   DEFAULT_ENCODING   = 'ISO-8859-1',
   WRAPPER = 'wrapper.tt');


There's a DEFAULT_ENCODING option?  Isn't it just ENCODING?




 Apparently all diacritic characters are expanded into HTML entities.


Where does that happen?




-- 
Bill Moseley
mose...@hank.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/


Re: [Catalyst] Avoiding UTF8 in Catalyst

2009-11-23 Thread Bill Moseley
On Mon, Nov 23, 2009 at 2:01 AM, Marc SCHAEFER schae...@alphanet.ch wrote:
 On Sat, Nov 21, 2009 at 05:16:24PM -0800, Bill Moseley wrote:
  Apparently all diacritic characters are expanded into HTML entities.

 Where does that happen?

 It looks like it's TT::View's htmlentity which does this, not just for
  and friends.  It's not a big issue for me. Maybe it could even be
 parametered.


Still not following.   You are talking about Catalyst::View::TT?


BTW -- when looking at C::V::TT I see where you got that DEFAULT_ENCODING
from -- it's documented in C::V::TT.

As far as I know there's no such setting in Template Toolkit.  There's
ENCODING to specify the encoding of your templates.

If your templates are 8859-1 with 8 bit characters my suggestion would be to
convert them to utf-8 and set ENCODING to utf8 for the templates, and move
toward utf8 everywhere.Make sure you use the plugin to decode and
encode.





-- 
Bill Moseley
mose...@hank.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/


Re: [Catalyst] Re: Avoiding UTF8 in Catalyst

2009-11-23 Thread Bill Moseley
On Mon, Nov 23, 2009 at 10:14 AM, Aristotle Pagaltzis pagalt...@gmx.dewrote:




 Encode the string to the destination encoding (not just character
 set), so that the string represents an encoded octet stream, and
 then look at the plain old character length of that string. That
 will always give you the right answer, regardless of whether that
 string is packed bytes or variable-width integers.


Correct.  And I'd argue that when it's time to set the length it should die
if utf8 flag is still set.

When calculating the length the content should have already been encoded.

Again, at some point decoding and encoding  should be core not just a
plugin.  It's an important part of the request cycle.



-- 
Bill Moseley
mose...@hank.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/


Re: [Catalyst] Request: Wrong Content-Length value: 2628941

2009-11-30 Thread Bill Moseley
On Mon, Nov 30, 2009 at 6:21 PM, Tomas Doran bobtf...@bobtfish.net wrote:

 On 15 Nov 2009, at 16:07, Tomas Doran wrote:

  I suppose if $buffer just happened to be zero.  Probably should be
 checking defined there.


 Yep, that should be fixed.


 This has been fixed in trunk, r12100

 http://dev.catalystframework.org/svnweb/Catalyst/revision?rev=12100

 Does that look sane to you?


Sure.   Always good to have sane code.  Thanks for taking time for this.

Like I said, I get these errors every so often, and it would be nice to
understand why -- not sure if it's a broken client or perhaps some encoding
error.  Not sure what additional error message would be helpful, though.


Thanks again,




-- 
Bill Moseley
mose...@hank.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/


[Catalyst] Sub-classing Application

2009-12-16 Thread Bill Moseley
I have an existing application Foo.  I'd like to create a new application
Bar that has very similar actions.

What I'm wondering is if there's a way where I could run catalyst.pl Bar to
create a new empty application and then tell it to inherit from Foo.  That
is load_components would load all of Foo's Models, View, Controllers
(basically creating in-memory empty sub-classes for each component) and
setting up all actions as if they were in Bar.  I could then override or add
additinal actions as needed to Bar::Controller::Whatever, which would
inherit from Foo::Controller::Whatever.

Any ideas how to implement something like that?

-- 
Bill Moseley
mose...@hank.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/


Re: [Catalyst] Sub-classing Application

2009-12-16 Thread Bill Moseley
On Wed, Dec 16, 2009 at 8:31 AM, J. Shirley jshir...@gmail.com wrote:



 The documentation seems quite sparse, but if you look at the source it
 just essentially does:
my $locator = Module::Pluggable::Object-new(
search_path = [ map { s/^(?=::)/$class/; $_; } @paths ],
%$config
);

 If you have MyApp-config-{search_extra} = [ 'Foo::Controller',
 'Foo::Model' ]; it should DTRT.


It almost works, but it sets up actions for both controllers using each
controller's class.

That is, if I start application Bar and pass in search_extra = [qw/
Foo::Controller / ] then indeed actions from Foo::Controller::* will get
added to the application.

But, they are added with the Foo:: namespace.  that is, that controller is
not a parent-class of Bar::Controller::*.

It also means I can't easly overide.  If I have hello() in both thes
controllers:

Foo::Controller::Whatever::hello()
Bar::Controller::Whatever::hello()

I then get:

[debug] Loaded Path actions:
.-+--.
| Path| Private
|
+-+--+
| /   | /index
|
| /   | /index
|
| /   | /default
|
| /   | /default
|
| /whatever/hello | /whatever/hello
|
| /whatever/hello | /whatever/hello
|
| /whatever/howdy | /whatever/howdy
|
'-+--'

So, I guess what I really would like is a way to have it load the Foo::*
modules but register their actions in the associated Bar:: namespace
so that /whatever/hello calls Bar::Whatever::hello but Foo::Whatever is the
parent class if hello() doesn't exist in Bar.

(That sentense make sense?)

I guess that means when Foo::Controller::Whatever is found, register the
actions in the Bar::Whatever namespace and push Foo::Whatever onto
@Bar::Whatever::ISA.


The problem I'm looking at is rebranding applications.  In the past I've
managed to modify config based on, say, domain name and use a different root
(for templates, css, images, etc.)  But, over time the application has to be
forked due to changes in code.  But, 90% of the controller code is still the
same between the two applications.

So, it would be handy to say, this application inheits from Foo, but these
with a few methods added or overridden.





-- 
Bill Moseley
mose...@hank.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/


Re: [Catalyst] Sub-classing Application

2009-12-16 Thread Bill Moseley
On Wed, Dec 16, 2009 at 9:59 AM, J. Shirley jshir...@gmail.com wrote:


 It seems you're after something that would best be accomplished using
 roles that get composed into the controller.


Ah, of course.  I think that's a good idea.  I rewrote a bunch of plugins
and other code using Roles and indeed it was pretty painless.

Means I need to make mostly duplicate and empty controllers for both Foo and
Bar applications but seems like a reasonable price to pay.

Now, I just need to think about good ways to inherit my temples (if not
simply modifying my INCLUDE_PATH) so that templates can be shared (or
overridden).

Thanks,




-- 
Bill Moseley
mose...@hank.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/


Re: [Catalyst] Sub-classing Application

2010-01-04 Thread Bill Moseley
On Sun, Dec 20, 2009 at 3:05 PM, Matthias Dietrich mdietr...@cpan.orgwrote:

 Hi,

 I'd like to catch up this slightly old topic...

 I've build a small app for a customer and want to pull out some sections to
 build a small CMS I can use in several upcoming apps.  I don't want to
 copy-paste everything everytime an app comes up or update all instances.  So
 it would be very nice to teach an arbitrary Catalyst app to glue everything
 from another app (controllers, models *and* views (note: html and static
 files, too!)) into the arbitrary app.

 There were several ideas in the past on this list to featurize apps, like
 the solution CatalystX::Featurizer/CatalystX::Features posted by Rodrigo.
  The problem with this solution is: features cannot just be released to
 CPAN and used by other persons without requiring them to change their
 Catalyst app heavily.  What I'm thinking of is something like use
 base/parent with specifying an action where the external Catalyst app is
 connected.


I'm more concerned about code reuse and maintenance in a set of large and
similar applications.   CatalystX::Features seems like a good approach for a
large application that is made up of different features (or products) that
may be managed by different teams.

That's a slightly different problem than one of code-reuse I initially
posted about.  In addition to the need to have features/components/products
managed separately and combined into a larger application I need to use
those parts in different applications that are slightly different.

That is, I need a second application that is very similar to the first, but
with slightly different controllers and somewhat different templates, css,
js. etc.

So, I've been thinking about building the controllers as Moose roles.  Then
build CatalystX::Features grouped by application where the Feature's
controllers use the roles (and override as needed).

I'm much less clear how to reuse/share templates and css between
applications -- but in that case it might just be better to copy.

The trade-off will be files scattered all over the place, something
developers are still trying to get used to with basic Catalyst.  Maybe
someone here can come up with something more clever.  But, do need a better
way to manage large applications.

I'm also debating CatalystX::Features approach vs. just using separate
applications (with shared sessions, etc.).  That's a bit more flexible for
deployment (e.g. some features on a subset of servers) but sharing of common
templates, css, js, etc. is more of a challenge.



-- 
Bill Moseley
mose...@hank.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/


Re: [Catalyst] proper flow control with $c-foward, in search of greater grok

2010-01-08 Thread Bill Moseley
On Fri, Jan 8, 2010 at 6:55 AM, Tomas Doran bobtf...@bobtfish.net wrote:




 $c-response-redirect($c-uri_for(/user/$user_id/blog/$blog_id/entry/list));


 Eww, don't do that.

 You want
 $c-response-redirect($c-uri_for_action('/user/blog/entry/list',
 [$user_id, $blog_id]));


I agree that's the right approach, but not sure I see why the Eww in this
specific case.  Can you explain?



-- 
Bill Moseley
mose...@hank.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/


[Catalyst] Not cleaning up temporary files / HTTP::Body

2010-01-13 Thread Bill Moseley
HTTP::Body::Multipart creates temporary files for uploads.  The temp files
are created with File::Temp( UNLINK = 1 ).

Catalyst then deletes these temp files in $c-finalize.  The problem is that
an exception can happen and then the temp files are not deleted.
Happens quite often, it turns out.  I seem to always see this in the logs at
the time of the orphaned temp file:

Caught exception in engine Apache2::RequestIO::read: (104) Connection reset
by peer

Aborting an upload isn't that unusual.

I can set temp directory for these uploads and use cron to clean them out,
but I wonder if they could not be cleaned up better automatically.

For example, unlink in DESTROY when the request object goes out of scope.
Or perhaps better, don't have HTTP::Body set UNLINK = 1 by default and when
the upload object finally goes out of scope File::Temp will remove the temp
file. HTTP::Body explicitly removes the File::Temp object from the upload
part, but I'm not sure why it needs to do that.   Why not leave the
File::Temp object in the upload part object then let it go out of scope at
the end of the request.

Where should this be addressed?  In Catalyst or in HTTP::Body?

-- 
Bill Moseley
mose...@hank.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/


Re: [Catalyst] Re: modules for conditional GET ?

2010-01-18 Thread Bill Moseley
On Sun, Jan 17, 2010 at 11:35 PM, Dami Laurent (PJ) 
laurent.d...@justice.ge.ch wrote:




 Indeed, this is exactly what I want to do. The app has a config file (not a
 Catalyst
 config file, but another file having to do with business logic), and some
 super-users
 have a mechanism for hot uploading of a new config to the server, at any
 time.
 A few app pages are expensive to compute, and they depend on the client and
 on that config file. So clients should keep asking for those pages at each
 request, and depending on the If-Modified-Since header and on the timestamp
 for the config file, the server can decide if it's worth recomputing the
 page for that client, or rather send a cheap 304 Not Modified.


Be careful about using timestamps if you are running multiple web servers
behind a load balancer (or may expand to where you will be behind a
balancer).  Here's a read on Etags:

 http://developer.yahoo.net/blog/archives/2007/07/high_performanc_11.html

For resources such as css, js, images I tend to create URLs that include an
md5.  Those include cache headers that don't expire and thus when the
content changes the URL changes.

I have also done that with text/html pages, but it's less common.  For a
config file you can send the config through Object::Signature to get an
md5.  You could recalculate and cache that whenever a new config is
uploaded.

For static pages (for non-logged in users) the pages tend to get cached
for some number of minutes as it's not critical that a change is seen
exactly the same time by all users.  Dynamic content is not cached, of
course, but elements of the page may be cached in memcached.



-- 
Bill Moseley
mose...@hank.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/


Re: [Catalyst] Error handling

2010-01-20 Thread Bill Moseley
On Mon, Jan 18, 2010 at 9:05 AM, Steve Kleiman st...@prodhub.com wrote:

 Thanks for all the feedback on how to log from within a schema. Log4perl is
 my hero.

 I'm still looking for a way to capture runtime errors and ideally email
 them out in addition to logging to a file.


I use log4perl to send error level messages to an additional log file.
Then I use cron to check for errors every few minutes and send a
notification email.  I like that better than the possibility of hundreds of
processes cranking out mail at the same time.

The plan is to move to a logging server to centralize this a bit more.




-- 
Bill Moseley
mose...@hank.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/


[Catalyst] Catalyst::Controller::REST vs. Catalyst::Controller::DBIC::API

2010-01-21 Thread Bill Moseley
I'm looking at adding an API interface to an application and looking at the
modules listed in the subject.  Anyone have experience with both?  Any
recommendations or experiences you can share?

I have another application that I added an API to using XML RPC.  It works
by adding attributes to actions not unlike
Catalyst::Plugin::Server::XMLRPC.  It's been very helpful to have the API
use the exact same controller actions as the web interface.  Some of the
existing controllers contain complex logic, so obviously want to use that
same code for the API as well.


-- 
Bill Moseley
mose...@hank.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/


[Catalyst] How to de-serialize json?

2010-01-23 Thread Bill Moseley
Following up on our recent simulating discussion on adding an API to an
application, I wonder is someone can help me understand something:

Catalyst uses HTTP::Body to parse body content.  It currently handles these
request content types:

our $TYPES = {
'application/octet-stream'  = 'HTTP::Body::OctetStream',
'application/x-www-form-urlencoded' = 'HTTP::Body::UrlEncoded',
'multipart/form-data'   = 'HTTP::Body::MultiPart',
'multipart/related' = 'HTTP::Body::XFormsMultipart',
'application/xml'   = 'HTTP::Body::XForms'
};

But, Catalyst::Controller::DBIC::API and Catalyst::Controller::Rest both use
Catalyst::Action::Deserialize.

My question is this:  why use an action class instead of extending
HTTP::Body to deserialize the content?  Isn't it HTTP::Body's job to decode
the body based on the content-type of the request?

I'm just wondering if I'm missing some important reason why these other
request content types are handled differently.

Seems like HTTP::Body is the correct place to do all decoding.  Decoded
JSON, for example, would just end up in $c-req-params and controllers
could be oblivious to the encoding of the request (similar to how we don't
really care how params are decoded if the body is x-www-form-urlencoded or
form-data).   True, could end up with a request parameter that is a hashref,
but I don't see anything wrong with that as long as parameters are validated
correctly.

So, why different approaches to decoding request body content?



-- 
Bill Moseley
mose...@hank.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/


Re: [Catalyst] How to de-serialize json?

2010-01-23 Thread Bill Moseley
On Sat, Jan 23, 2010 at 1:40 PM, J. Shirley jshir...@gmail.com wrote:



 If I assume that decoding is synonymous with de-serialization, it
 makes more sense.  At first thought, I just don't think they're that
 similar, though.  Maybe in implementations (comparing JSON to HTTP
 POST parameters) it is, but in the case of HTTP::Body decoding a
 mime64-encoded JPEG, it isn't at all.



With a jpeg I assume the content type would be form-data (that included an
upload in the form) where the file ends up in $req-uploads, not as a
request parameter.

I find decoding requests analogous to Views.  In my apps controllers take
input (params, arguments and uploads) and the result is data in the stash.
 Then the View has the job of serializing (normally to HTML via template,
but no reason it can't be JSON or anything else).  In fact I have many
controller actions that are used for both normal full-page HTTP requests and
AJAX requests.  So, similar to how the controller action does not know or
care what view is going to be used, the controller action doesn't know or
care how the request is serialized over the wire.  That's how I picture it.




 From a behavior standpoint, having a POST/PUT'd JSON segment that ends
 up in -params would be maddening to me.  They aren't parameters, not
 even in the loosest of the RFC interpretations.


I'm trying to understand that point of view.  Why is that maddening?  If you
have a request serialized as json then $req-parameters would go unused and
instead have the deserialzed request end up some place else, say as
$req-data?

I have an XMLRPC API to an application.  I implemented it by creating an
HTTP::Body subclass that parses the XMLRPC XML body.  The method ends up
mapped to an action, the params ends up as body parameters, and base64
elements end up as uploads.  As a result existing controller actions can be
used for both XMLRPC request and for normal web requests.  All I have to do
to expose the action in the API is add  XMLRPC( $method_name ) as a action
attribute.

Catalyst::Engine hard-codes HTTP::Body.  I think it would be more flexible
if the body parser class could be a config option (to allow easy
sub-classing), -- similar to how the request class can be defined -- but
it's not that difficult to set up now.   Just have to add the content type
to  %HTTP::Body::TYPES.

Thanks for your comments, I appreciate the feedback.


-- 
Bill Moseley
mose...@hank.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/


Re: [Catalyst] How to de-serialize json?

2010-01-23 Thread Bill Moseley
On Sat, Jan 23, 2010 at 5:39 PM, Hans Dieter Pearcey 
hdp.perl.catalyst.us...@weftsoar.net wrote:

 Excerpts from Bill Moseley's message of Sat Jan 23 19:45:28 -0500 2010:

  With a jpeg I assume the content type would be form-data (that included
 an
  upload in the form) where the file ends up in $req-uploads, not as a
  request parameter.

 That assumption may hold true for *your* applications, but he didn't say
 anything about a form or even a web browser.  It's perfectly reasonable,
 especially in the context of REST APIs, to talk about non-form-based
 request
 bodies.  (I've written actions that accepted PUT requests with a
 content-type
 of application/vnd.ms-excel, for example.)


But, that's a different content type.  I assumed form-data.  So, in this
case in my HTTP::Body deserialization layer approach, I'd thus add:

   $HTTP::Body::Types('application/vnd.ms-excel') = 'My::ExcelParser';

which would result in $req-uploads having an upload object for the
spreadsheet.  My::ExcelParser would probably be a thin sub-class of
something like My::Upload.  Then the same controller would work with both a
web request with an upload field or this REST request and expect to find the
upload object in $req-uploads.



-- 
Bill Moseley
mose...@hank.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/


Re: [Catalyst] How to de-serialize json?

2010-01-24 Thread Bill Moseley
On Sat, Jan 23, 2010 at 7:20 PM, Hans Dieter Pearcey 
hdp.perl.catalyst.us...@weftsoar.net wrote:


 As far as I can tell, you missed the point of my message, which makes me
 wonder
 if I've missed the point of yours.  Are you talking about a set of
 conventions
 you'd like to be able to build for your own use on top of HTTP::Body, or a
 set
 of conventions that you expect everyone will want and so should be built
 into
 HTTP::Body, or something else entirely?


I thought you were saying that the request might not be a normal form
posting, and I was saying only that HTTP::Body can support that, too.
I was not suggesting everyone should use one method over another.

HTTP::Body seems (to me) like the natural place to deserialize.  Yet, the
REST modules I cited use an action class to deserialize.  Thus, I was
wondering if there was a specific reasons for that approach that I had not
understood.  That's really all.





-- 
Bill Moseley
mose...@hank.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/


Re: [Catalyst] Where is the form field lost?

2010-01-24 Thread Bill Moseley
On Sun, Jan 24, 2010 at 7:03 AM, Octavian Rasnita orasn...@gmail.comwrote:

 I need to know if the form didn't have a file upload field, or if it had it

but no file was uploaded.


Give your upload field(s) a name like upload_1  and then see if it exists
in uploads.


Can you give me a hint where I should look for finding where the empty file
 upload field is skipped if it is empty?


That's how HTTP::Body works.   If there's a filename, which there is with
upload fields, but the file name is empty, then it's skipped.

if ( exists $part-{filename} ) {
if ( $part-{filename} ne  ) {
$part-{fh}-close if defined $part-{fh};

delete @{$part}{qw[ data done fh ]};

$self-upload( $part-{name}, $part );
}
}

BTW -- I think that delete of fh should not happen (and the temp file
should be set to unlink on destroy).  Otherwise you can end up with orphaned
temp files.

-- 
Bill Moseley
mose...@hank.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/


Re: [Catalyst] Where is the form field lost?

2010-01-24 Thread Bill Moseley
On Sun, Jan 24, 2010 at 8:31 AM, Octavian Rasnita orasn...@gmail.comwrote:


 Give your upload field(s) a name like upload_1  and then see if it
 exists
 in uploads.


 I gave it the name file, but if the file is not uploaded, it doesn't
 appear in uploads(). (I hope file is OK as a name, no?)


Why do you need to know that a field existed on the form but was submitted
empty?  Checkboxes don't submit if not checked.  You get what's included in
the post and have to work from that.  Either you have an upload or not,
right?




Aha, so I should look better in HTTP::Body.

Is there a reason it does that? (Leaves alone all other empty form fields
 but deletes the empty file upload fields?)


Without commends in the code or documentation can't really know the author's
reasoning.   I guess it assume uploads go to temp files and no need to do
that if there's no content.

(IIRC, I thought filename was optional, but maybe I'm mistaken.)

I'm kind of curious why it does this:


if ( $part-{fh}  ( my $length = length( $part-{data} ) ) ) {
$part-{fh}-write( substr( $part-{data}, 0, $length, '' ), $length
);
}

instead of:

print $part-{fh} $part-{data} if $part-{fh};

Maybe for fear of line ending conversion??




-- 
Bill Moseley
mose...@hank.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/


Re: [Catalyst] UTF-8 and mails

2010-01-25 Thread Bill Moseley
On Mon, Jan 25, 2010 at 6:54 AM, Bernhard Graf cataly...@augensalat.dewrote:


 Does Mail::Sender::Easy automatically encode _text into the encoding
 given in charset? If not, then /you/ have to do it:
 Encode::encode(utf-8, $string);


That's what I do.   Specifically, I have this for generating inline text
emails:


for my $template ( @templates ) {
my $body_content = $self-render_email_template( $template,
$c-{stash} );

push @parts, Email::MIME-create(
attributes = {
content_type = ( $template =~ /_html$/ ? 'text/html' :
'text/plain' ),
charset  = 'utf-8',
disposition  = 'inline',
encoding = 'base64',
},
body = encode_utf8( $body_content ),
);
}

}



 Concerning use utf8: As soon as you have any non-ASCII literals in
 your code (Herr Müller), then you want to use that, BUT only if your
 perl code file is also utf-8 encoded. Read the perl man pages about
 unicode, if you are not sure. Read them twice, and then once more. ;-)
 It's not a shame, if you don't get the whole picture at first.


And IMO string literals are better left in templates, in the databaes, and
.po files.

I use English, so I don't worry about utf-8 variable names.  I always
assumed at some point utf8 would become the default for Perl source, though.



-- 
Bill Moseley
mose...@hank.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/


Re: [Catalyst] How to de-serialize json?

2010-01-27 Thread Bill Moseley
On Tue, Jan 26, 2010 at 6:33 AM, J. Shirley jshir...@gmail.com wrote:



 I'm all for reusable code, but in no way should HTTP::Body start
 taking this behavior by default.  I'm not really that sure how
 effective it is, anyway.


No, I was not suggesting that would be the default (although I'm not sure
why not handling other serializations by default is a bad idea).  Not sure
what you mean by effective.


 decode_json( $c-req-body ); Is just not that hard :)


Of course it's not that hard.  Of course, this isn't hard, either:  [1]

map { s/%([0-9A-Fa-f]{2})/chr(hex($1))/eg; $_ } split /[;=]/,
$c-req-body;

I see those as similar operations.  The request is serialized in both cases.

But, one should not have to worry about adding low-level details like that
to application code when using an elegant web framework. ;)


No big deal.  I was just curious why the HTTP::Body approach was not used in
the existing REST/RPC modules, as that was already the place used by
Catalyst to de-serialize the body.  I thought maybe there was a reason I
might not understood, which is why I asked.

[1] Or whatever the correct approach is, and apologies to Damian for the
map.

-- 
Bill Moseley
mose...@hank.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/


Re: [Catalyst] How to de-serialize json?

2010-01-27 Thread Bill Moseley
On Wed, Jan 27, 2010 at 1:16 PM, Tomas Doran bobtf...@bobtfish.net wrote:


 On 27 Jan 2010, at 15:33, Bill Moseley wrote:


 No big deal.  I was just curious why the HTTP::Body approach was not used
 in the existing REST/RPC modules, as that was already the place used by
 Catalyst to de-serialize the body.  I thought maybe there was a reason I
 might not understood, which is why I asked.


 HTTP::Body isn't really structured for this - you can (and I _do_ in one of
 my apps) add or override the content type handlers.

 However as it's class data, this is perl interpreter wide - which means
 that two different applications with conflicting requirements can't exist in
 the same mod_perl interpreter - not awesome.


I see.  So you are saying that Content-Type: application/json might need to
be deserialized differently in different applications that share the same
interpreter?  Obviously, json could decode into an array ref so that could
not be mapped to request parameters.  Is that what you mean?  Or that an
application might want the raw json?

-- 
Bill Moseley
mose...@hank.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/


Re: [Catalyst] Using Catalyst with mod_per or FastCGI on heavy traffic web application

2010-01-29 Thread Bill Moseley
Just so it's not one-sided, I moved from FastCGI to mod_perl some years
back. Start up and restart time was one issue, IIRC, but mod_perl was
trivial to configure and solved stability issues we were seeing.  I never
went back, so maybe it's better now.  Is there now a manager that will spawn
more FastCGI processes based on load?

The Catalyst server is used for development.  The app knows it's running
with that engine and disables the SSL requirements, but logs that the page
would be blocked if not in SSL.

Starting different configurations is no problem at all.  I have an app
startup script that generates the httpd.conf file from configuration files
at startup time.  It's basically start_app --app=foo --mode=testing.   The
apps have dev, testing, qa, stating, and production modes, so as you can see
it's not a big deal.  All those are on different machines, but different
modes can use different ports, of course, so can be on the same machine.

I'm usingCronolog so there's no log rotation/restart needs.

mod_perl does seem a bit heavy weight just to serve requests, especially
since all we use is the response handler.  We also don't use many modules
(SSL is not handled by Apache).  I've meant to look at other server options,
but there's not pressing need.

I don't really see how what server you use effects error messages.  Stderr
is stderr.   I would never use the canned Apache error responses anyway for
a site.

True, Apache can run as only one user.  But, that's normally the apache (or
whatever) user which has very limited access, which is what you want.  So, I
don't see a benefit of running as different users.  Apps may need to run on
multiple machines so only part of the file system need access to would be
for temp files.

I think mod_perl is daunting to some due to all the possibilities (and
default httpd.conf Apache provides) but really the config required to get it
to serve a Catalyst app is just a few lines.  My entire files are pretty
small:

$ fgrep -v '#' httpd.conf | grep -v '^$' |grep -v LoadModule | grep -v
'Module' | wc -l
40




-- 
Bill Moseley
mose...@hank.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/


Re: [Catalyst] Using Catalyst with mod_per or FastCGI on heavy traffic web application

2010-01-30 Thread Bill Moseley
On Fri, Jan 29, 2010 at 10:59 PM, Adam Mackler nab...@mackler.org wrote:



 But with mod_perl, when you're restarting your application, you're
 starting the whole web server, so during that time...which can be
 longer than you expect for a number of reasons...people attempting to
 reach your site will get browser errors saying your site is down or
 unreachable.


 But with fastcgi, the web server keeps running and can serve a static
 error page while the fastcgi server is not available.  And with no
 perl in the mix, restarting the web server itself takes less time and
 can be done more gracefully.


That makes no sense. If fastcgi processes are down, then, well they are
down.  If all your mod_perl servers are down, they are, well, down.

Maybe you are assuming the Apache that is running mod_perl also serves
static content?  Or that there's only one web server? Or there's no load
balancer?  Or it's not run with a reverse proxy as is the standard approach?

We found that restarting with FastCGI took longer.  Maybe that was because
each process has to compile the app (instead of compile and fork to many
processes?).  Is that true?  I can't remember.




-- 
Bill Moseley
mose...@hank.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/


[Catalyst] Large requests with JSON?

2010-02-05 Thread Bill Moseley
As you might have picked up I'm working on an REST api that uses JSON in the
request.  I need to also allow large file uploads.

HTTP::Body::OctetStream will chunk the request body and send to a temp file,
but Catalyst::Action::Deserialize::JSON will load the temp file into memory.
 Obviously, want to limit that.

AFAIK, there's no way to stream parse JSON (so that only part is in memory
at any given time).  What would be the recommended serialization for
uploaded files -- just use multipart/form-data for the uploads?

BTW -- I don't see any code in HTTP::Body to limit body size.  Doesn't that
seem like a pretty easy DoS for Catalyst apps?  I do set a request size
limit in the web server, but if I need to allow 1/2GB uploads or so then
could kill the machine pretty easily, no?



-- 
Bill Moseley
mose...@hank.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/


Re: [Catalyst] Large requests with JSON?

2010-02-06 Thread Bill Moseley
On Fri, Feb 5, 2010 at 8:56 PM, Tomas Doran bobtf...@bobtfish.net wrote:


 On 5 Feb 2010, at 20:54, Bill Moseley wrote:

 AFAIK, there's no way to stream parse JSON (so that only part is in memory
 at any given time).  What would be the recommended serialization for
 uploaded files -- just use multipart/form-data for the uploads?


 Don't?


 Why not just do a PUT request with all the data as unmangled binary?


As in don't provide a way to upload meta data along with the file (name,
date, description, author, title, reference id) like the web upload allows
with multipart/form-data?  Or invent some new serialization where the meta
data is embedded in the upload?  Or do a POST with the file, then flag the
new upload as incomplete until a PUT is done to set associated meta data?

The API is suppose to offer much of the same functionality as the web
interface.  JSON is somewhat nice because, well, customers have requested
it, and also that it lends itself to more complex (not flat) data
representations.  Of course, urlencoded doesn't have to be flat -- we have
some YUI-based AJAX code that sends json in $c-req-params-{data}.  But I
digress.

The 'multipart/form-data' is nice because if the client is well behaved
uploads are chunked to disk.  XML can also do this, too (I have an
HTTP::Body subclass for XML-RPC that chunks base64 elements to disk).



  BTW -- I don't see any code in HTTP::Body to limit body size.  Doesn't
 that seem like a pretty easy DoS for Catalyst apps?  I do set a request size
 limit in the web server, but if I need to allow 1/2GB uploads or so then
 could kill the machine pretty easily, no?


 Well, you set it at the web server.. That stops both overlarge
 content-length requests, and when the body exceeds the specified content
 length.


Yes, for example in Apache LimitRequestBody can be set and if you send a
content-length header larger than that value the request is rejected right
away.  And, IIRC, Apache will just discard any data over the what is
specified in the content-length header (i.e. Catalyst won't see any data
past the content length from Apache).



 But yes, you have to provision temp file space for n files in flight x max
 file size...


You are making an assumption that the request body actually makes it to a
temp file.

Imagine you allow uploads of CD iso files, so say 700MB.  So, you set the
webserver's limit to that.  Normally, when someone uploads HTTP::Body you
expect OctetStream or form-data posts which ends up buffering to disk.

Now, if someone sets their content type to Urlencoded then HTTP::Body just
gathers up that 700MB in memory.   MaxClients is 50, so do that math.

Granted someone would have to work very hard to get enough data at once all
to the same web server, and if an attacker is that determined they could
find other equally damaging attacks.  And a good load balancer can monitor
memory on disk space on the web servers and stop sending requests to a
server low on resources.


Most applications don't have this problem since uploading that large of a
file is likely rare.  Well, that assumes that everyone is using something in
front of Catalyst that limits upload size (like Apache's LimitRequestBody).

It's unusual to have a very large valid Urlencoded (or non-upload form-data)
body in a normal request (that's a lot of radio buttons and text to type!)
so, it would is not be wise for HTTP::Body to limit the size of
$self-{buffer} to something sane?  I suppose it could flush to disk after
getting too big, but that doesn't really help because some serializations
require reading the entire thing into memory to parse.



-- 
Bill Moseley
mose...@hank.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/


Re: [Catalyst] Re: action_for with user_id removed ...

2010-02-06 Thread Bill Moseley
On Sat, Feb 6, 2010 at 2:25 AM, Kiffin Gish kiffin.g...@planet.nl wrote:


 
  From an HTTP point of view it is unwise to make endpoint URIs
  like that which can refer to many different resources at any one
  point in time.




 I'm not so sure that I agree, though I can appreciate your point of
 view.


We have debated this in our apps, too.  If some set of URLs are only valid
once a user logs in then do they have an implicit domain?

Plus, it sure is handy in documentation to say:

  To update your personal profile go to: http://example.com/myprofile

vs.

  To update your personal profile go to: http://example.com/user/your id
here/profile

Because you know what the tech support calls will be like


-- 
Bill Moseley
mose...@hank.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/


Re: [Catalyst] Re: Large requests with JSON?

2010-02-06 Thread Bill Moseley
On Sat, Feb 6, 2010 at 11:29 AM, Aristotle Pagaltzis pagalt...@gmx.dewrote:

 * Bill Moseley mose...@hank.org [2010-02-06 17:30]:
  As in don't provide a way to upload meta data along with the
  file (name, date, description, author, title, reference id)
  like the web upload allows with multipart/form-data? Or invent
  some new serialization where the meta data is embedded in the
  upload?

 Neither, depending on your metadata. The things you did mention
 could quite well be sent as request headers. No need to put
 another envelope inside the HTTP request envelope.


Could you be more specific?  For example API request to

1) create a new user in account #1234 with name, email, etc.
2) create a user but also provide a photo when creating the user
3) upload a document for the user and the document must include an
associated collection of meta data (e.g. filename, timestamp, author etc.).
 The uploaded document must include
this meta data before it can be accepted.





-- 
Bill Moseley
mose...@hank.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/


Re: [Catalyst] Run catalyst tests against another database

2010-02-06 Thread Bill Moseley
On Sat, Feb 6, 2010 at 2:01 PM, John Atzger jatz...@hotmail.com wrote:

  I want my Catalyst tests to run against a test database.  I wrote this:

   package MyApp::Model::DB;
   use strict;
   use base 'Catalyst::Model::DBIC::Schema';

   BEGIN {
 require MyApp;
 my $db = $ENV{HARNESS_ACTIVE} ? 'test' : 'myapp';
 my $config = MyApp-config-{database}{$db};

 __PACKAGE__-config(
 schema_class = 'MyApp::Schema',
 connect_info = {
   dsn = $config-{dsn},
   user = $config-{user},
   password = $config-{password},
 );
   }

 I don't want test information in my code. How do people do this?


I use separate config files that get merged into the main config.



-- 
Bill Moseley
mose...@hank.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/


[Catalyst] JSON views and CamelCase column names

2010-02-25 Thread Bill Moseley
As you know, by default the TT View maps actions to template files based on
the action's name.  The controllers place data into the stash and the
templates render that into markup.

I need to do something similar with JSON output.  The current JSON View will
turn data in the stash into JSON, but what I need is code that sits between
the controller action and the JSON view that is action-specific (just like
the templates are action-specific).  This code would take the objects in the
stash and build a hash used by the JSON view.  I need to do this for a large
number of actions, so I'm looking for something to work for all controllers.

I could do this in the controller (map the data into the stash for the JSON
view), but the same controllers are used for many views, so the controller's
job is just to populate the stash with model objects.  The rendering of
HTML, as well as rendering to JSON, is a View task.

The TT View has a system for running code (the templates) for each action.
 I'm looking for suggestions how to implement something similar when
rendering JSON.  That is, having the view call methods based on the action
name -- and suggestions were those methods should live.  Those
action-specific view methods would be responsible for mapping to a hash
structure the JSON view will render.

In case the question wasn't clear: how should I implement a View that has
methods associated with specific controllers and where should that live?

Of course, I'm interested in hearing other approaches, too.

There's a part 2 of this question:

For the JSON responses the view will be mostly returning column data fetched
from the model (using DBIC queries).

The database column names are not CamelCase, but the front-end/Javascript
programmers favor CamelCase.  That means for every action we need to map
data from the stash to a JSON response and at the same time map to the
CamelCase names.

I'm not thrilled about that mapping -- I'd prefer to use the column names to
reduce confusion and simplify code, but that's another story.   Also, these
JSON responses will become part of the public API, so once we start down the
CamelCase path we are there for good...

Maybe this is a DBIC-list question, but I'm wondering if anyone has a clever
way where I could map the DBIC objects to a hash but where the CamelCase
names are used instead of the existing column names.  It's painful enough
without having to do it for every action explicitly.  Something similar to
DBIC's HashRefInflator.






-- 
Bill Moseley
mose...@hank.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/


Re: [Catalyst] Check session expiry without extending it

2010-03-04 Thread Bill Moseley
On Thu, Mar 4, 2010 at 7:05 AM, Peter Karman pe...@peknet.com wrote:


 // make sure we are logged in before every xhr request
 Ext.Ajax.on('beforerequest', function(conn, opts) {
if (!AIR.Auth.isAuthenticated()) {
AIR.Auth.login();
return false;
}
return true;
 });


I thought about this, but in our case the ajax was checking for a specific
session because the server-side session had state info need for the ajax
request.  So, just allowing the user to log in again was not possible.

That's probably bad design on top of bad design.  In our case probably
better to rethink  then entire process and just make request that can be
independent and either work or fail in some graceful way.  making
assumptions about expected state is problem the root cause.



-- 
Bill Moseley
mose...@hank.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/


Re: [Catalyst] Which C::View::PDF should I use?

2010-03-06 Thread Bill Moseley
On Friday, March 5, 2010, Charlie Garrison garri...@zeta.org.au wrote:
 Good afternoon,

 Thanks, that was a good intro. It looks like I could almost get away with a 
 simple LaTeX table for the form. But I can see myself getting bogged down by 
 the details; I think latex is going to be too hard for this project. I may 
 still come back to it as best option though.

If your needs are pretty simple there's HTMLDOC. I've used it for
simple reports and invoices.
http://www.easysw.com/htmldoc/

It doesn't sound like it would be right in this case (modifying
existing pdf) but it's worth knowing about.



-- 
Bill Moseley
mose...@hank.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/


Re: [Catalyst] Best practices: XML output from static XML

2010-03-06 Thread Bill Moseley
On Sat, Mar 6, 2010 at 6:34 AM, J. Shirley jshir...@gmail.com wrote:

  Just one last question. When you talk about using
  'lib/MyApp/View/MyView.pm', you mean that is also correct to create a
 simple
  perl Module for your view. Then implement process method in the View.pm
 and
  forward the context from the Controller ( $c-forward( $c-view('MyView')
 );
  )?
 
 
  David
 

 Yup, that is exactly right.


Expanding this thread a bit...

I asked a related question in another thread.  What if you want a view that
needs separate code for each action?

For example, when no template is explicitly defined in the action,
C::View::TT will pass control to a template based on the action's name.
 Each action can have its own associated template.

Likewise, for a different type of output I might need code to run for each
action.

Say the controller action for the path /music/recent_uploads places a list
of objects in the stash.  Rendering with HTML sends it to TT (e.g
/templates/music/recent_uploads.tt).  But, what if the client wants, say an
RSS feed or JSON response for that same action?  Doesn't that seems like a
View's job to turn that into a feed or JSON?

But for both of those examples I need code to serialize those objects in the
stash (into a feed or JSON).  So, my question is 1) how to map the action
into a view method, and 2) where those view methods should live?

I don't think a separate view for every possible action is the correct
approach.  Seems better to have in an end() method simply:

$c-forward( $c-view( $view_type ) );


A simplistic or naive View approach might look like:

sub process {
my ( $self, $c ) = @_;

my $method = $c-action-reverse;

$method =~ s{/}{_};

$self-$method( $c ) if $self-can( $method );
}

But, that's flat and ugly.

I could keep the view code in with the controllers which in some way makes
maintenance easier (related code is together), but then the view is not
separate.

my $method = $c-action-name;
$method .= '_render_json';
$c-action-controller-$method( $c );


So, what's the recommended approach to per-action view code?



-- 
Bill Moseley
mose...@hank.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/


Re: [Catalyst] Best practices: XML output from static XML

2010-03-06 Thread Bill Moseley
 when the
response is actually json.



-- 
Bill Moseley
mose...@hank.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/


Re: [Catalyst] Best practices: XML output from static XML

2010-03-07 Thread Bill Moseley
 names.

Second, the ::REST approach has the controller actions building the entity
structure which feels more like a view operation.  Minor point but turning,
say, a DateTime object into a human-readable format (or ISO8601 for JSON
response) both seem like views.




-- 
Bill Moseley
mose...@hank.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/


Re: [Catalyst] Taking advantage of idle periods by performing some action(s)

2010-03-25 Thread Bill Moseley
On Thu, Mar 25, 2010 at 5:30 AM, Ido Perlmuter i...@ido50.net wrote:

 I'm looking for direction on how to possibly implement a feature in a
 Catalyst app that automatically performs some action, or actions, when the
 app is idle and hasn't been accepting requests (either none or some small
 number). For example, let's say I want my app to take advantage of such
 situations by indexing documents to KinoSearch, rebuilding a sitemap.xml
 file, whatever.


Doesn't really seems like the job of a Catalyst app to run background tasks.

What's wrong with cron?  It can run a script and see if the machine's load
is low (or some other measurement) before deciding to run.



 Thing is, I do not want (if possible) to implement a job queue such as
 TheSchwartz. I do not want an outside worker, I want my app to be the
 worker, and let it decide by itself what to do instead of take jobs from a
 queue.


Yes, you do want an outside worker.  It can be part of  your app, but it
should be separate from Catalyst.  Put it in a model class.  Ok, sure you
could have cron run App/script/app_test.pl /path/to/action but why load all
of Catalyst just to run some code in your application?




-- 
Bill Moseley
mose...@hank.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/


Re: [Catalyst] Taking advantage of idle periods by performing some action(s)

2010-03-25 Thread Bill Moseley
On Thu, Mar 25, 2010 at 8:04 AM, Ido Perlmuter i...@ido50.net wrote:

 Kiffin, thanks for the heads up about Plugin::Scheduler, seems to fit my
 needs quite good.


I used that plugin in an early application that is still running.  I've
never spent the time to debug, but I've had times when it seems an error in
one job resulted in other jobs not running.  So, if you really want to
send requests to your running Catalyst application then I'd use cron and
lwp/wget instead of the plugin.


-- 
Bill Moseley
mose...@hank.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/


Re: [Catalyst] Catalyst Redirect to https

2010-03-25 Thread Bill Moseley
2010/3/25 Octavian Rasnita orasn...@gmail.com


 The back end servers don't know if the current request is an http or an
 https one and on each redirect, they do the redirection using the http
 scheme.
 (I have also set the configuration option using_frontend_proxy to true.)


 Also, because the back end servers receive only http requests,
 $c-req-secure is always equal to 0.
 I have read that I can set the HTTPS environment variable to On and I put
 the following line in the configuration file of the load balancer Apache
 server in the virtualhost that handles SSL requests:

 SetEnv HTTPS On


Does that header get to Catalyst?  Obviously, check that first.

I have this in  a after 'prepare_headers':

   $res-secure( 1 ) if lc( $req-header( 'Https' ) || '' ) eq 'on';

The load balancer sends all traffic to the same port.  The load balancer
sets that header for SSL traffic.

I used to send to two different ports and then detect SSL based on the port
number.  Same result either way.




-- 
Bill Moseley
mose...@hank.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/


Re: [Catalyst] Catalyst Redirect to https

2010-03-26 Thread Bill Moseley
On Fri, Mar 26, 2010 at 12:46 AM, Octavian Rasnita orasn...@gmail.comwrote:

  *From:* Bill Moseley mose...@hank.org

   SetEnv HTTPS On


   Does that header get to Catalyst?  Obviously, check that first.
 

 I didn't know that HTTPS should be an HTTP header and not an environment
 variable so I have also added as a header.

 Sorry, I missed that you were setting the environment var -- I assumed you
were setting a header in your load balancer.  Obviously, the front-end web
server's environment is not shared with the back-end's environment.

You have the front-end load balancer add a header to SSL requests when being
proxied to the backend.  Then the backend looks for the this header and, if
set, sets $c-req-secure(1);

You just need some way for the front-end to tell you which requests are SSL
on the front end.  As mentioned, another approach is to use two different
ports on the backend.




 And finally, even though I forced $c-req-secure to be true,
 $c-uri_for_action still uses the http scheme and not https so in the entire
 application the redirects won't be done correctly and this is the big
 problem.


You need to set $request-secure(1) earlier in the request so that when
$base is created it has the correct scheme.

Here's a simple example application:

$ cat lib/ssl.pm lib/ssl/Controller/Root.pm
package ssl;
use Moose;
use namespace::autoclean -except = 'meta';
extends 'Catalyst';

__PACKAGE__-setup();

after 'prepare_headers' = sub {
my $self = shift;
$self-req-secure( $ENV{SSL} );
};

1;


package ssl::Controller::Root;
use Moose;
use namespace::autoclean -except = 'meta';
BEGIN { extends 'Catalyst::Controller' }
__PACKAGE__-config-{namespace} = '';

sub hello : Local {
my ( $self, $c ) = @_;
$c-res-body( $c-uri_for( '/hello' ) );
};

1;


~/ssl$ script/ssl_test.pl /hello
http://localhost/hello

~/ssl$ SSL=1 script/ssl_test.pl /hello
https://localhost/hello


Don't get confused by that example where I'm checking $ENV.  You will want
to check a request header (or port) as that's how the front-end can
communicate with the back-end.

Note that Catalyst::Apache::Engine will check for $ENV{HTTPS} is ON but
for that to happen you would have to do something like  $ENV{HTTPS} =
$c-req-headers( 'HTTPS' ) very early in the request (or get Apache to set
it based on the request header.

I find it easier to just explicitly set secure(1) based on a header (or
port).


-- 
Bill Moseley
mose...@hank.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/


Re: [Catalyst] Picking template type based on input

2010-03-26 Thread Bill Moseley
On Fri, Mar 26, 2010 at 5:50 AM, Tomas Doran bobtf...@bobtfish.net wrote:


 The controller asks the model for some data, and then chooses how to
 present that data (whilst the view actually handles the presentation
 details.


That means the controllers have to be aware of the view. That is, the
controllers have to know what view is going to be used so that it can fetch
the data needed for that specific view.  Is that what you are saying?


-- 
Bill Moseley
mose...@hank.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/


Re: [Catalyst] Picking template type based on input

2010-03-28 Thread Bill Moseley
On Sun, Mar 28, 2010 at 7:12 AM, Jon mailinglists jon.ml...@gmail.comwrote:

 In my catalyst app I have this sub (not really, but this makes things
 easier to follow):

 sub get_info : Local {
   my ($self, $c) = @_;

my $info = $c-user-member_info;
my $res =
 'MyNamespace.callback({ResultSet:{totalResultsAvailable:73399,firstResultPosition:0,totalResultsReturned:20,Result:[{Title:'.$info-get_column('first_name').'

 '.$info-get_column('last_name').',zip_code:'.$info-get_column('areacode').'}]}});';
$c-response-body($res);
 }


I think I get it now.  I first thought you were talking about users adding
javascript to pages you render -- that is, allowing someone to inject script
onto your pages.

(I'm hoping someone will jump in an correct anything I say wrong here --
which often seems like the best way to get a response here...)

I think the short answer is, don't return JSONP -- don't return JSON wrapped
in a function call.  That's a way to bypass security provided by the
same-origin policy.

Let me restate what I think you are saying:


   1. The good site (MY-CATALYST-SERVER in your example) returns the JSONP
   above as long as the user is logged in.  By logged in that means the
   request includes a valid session id in the cookie.
   2. In another tab of the same browser when viewing a page from 
   evil_empire.com a request is made to
   http://MY-CATALYST-SERVER:3000/member/get_info.
   3. That request will include the cookie required to gain access (and thus
   return private user data).
   4. Javascript is returned that includes a call to a function passing the
   user's private data to that function.
   5. evil_empire.com now has access to the user's name and zip code.

Yes, this is true.  This is a security hole.  But by returning JSONP you
gave away this access.

JSONP is application/javascript -- and as such it can be loaded from any
domain.  Loading javascript is not limited by same-origin policy.  (If it
was then Content Delivery Networks would be of limited use.).

Note, this has nothing to do with YUI.Get.  evil_empire.com just needs to
add a script tag to their page to fetch the JSONP from your app.  YUI.Get
just provides a dynamic way to accomplish that.

Your application should only return data via JSON, not JSONP.   For a script
to read JSON data it needs to use XMLHttpRequest and that request is limited
by the same-origin policy.  That is, javascript running on evil_empire.com's
page cannot do an AJAX request to your catalyst application.

Hopefully, that's clear -- and correct. ;)


-- 
Bill Moseley
mose...@hank.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/


Re: [Catalyst] Picking template type based on input

2010-03-28 Thread Bill Moseley
On Sun, Mar 28, 2010 at 3:13 PM, Tomas Doran bobtf...@bobtfish.net wrote:

Speaking of XSRF:


 It would be possible to parse the HTML your app output, add an extra hidden
 field to any forms you had generated in the page, and then look for a
 previously generated token and redirect / refuse the request if it wasn't
 present.


I do this -- every POST must include token, and the token can only be used
once.  That means the the form must be fetched before bing posted (to
generate the token).

I'm not sure I understand XSRF enough to know if there's a way to get around
the token (or trick the browser into doing a POST for, say, and img.

And for a SSL only site that requires login, I'm also not so sure the token
requirement helps that much for security.  The original purpose was to slow
down form spamming and to prevent double-posting of forms.

The tokesn don't work so well with an API, of course, but XSRF needs a
browser, AFAIK (hard to trick a user of an API into making a request..)



 However this would obviously not catch forms generated purely from
 Javascript (and a number of other cases), and so I'm somewhat doubtful of
 its value in more complex applications. I can certainly remember the stuff
 which tries to achieve this that is baked into Rails making me scream :)


I'm not clear how javascript is an issue here, unless the attacker has
injected javascript into my site.

The example on Wikipedia for XSRF is to add a link to your bank on the
attackers site, which you view:
img src=
http://bank.example/withdraw?account=bobamount=100for=mallory;

Which is a pretty bad bank that allows that.  A third-party (evil) page can
include the above and force a GET request that is not noticed, but to make a
POST it would have to have a form where the response is from the bank.  That
is, you would see the bank's response page.  Can't do it via an AJAX request
because of the same-origin policy.

Slippery stuff.



-- 
Bill Moseley
mose...@hank.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/


Re: [Catalyst] Picking template type based on input

2010-03-28 Thread Bill Moseley
On Sun, Mar 28, 2010 at 6:05 PM, Tomas Doran bobtf...@bobtfish.net wrote:


 On 29 Mar 2010, at 01:06, Bill Moseley wrote:


 I do this -- every POST must include token, and the token can only be used
 once.  That means the the form must be fetched before bing posted (to
 generate the token).


 Have anything generic you'd care to share? :)


Nothing generic -- and it's not rocket science, either.  Or very glamorous.
 I simply have a template macro for creating my form tag which also
includes the hidden field with the token id.

Then part of form validation processed used for every post I check that the
token was provided and is valid.  The token is either in the database or in
memcached.  (I have a form_posted() method that does this check, along check
for the correct method (PUT or POST) .)




 The issue is that if you're generating a form in javascript, and submitting
 it in javascript, then something finding forms in the page output (and
 adding a token automatically), which was what I initially suggested - would
 fail to find the form, and ergo you'd have an issue :)

 (i.e. it couldn't 'just work automatically' in that case without the
 application collaborating in some manor).


I think I get it.

Thanks,



 --
Bill Moseley
mose...@hank.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/


Re: [Catalyst] Picking template type based on input

2010-03-29 Thread Bill Moseley
On Mon, Mar 29, 2010 at 2:12 AM, Jon mailinglists jon.ml...@gmail.comwrote:


 It seems like it is. I just stumbled upon this when checking out YUI
 3, and had managed to stay oblivious to this problem before. I then
 went on with checking if one could make an attack that way and got a
 bit scared by the results and asked here. Classic case of reinventing
 wheels. I called it XSS because I figured it was scripts running
 across sites, but apparently this is XSRF as you said.


I think you are missing it still. It's not really XSRF.

These terms are a bit fuzzy and overloaded, but in general:

XSS is where an attacker places script on the attacked site.  This is
accomplished by correctly not filtering user input.  One example is a blog
site where the attacker places script on a common page that many others
view.  Another approach is for the attacker to create a link to the site
they wish to attack which includes javascript and trick people into clicking
the link.
When the script runs it can, for example, send the cookie to the attacker's
site and then the user can use that session id to gain access.

XSRF is (typically, AFAIK) where the attacker's site includes a tag that
generates a request to another site.  Wikipedia is worth reading, and it
includes this example:

img src=
http://bank.example/withdraw?account=bobamount=100for=mallory;

The attacker has to know (or hope) the person that is viewing the page with
the img  has an account at bank.example and that they are logged in (or
have a remember me cookie).

Of course, the img does a GET request to the poorly-coded bank site and
incorrectly causes something to happen.  This works because the browser will
send the cookie with the request.

Now to your example.   It's ok to load and run javascript from a third party
site.  And any data that javascrpt brings in will be available to the page
that is loading the script.  This is expected.  It's also expected that the
browser will send the site's cookie along with the request.

Your example seems like XSRF because the attacking site is requesting a
resource (javascript) from your site -- just like the img above is making
a request to another site.  It's also similar because in both your example
and the XSRF example above, the site is doing something dumb.

The bank.example site is dumb because it's allowing a GET request to make a
change.  Your example is making the mistake of providing javascript that
gives private data away.

And that's why AJAX requests follow same-origin policy.  It provides a way
to fetch data from a site, but only from the site that the browser is
viewing.

(Sure, the attacking site could create a form (perhaps in a hidden iframe)
and POST that, but hopefully your bank will return an Are you sure you want
to transfer your money to Mallory? confirmation screen first.)


 Wouldn't it make sense to have and option in Authorization which
 generates and stores a token server side, in either a database or in
 the session (like Bill seems to do) at login time. If I'm not horribly
 mistaken would one token be enough for a session since the attack is
 blind and there's no way for a 3rd party to figure it out unless using
 brute force.

 If that is correct, one can go about playing CRUD and allowing
 /member/get_info?token=... and /member/set_info?token=... with GET
 requests?


First, don't set_info with a GET request.  That just makes the XSRF easy.
 Second, if this is to protect against your example that returns JSONP (and
thus leaks personal user info) then, the real solution is to not return
JSONP.

I think the tokens are a mixed bag.  Yes, the tokens would help, but if you
have them on your URLs then you have to worry about bookmarking and link
leaking.  The tokens I use help with POSTing forms, but for critical changes
I still add an Are you sure? page.



-- 
Bill Moseley
mose...@hank.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/


[Catalyst] HttpOnly flag dependency.

2010-03-29 Thread Bill Moseley
About a year ago Scott Thomson provided a patch to CGI::Cookie::Simple for
supporting the HttpOnly flag.

1.109   2009-04-16
  - Added support for HttpOnly to CGI::Simple::Cookie. Thanks to
Scott Thomson for the patch.


I don't see that dependency in Catalyst::Runtime or
C::P::Session::State::Cookie.  Could that be added to Runtime?

Thanks,

-- 
Bill Moseley
mose...@hank.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/


Re: [Catalyst] Distributing and updating Cat apps

2010-03-30 Thread Bill Moseley
2010/3/30 Tomáš Znamenáček tomas.znamena...@gmail.com


 I have a Catalyst application that I would like to upload from the
 development box to the production server. Is there some kind of best
 practice to do that? My requirements:


I don't think there's any standard approach.  I know many people seem to
just do a checkout from the repository.


 1) The process should take care of the dependencies and run the tests
   before installing. (Let’s say the deps are declared in Makefile.PL
   or Build.PL.)


I have a separate cron job that polls the repository looking for changes.
 When it notices that a new version has
been checked in it checks it out and runs the full test suite. A big fat
email goes out if test do not pass.  If it passes, but a previous run failed
an email also goes back congratulating everyone on fixing the problem.

This works well because the same process can be used on multiple
applications and is constantly running -- not just when it's crunch time to
push a release.



 2) It would be nice to keep the application isolated in one directory
   so that I can keep several instances under the same account to do
   primitive staging.


Agreed.

I have a separate build process.  This is a simple process and doesn't run
any tests (because the build process may happen
on a build server w/o dependencies needed by the application).

This simply does an svn export, then it runs build/build_app.sh which then
runs whatever scripts are needed to build that specific application.  For
example, minify and combine css and javascript, etc.

Then a tarball is built of this export (named after the application and
version) and made available on a web server.

This can then be pushed to any server.  The push process simply fetches
the tarball from the build web server, unpacks it into it's version-specific
directory and runs the Makefile to test for dependencies on the target
machine.  If that passes a symlink is updated to point to this new version
and the web server is restarted.

The symlink makes it easy to revert to a previous version or to have
multiple versions on the same machine for testing.

The applications have separate YAML files for different environments.  There
might be dev.yml, testing.yml, qa.yml, and produciton.yml.  Each
machine has a file in /etc/$app_name that sets what environment the
application should start in (i.e. what YAML config file to use).  Push to
testing and the app starts and uses the testing database as configured in
testing.yml.

I've used this method for pushing directly to production, but in other cases
use it for staging and then rsync to production servers from staging.



 I’ve read something about local::lib, but I’m still not sure about how
 to put things together. This has to be a common scenario, isn’t it? When
 you are finished updating the development version, what do you call to
 upload the update to the production server and what exactly happens
 along the way?


Good question.   Hopefully someone has a great solution.

In the past I've used cfengine to make sure machines have the right
dependencies.

I've also used a local lib and rsynced that and messed with @INC and
PERL5LIB, which doesn't make me happy. (Think about init.d scripts, cron
jobs, etc.)

The next approach is to build packages (deb or rpm) of the application and
dependencies and let the OS package manager handle it all.  The goal there,
besides making it easy for deployment, is to break out common code shared by
apps into libraries.

That said, there is something to be said with throwing everything in the
application's lib directory since you know when it's pushed you will have
exactly the same code used in development.  Lot easier to revert when
everything is under a a single symlink.

I've heard of people that build an entire Perl installation and keep that
separate from the OS installed Perl.


-- 
Bill Moseley
mose...@hank.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/


[Catalyst] [OT] XSS, XSRF, and REST

2010-04-01 Thread Bill Moseley
We love our acronyms.


As discussed in another recent exciting thread, I use a unique, single-use
token on forms that must be returned with a POST.  This seems to be the best
approach to prevent XSRF[1].  But, what about for a (RESTful) API where it's
common to receive a PUT or POST request without expecting that a GET was
done immediately before to fetch the token?

In those cases I cannot expect that the unique token would be provided.
 Therefore, I need a way relax the token requirement for some requests, but
only if I'm sure it's not coming from a browser that might be generated via
an XSRF attack.

Is it enough to allow the requests if a valid session is is provided in a
Cookie *plus* one of:

   - A valid token in the body parameters (as the case for a valid web
   request)
   - A valid JSON body in the request (assumes that a XSRF could not trick a
   browser into sending json, etc.)
   - A X-Requested-With: 'XMLHttpRequest header (or similar header) that
   would indicate that the request was not generated from a web browser (via
   XSRF attack) because  it included a header not normally sent by browsers.
   - Require API users to fetch a token and place it in a HTTP header or
   body for every request (that seems expensive).  Hum, if a GET can fetch a
   token could the attacker use Flash/Siverlight to accomplish the GET and gain
   access to the response data?

Of course, the first two won't work if there's no body (say a DELETE).  Do
(will?) browsers send a DELETE with form method=delete?


What approach can you recommend for determining that a request is not from a
XSRF-susceptible client?



[1] A second commonly suggested approach for protecting against XSRF is to
include the session id in the POST.  Then the server can compare the session
id in the cookie (something the XSRF attacking site would not have) to the
session id sent in a body parameter.

The problem I have with this approach is then the client (the web browser)
must have access to the session id either via javascript or directly in the
markup.  I use the HttpOnly to prevent javascript access (in complying
browsers).  And I feel like providing the session ID in the markup opens up
the possibility of XSS that would send the session id to an attacker.  Of
course, a successful XSS attack and your wide open anyway.


-- 
Bill Moseley
mose...@hank.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/


Re: [Catalyst] Distributing and updating Cat apps

2010-04-05 Thread Bill Moseley
On Mon, Apr 5, 2010 at 2:31 AM, Oleg Kostyuk cub.ua...@gmail.com wrote:

 2010/3/30 Bill Moseley mose...@hank.org:
 
  ..
  The applications have separate YAML files for different environments.
  There
  might be dev.yml, testing.yml, qa.yml, and produciton.yml.  Each
  machine has a file in /etc/$app_name that sets what environment the
  application should start in (i.e. what YAML config file to use).  Push to
  testing and the app starts and uses the testing database as configured in
  testing.yml.

 Catalyst already have such possibility: read end of DESCRIPTION in
 Catalyst::Plugin::ConfigLoader, and more details in description of
 get_config_local_suffix().


Yes, similar.  ConfigLoader didn't exist when I wrote the above, and it's
not a plugin (the Plugin is just a thin wrapper) -- it's available outside
of Catalyst which is very useful.Wasn't there talk a while back about
splitting up ConfigLoader to make it available outside of Catalyst and with
the ability to merge files?



-- 
Bill Moseley
mose...@hank.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/


Re: [Catalyst] Distributing and updating Cat apps

2010-04-09 Thread Bill Moseley
On Thu, Apr 1, 2010 at 12:51 AM, Toby Corkindale 
toby.corkind...@strategicdata.com.au wrote:


 We package things up into Debian-style packages, and then upload those to a
 local repository of packages.
 Then servers can just be updated using the standard system tools (apt).


Hi Toby,

This is really the direction I'm heading now (although it's looking like
CentOS and RPMs).  Can you answer a few general questions?

Are you using Template Toolkit?  How (or really where) are the templates
managed?   Where do they get installed, how does the TT View know where to
find them, etc?  Do they end up in /usr/share/app/ for example?

I'm sure you never have to roll-back a release, but I also assume you are
prepared to roll-back if needed.  How does that process work?

What about your static content (css, js, images)?  Where do those get
installed?

Any special tricks when using an app in development vs. production?  (For
example, under dev I use source css, js, but otherwise the app uses
combined and compresses css and js.



 You have a choice of either packaging up every single Perl dependency into
 a Debian package too (which is a world of pain), or installing all your
 dependencies into a local directory that you ship with the application. I
 recommend the latter.. (you'll still need to include dependencies on things
 like the C libraries for your database client, etc though, in the debian
 control file.)


We are doing a mix.  But, for the most part we are creating single modules
(packages).  Mostly that was to encourage inclusions of unit tests and just
more fine-grained management.  But, it is more work, true.


-- 
Bill Moseley
mose...@hank.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/


[Catalyst] Catalyst::Utils::home()

2010-04-12 Thread Bill Moseley
I was hoping to use Catalyst::Utils::home outside of Catalyst -- I can do
that but I must load the application because home() looks in %INC to find
where the application class is located.  It's not a huge problem to load the
class, but it's not necessary for my needs.

Do you see any reason why home() could not walk @INC looking for the app .pm
file if not found in %INC?  Or is there another approach to find home?

Oh, btw --

# we found nothing
return 0;

maybe just return; -- or simply die Cannot determine home for App
$class;



-- 
Bill Moseley
mose...@hank.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/


[Catalyst] Automated testing?

2010-04-18 Thread Bill Moseley
I have a cron job that watches for changes to SVN, and when found the cron
script exports the code and runs the tests.  The idea is to notify
developers if they check in code that causes testing to fail.

I'd like to move away from using my custom scripts to a more generic tool
that will do automated testing for all our packaged Perl code, not just the
Catalyst apps.  (Since the Catalyst app is just another Perl distribution).
 Perhaps something similar to what cpan testers use where email
notifications are sent but also provide a web-based history of testing.

Do you do anything similar?  Anyone using Smolder and/or SmokeRunner::Multi
or other standard tools for their in-house code?

Thanks,

-- 
Bill Moseley
mose...@hank.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/


Re: [Catalyst] RunAfterRequest/delayed Catalyst view

2010-04-30 Thread Bill Moseley
On Fri, Apr 30, 2010 at 2:38 PM, Steve Kleiman st...@prodhub.com wrote:

  Here goes...hopefully a simple test case for the RunAfterRequest oddness.


This is really not the response you were hoping for, but have you considered
not using RunAfterRequest?  I either send email directly during the request
to the local sendmail or I write it to a store and another (non-web) process
on a separate machine (or machines) manage delivering the mail.

-- 
Bill Moseley
mose...@hank.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/


[Catalyst] Returning error codes to the user.

2010-04-30 Thread Bill Moseley
I have a CRUD interface to an application.  This is used for both the Web
and directly as an API.

The model uses DBIC which, as you know, allows chaining resultsets, which I
use to add additional constraints to the result set.

So, a request for, say, /user/1234 might result in:

$c-model( 'App::User' )-search(
{
'me.id' = $requested_user_id,
'me.active  = 1,
'me.date_expires'   = [
{ '' = \'now()' },  # past expired
{ '=' = undef }, # or never expires
],

'account.active'= 1,
'account.balance'   = { '' = 0 },
'account.locked'= 0,
'account.date_expires'  = [
{ '' = \'now()' },  # past expired
{ '=' = undef }, # or never expires
],
},
{
join = 'account',
},
);

[That's not a great example because we assume that user and account
might get checked when first logging in.  Ignore that. Just assume a query
that does a lot of joins to test if a given object can be accessed.]

The request either succeeds (200) or fails (404).

The VAST majority of the time the ID provided will return a row because a
valid ID was provided by the application itself in the first place.

But, for a tiny, tiny percent a request might fail.  Then the question is
*why* did it fail?  What WHERE condition or join failed?

Just like our favorite topic premature optimization, I don't think it would
be wise to write the above in multiple stages (and multiple requests to the
database) just to check each step for something that almost never fails.

On the other hand, it's not unreasonable for an API request to return a
reason why something failed.  Sure would make tech support's life easier.


So, what would you recommend? Have a separate /user/$id/debug method that
does a separate step-by-step of the business logic?  Scrap all that really
handy chaining of resultsets that works so well with Catalyst's chained
actions?



-- 
Bill Moseley
mose...@hank.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/


Re: [Catalyst] RunAfterRequest/delayed Catalyst view

2010-04-30 Thread Bill Moseley
On Fri, Apr 30, 2010 at 3:59 PM, Steve Kleiman st...@prodhub.com wrote:

 That's definitely my fallback if necessary. I really like using the
 Catalyst-centric option because it's easier for my brain to
 compartmentalize. It keeps the email dispatching process consistent with the
 rest of the Email::Template paradigm used throughout my app.

 Also it's not just for email I'm using RunAfterRequest...it's a bunch of
 slow database processing that leads up to the generation of the email. So I
 was hoping to drop the whole bit into RunAfterRequest instead of having a
 cron job deal with it. Keeps all my stuff in one place and for a Catalyst
 newbie that's a nice thing (if it works).


Ya, it's a fine line.  I tend to think Catalyst's job is to handle a request
and return the response as soon as possible and then move on to serve
another request.  But, if you have processes to spare then why not use them?

Might need to think about other things like how a long running process might
effect the need to restart the sever, etc.  Job queues are nice.



-- 
Bill Moseley
mose...@hank.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/


Re: [Catalyst] Returning error codes to the user.

2010-05-02 Thread Bill Moseley
On Sat, May 1, 2010 at 6:17 PM, Tomas Doran bobtf...@bobtfish.net wrote:



 So, what would you recommend? Have a separate /user/$id/debug method that
 does a separate step-by-step of the business logic?  Scrap all that really
 handy chaining of resultsets that works so well with Catalyst's chained
 actions?


 Given that 'a tiny, tiny percent a request might fail', why not do the step
 by step for the tiny failed set and then present the reason to the user for
 those?

 (Or am I missing something obvious here?)


You are not missing anything if that's your recommendation.  I assume lots
of people here are creating real web applications with Catalyst so was
inquiring how others handle this situation in the design of their
applications.

I have a CRUD controller base class to help generate a RESTful-like API that
is used by both API users and with an AJAX-based application, which I assume
is not that uncommon with Catalyst apps.  For example, when a PUT
/thingy/52113 fails (which means the query used to fetch the item failed),
how do you reported to the user?  A 404 with a text description?  Some kind
of error code in the response body?

I my case, I'm added a method explain_not_found() to the base class that can
be overridden in the controller to provide specific details in textual
format.  That method would be used to break the query into parts to test
each join and condition, for example.


As a side note: Frankly, I enjoy the discussions of real problems and
solutions on this list.   I try not to find it discouraging that old topics
like benchmarking methods calls and the few inflammatory remarks seem to get
so much traction.   :)



-- 
Bill Moseley
mose...@hank.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/


Re: [Catalyst] Returning error codes to the user.

2010-05-02 Thread Bill Moseley
On Sun, May 2, 2010 at 12:53 PM, Matt S Trout m...@shadowcat.co.uk wrote:


 Am I correct in thinking that's built up in multiple -search calls?


Somewhat, yes.



 ... if you keep all the intermediate resultsets around in the stash or
 wherever (or better still refactor to resultset methods and have your
 custom resultset class keep the intermediate resultsets around) then it
 seems like it should be pretty easy to walk back up the chain making
 the extra queries until one returns data - at which point you know the last
 step you walked back up is the problem child for this request.


That's an interesting idea.  So, instead of adding multiple constraints in a
single call to search I could do it individually.
I'm not sure if I need to subclass the resultset_class -- could just add a
controller base class method.  i.e.:


$self-add_to_resultset( $c,
'User account must be active',
{ me.active = 1 },
);

$self-add_to_resultset( $c,
'User account expired',
{   'me.date_expires'   = [
{ '' = \'now()' },  # past expired
{ '=' = undef }, # or never expires
],
},
);

$self-add_to_resultset( $c,
'Parent account must be active',
{ 'account.active' = 1 },
{ join = 'account' },
);

etc.

Then, as you say, if $self-current_resultset-first (top of stack) fails
then work down the stack until find the spot where the query passes and
return the previous message.

Thanks,



-- 
Bill Moseley
mose...@hank.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/


Re: [Catalyst] Catalyst::Plugin::Session: Duplicate entry errors

2010-05-08 Thread Bill Moseley
On Fri, May 7, 2010 at 2:33 AM, Tobias Kremer tobias.kre...@gmail.comwrote:

 I'm not sure why this is happening because the _load_row() method of
 the store delegate explicitly wraps everything in a txn_do() which
 should make the find_or_create() atomic and not prone to concurrent
 select/insert/update problems.


Does it make it atomic or just fail if a second session tries to create with
the same primary key?

Looking at some old code I see that I first attempt a create, and if that
fails with a duplicate error I then do a find.  Don't need a transaction for
that.


-- 
Bill Moseley
mose...@hank.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/


[Catalyst] Adding build scripts to Makefile.PL

2010-05-10 Thread Bill Moseley
I have a number of scrips that need to be run when building an application.
 For example, I have a script that minifies javascript and css.  In many
cases it's a real Makefile dependency -- need to run a command to turn one
file into another -- but in some cases don't know the sources of the targets
(i.e. a script just finds all .css files and minifies them) so might just
want to run a command every time make is run.

Anyone have examples of how to set this up in Makefile.PL (which uses
Module::Install)?

Thanks,


-- 
Bill Moseley
mose...@hank.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/


Re: [Catalyst] Adding build scripts to Makefile.PL

2010-05-11 Thread Bill Moseley
On Mon, May 10, 2010 at 9:31 PM, Florian Ragwitz r...@debian.org wrote:

 On Mon, May 10, 2010 at 06:15:03PM -0700, Bill Moseley wrote:
 I have a number of scrips that need to be run when building an
 application.  For example, I have a script that minifies javascript
 and
 css.  In many cases it's a real Makefile dependency -- need to run a
 command to turn one file into another -- but in some cases don't know
 the
 sources of the targets (i.e. a script just finds all .css files and
 minifies them) so might just want to run a command every time make
 is
 run.

 You can do globbing in your Makefile.PL, or use a script to just find
 the files, and have a target that depends on whatever the script
 outputed, or whatever.


Ok, thanks.  Do you have an example you can share?  Thankfully it's been
years since I created a Makefile by hand. ;)

Will that work in cases where there's no direct input and output files?
 Seems I remember using .PHONEY targets when I needed to run programs that
didn't alway produce a direct output -- that or create flag files to compare
against.

I have build scripts that combine .js and .css files into collections and
then outputs four versions (text, gzipped, and both with a version string),
another that extracts text to localize from javascript and validates that
the strings can be looked up in a db, one that builds jemplate files and
another that builds .js from other sources.  Some use File::Find to find
sources and others use config files.  Another processes images and other
media. The source file list can be very large, of course.


Anyone have examples of how to set this up in Makefile.PL (which uses
 Module::Install)?

 Module::Install has a postamble() command to add makefile snippets to
 the generated Makefile.PL


I've used postamble to add new targets (make foo) but I'm not clear how to
make just make depend on them.   Maybe that's not the correct approach,
but I want our existing tools that build RPMs to run this code as part of
the normal make process .

Thanks,



-- 
Bill Moseley
mose...@hank.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/


[Catalyst] Catalyst::Model::DBIC::Schema and ACCEPT_CONTEXT -- current user in model

2010-05-13 Thread Bill Moseley
I've managed to keep context related items  (e.g. current user) out of my
DBIC model up until now.  Now finding it would be very helpful to be able to
call a method on a row object and have access to the current user.

So, I'm trying to hunt down an example of how to make a current user
available to row objects.  Seems this has come up many times but not having
much Google luck.

Anyone have a link or an example?

Thanks,

-- 
Bill Moseley
mose...@hank.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/


Re: [Catalyst] Catalyst::Model::DBIC::Schema and ACCEPT_CONTEXT -- current user in model

2010-05-14 Thread Bill Moseley
On Thu, May 13, 2010 at 2:54 PM, Kieren Diment dim...@gmail.com wrote:

  sub ACCEPT_CONTEXT {
 my ($self, $c ) = @_;
 my $new = $self-meta-clone_object($self, arg =
 $c-stash-{something});
 return $new;
  }


Hum, I'm not clear how that works with Catalyst::Model::DBIC::Schema,
because I want to be able to call current_user on any row object.
 $track-current_user.


Again, I have some aversion to saving a current user in my model.  That was
more my question.  Getting something to work is easy enough, just not sure
it's the best approach.

For example:

In my Music::Schema base class I add an accessor:

 has 'current_user' = ( is = 'rw'  );

Then in my Result base class add a convenience method:

 sub current_user { return shift-result_source-schema-current_user }

Now, I might want to have a method $track-can_user_access so in my Track
class:

sub can_user_access {
my ( $track, $current_user ) = @_;

# Use saved user if one not passed.
$current_user ||= $track-current_user || die 'no current_user';
...
return $has_access;


Finally, in Catalyst my Model class would then look like:

package MyApp::Model::Music;
use Moose;
extends 'Catalyst::Model::DBIC::Schema';
use namespace::autoclean;

before 'ACCEPT_CONTEXT' = sub {
my ( $self, $c  ) = @_;
$self-schema-current_user( $c-current_user );

};


 __PACKAGE__-meta-make_immutable;
1;


That implementation is simple enough, but not clear is it's the best
approach.


Backing up, the issue that came up is I have a base class used for setting
up very common actions for an API.  The controllers for, say,
/music/track/$id are set up with configuration only:

package MyApp::Controller::Music::Track;
BEGIN { extends 'MyApp::Controller::API' }
__PACKAGE__-config(
return_colums = [qw/ id track_name position can_user_access /],
);
1;


The controller base class then builds a response that includes those columns
and methods.  But, the base class doesn't know when to pass in the current
user to a method (e.g. for can_user_access).

So, I either extend the config to tell the base class to pass the current
user to some methods:

pass_user_to_meethod = [ 'can_user_access' ]


Or I use something like ACCEPT_CONTEXT to set the current user in the
schema.

Better ideas?


This is going to be a killer Music app.  I just hope CDs don't go out of
style.



-- 
Bill Moseley
mose...@hank.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/


Re: [Catalyst] Not cleaning up temporary files / HTTP::Body

2010-05-22 Thread Bill Moseley
On Fri, May 21, 2010 at 10:24 AM, Tomas Doran bobtf...@bobtfish.net wrote:


 On 13 Jan 2010, at 14:53, Bill Moseley wrote:

 Where should this be addressed?  In Catalyst or in HTTP::Body?


 I'm all for it being addressed as suggested, in both places (for extra
 double sure).



It's been five months since I looked at this.  HTTP::Body now has an option
to have it remove the temp files on DESTROY, but catalyst would have to set
that.

I see that what I did was replace the Multipart handler with one that simply
sets UNLINK = 1 and have not had any problems since.  We removed the cron
job we used to use for keeping /tmp clean.



-- 
Bill Moseley
mose...@hank.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/


[Catalyst] Catalyst::Model::DBIC::Schema and dbh_maker

2010-05-25 Thread Bill Moseley
I would like my Catalyst::Model::DBIC::Schema model class to be able to
inspect the configuration and modify connect_info.  Specifically, based on a
flag in the config either pass connect_info unmodified or replace
dsn/user/password with a dbh_maker sub.

What seems to work ok is to use before ' COMPONENT' = sub {} and simply
modify the passed in arguments.  I do not have any config in the model class
that I need to worry about merging with the passed in arguments.

Is this a reasonable way to do this?



-- 
Bill Moseley
mose...@hank.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/


Re: [Catalyst] Refactoring question

2010-05-27 Thread Bill Moseley
On Thu, May 27, 2010 at 5:38 AM, Steve st...@matsch.com wrote:

 I think your business logic should be moved to the model, not the
 controller.
 The model does the heavy lifting.


  My model is currently comprised only of my DBIC Result and ResultSet
 classes.  Are you suggesting that some of the logic in my controllers should
 be moved into my DBIC classes, or should I create new Moose classes.  If
 Moose, how do I 'hook up' those classes to Catalyst?


There's always room for another layer of abstraction.  That said, I find
that adding custom ResultSet and Result methods (and using custom base
classes for both) handles most of the abstraction.  You can abstract most
calls so that you aren't writing little, if any, DBIC-looking code in your
controllers.  The Controller actions should be pretty tiny -- just a few
lines at most.

Decouple as much as possible. If you have to fire up your web application
 in order to test database insertion, that's wrong. Build the model so that
 you can use Perl one liners to manipulate data through it.


True, although I've been working on an app that is entirely AJAX-based so
the Catalyst app is exposed as an API of URLs (I'll avoid the term REST
here).  So, that means all access to the app is via the API -- even for cron
scripts. As a result, the bulk of the tests are talking to the app via URLs
and HTTP method names.  (PUT /user/1234).  We still have tests for the
model, but no other code uses the model directly (by contract). We still
push as much code low into the model as possible.

And to your original post:

Take a look at
http://search.cpan.org/~masaki/Catalyst-Controller-Resources-0.08/ .

I would split up your existing controllers.  Think about the objects
returned and name them them the same.  I often have model class names that
are the same as controller class names (and form classes).   Need to get a
user?  /user/$id  Instead of a verb like /ViewStmt use a name for the thing
you want:  /statement/$id or /invoice/$id.  I'd be interested to hear
opinions about your admin interface,  but, I often mirror existing
controllers with /admin/user/$id  (admin's view of a user).

I often have a /login controller -- POST /login creates a new token
(cookie).  Then there's room for /login/forgot_my_password kind of thing.



-- 
Bill Moseley
mose...@hank.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/


Re: [Catalyst] Refactoring question

2010-05-27 Thread Bill Moseley
On Thu, May 27, 2010 at 8:09 AM, Steve st...@matsch.com wrote:


  At present, the only DBIC-looking code is contained in two lines
 (chaining resultsets).  I'm not sure it's worth the effort for this
 application, but it certainly will be for others.  Can you elaborate on the
 custom base classes idea?


Sorry for not being clear.  I was referring to DBIC base Result and base
ResultSet classes.




   In which case the controllers would be...?  Admin, User, and Statement?


Yes.

-- 
Bill Moseley
mose...@hank.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/


[Catalyst] Catalyst::TraitFor::Model::DBIC::Schema::Replicated connect info

2010-06-04 Thread Bill Moseley
The docs show:

__PACKAGE__-config({
traits = ['Replicated']
connect_info =
['dbi:mysql:master', 'user', 'pass'],
replicants = [
['dbi:mysql:slave1', 'user', 'pass'],
['dbi:mysql:slave2', 'user', 'pass'],
['dbi:mysql:slave3', 'user', 'pass'],
],
balancer_args = {
  master_read_weight = 0.3
}
});

Shouldn't that be regular connect_info?

my %config = (
traits = ['Replicated'],
connect_info = {
dsn = 'dbi:mysql:master',
user = 'username',
pass = 'password',
},
replicants = [
{
dsn = 'dbi:mysql:slave1',
user = 'username',
pass = 'password',
},
{
dsn = 'dbi:mysql:slave1',
user = 'username',
pass = 'password',
},
],
balancer_args = {
  master_read_weight = 0.3
}
);

-- 
Bill Moseley
mose...@hank.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/


[Catalyst] Re: Catalyst::TraitFor::Model::DBIC::Schema::Replicated connect info

2010-06-04 Thread Bill Moseley
It would seem there's a coercion for the synopsis syntax.  So, I'm not clear
if I'm using it incorrectly or if there's a problem.

So, if I take the SYNOPSIS example:

my %data = (
traits = ['Replicated'],
connect_info =
['dbi:mysql:master', 'user', 'pass'],
replicants = [
['dbi:mysql:slave1', 'user', 'pass'],
['dbi:mysql:slave2', 'user', 'pass'],
['dbi:mysql:slave3', 'user', 'pass'],
],
balancer_args = {
  master_read_weight = 0.3
}
);

and convert to YAML:


balancer_args:
  master_read_weight: 0.3
connect_info:
  - dbi:mysql:master
  - user
  - pass
replicants:
  -
- dbi:mysql:slave1
- user
- pass
  -
- dbi:mysql:slave2
- user
- pass
  -
- dbi:mysql:slave3
- user
- pass
traits:
  - Replicated

Then try with my actual YAML:

balancer_args:
  master_read_weight: 0.3
connect_info:
  - dbi:Pg:dbname=test
  -
  -

replicants:
  -
- dbi:Pg:dbname=slave
-
-
traits:
  - Replicated


Use of uninitialized value $driver in concatenation (.) or string at
/usr/local/share/perl/5.10.0/DBIx/Class/Storage/DBI.pm line 935.
DBIx::Class::Storage::throw_exception(): Can't locate
DBIx/Class/Storage/DBI/.pm in @INC


The hash-base connect_info works fine.


-- 
Bill Moseley
mose...@hank.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/


Re: [Catalyst] Re: Catalyst::TraitFor::Model::DBIC::Schema::Replicated connect info

2010-06-07 Thread Bill Moseley
On Mon, Jun 7, 2010 at 12:58 PM, Rafael Kitover rkito...@cpan.org wrote:

 The ::DBI::Replicated storage, to my knowledge, has only been tested on
 MySQL. If you are using it successfully with Postgres I would love to
 hear the details. Which replication software you are using, and does it
 work as you expect.


I've just started looking into using Replicated.

Slony is used for replication and there's discussion of using pgbouncer for
slave connection pooling.  An existing application that uses the same
database has a DBI subclass that works at the $dbh level to provide
replication, so looking at using that also.

Memcached is track when to force reads to the master after a write.  This is
keyed by user id -- i.e. once a user does a write then they are forced to
the master for an amount of time to let the slaves catch up.

What I'm now wondering about is where I could hook in to determine when a
write to the master happens so I can make all subsequent queries also go to
the master and to set a flag in memcached for other processes to detect.

But, this is a discussion that should be on the DBIC list.

-- 
Bill Moseley
mose...@hank.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/


[Catalyst] Wrong Content-Length value: 392918

2010-06-08 Thread Bill Moseley
I see these errors a few times a day.  I wonder why this is happening --
could the browser really send the wrong content length?  I seem to see it
often in ajax calls for a progress bar, but also during file uploads and
sometimes for just a normal post.

Is there any additional info that could be included in the exception message
that would help explain this?  Perhaps the length of data actual read in
addition to the content-length -- and maybe even the last few bytes read and
the content-type?  Could a failed or closed connection be causing this (and
reported in the message)?


# paranoia against wrong Content-Length header
my $remaining = $length - $self-read_position;
if ( $remaining  0 ) {
$self-finalize_read($c);
Catalyst::Exception-throw(
Wrong Content-Length value: $length );
}


-- 
Bill Moseley
mose...@hank.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/


[Catalyst] Module::Install::Catalyst very slow

2010-07-30 Thread Bill Moseley
When I run Makefile.PL the Module::Install::Catalyst step can take a number
of minutes -- it just took five minutes on one machine just now. I assume
that's because of the recursive copy.

Does the build process require actual copies or could symlinks be used to
speed up this process?

-- 
Bill Moseley
mose...@hank.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/


[Catalyst] Trapping exceptions in Catalyst.pm

2010-08-02 Thread Bill Moseley
In execute() there's this code:

eval { $c-state( $code-execute( $class, $c, @{ $c-req-args } ) || 0
) };

$c-_stats_finish_execute( $stats_info ) if $c-use_stats and
$stats_info;

my $last = pop( @{ $c-stack } );

if ( my $error = $@ ) {

The problem is that it's possible for the eval to fail but $@ is not set.
 An example is where Locale::Maketext localizes $@ so that exceptions come
back with $@ undefined (for some odd reason).

In general, it's better to test the return value from eval directly instead
of depend on $...@.  Something like:

my $has_exception;
eval { $c-state( $code-execute( $class, $c, @{ $c-req-args } ) || 0 );
1; } || $has_exception++;
...
if ( $has_exception ) {

Or use the eval {; 1 } || do { my $msg = $@; ...}; style.

-- 
Bill Moseley
mose...@hank.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/


Re: [Catalyst] Speeding up recovery from 503 errors + backend

2010-08-02 Thread Bill Moseley
On Mon, Aug 2, 2010 at 12:58 AM, Paul Makepeace pa...@paulm.com wrote:

 From time to time I forget to restart the Catalyst backend and Apache
 reports the usual 503 Service Temporarily Unavailable error.
 Annoyingly, even when the backend is restarted Apache seems to
 negatively cache that backend gone away result and keep serving
 503s. Is there a way to have it re-check every time, or some other
 solution that doesn't require an Apache restart?


See the retry setting:

 http://httpd.apache.org/docs/2.2/mod/mod_proxy.html#proxypass

We have the same issue when using mod_rewrite to proxy with [P].

You might want to look at using some other type of front end proxy, too,
perhaps Perlbal.


-- 
Bill Moseley
mose...@hank.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/


Re: [Catalyst] process a restored request

2010-08-04 Thread Bill Moseley
On Wed, Aug 4, 2010 at 11:22 AM, Steve st...@matsch.com wrote:

 Original post:
 http://www.mail-archive.com/catalyst@lists.scsys.co.uk/msg01222.html

 My apologies for rehashing this old post, but this is such a *nice* thing
 to do for users that
 I'm sort of surprised the solution hasn't been implemented as a plugin or
 something, at least
 so far as I can tell...

 I'm trying to implement this elegant solution, but am getting stuck with
 the

 'just dump any POST data back out into
 hidden fields in the login form, don't change the URL, and have the login
 form processed in a forward() from auto or similar rather than doing a
 detach' part.


I think the suggestion was in auto always check if authenticated.  If not
authenticated, then attempt to authenticate with existing form data (e.g. if
a username and password have been posted).  if that succeeds then just
continue on to the requested action.

If cannot authenticate then display a login form but also include all other
parameters that were posted in hidden fields.  Set the action to post back
to the original action.

Repeat.

You probably want to track the original request method (GET POST PUT DELETE)
so that when the form is submitted (and finally authenticated) your action
sees the original request method.

If there's upload data then you would need to handle that additionally.




 My questions are as follows:
 What hidden field or fields are in the login form?


One for each posted parameter.



 Where in the code sample are the items stashed? (or are they stored
 elsewhere?)


When rendering the form.  You are using the client as a store.



 Where in the code sample do we pick up after successful
 authentication in order to (forward, detach, redirect - pick one or supply
 alt.)?


You don't.  if the original post was to /user (e.g. to create a new user)
then the login form looks just like your normal login form, but the action
is a POST to /user.



-- 
Bill Moseley
mose...@hank.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/


Re: [Catalyst] I18N with variables

2010-08-06 Thread Bill Moseley
On Fri, Aug 6, 2010 at 6:16 AM, Matthias Dietrich mdietr...@cpan.orgwrote:

 I'm using short identifiers for my I18N texts, like Home.Greeting which
 is then translated to Hi there for en_us or Hallöchen for de_de.  When I
 added a small CMS to a customer's application all texts should also be
 translated.  So I saved any text to I18N key CMS.NavigationPoint.PageKey.*
 within the right language file (actually I'm using C::P::I18N::DBI), * for
 Title or Content or similar.


I've been arguing with work about how to key our text.  So far we continue
to use the English in the loc() tags in the templates, and then the I18N
team uses a script to pull out this text which gets sent to translation
services.

The risk is text gets into the templates that for some reason does not get
pulled out.  The developers like the English in the templates as it makes
them easy to read, and it means they don't really have to stop when entering
new text.  Just seems like in the long run this will be unmaintainable and
error prone.  (Well, not in the long run as it already is error prone.)

I've been arguing for a system where we use some kind of ID for the keys.
 I'm not so sure the key format matters -- could be just a primary key in
the db, for example.  This could be a stage done by the designers so the
design spec just indicates a message id.  Then code development and
translation can happen at the same time.

Is anyone using a system like that?  And more specifically, what application
are you using to manage the translation database?  We have started to write
one, but it's a bit more than trivial as we need it to work with different
translation services, track history/changes, multiple applications, etc.
 So, it would make more sense to use an existing tool.

So, I'd like to hear about your translation workflow and any tools you are
using.

Thanks,


-- 
Bill Moseley
mose...@hank.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/


Re: [Catalyst] Module::Install::Catalyst very slow

2010-08-16 Thread Bill Moseley
On Fri, Jul 30, 2010 at 8:13 AM, Curtis Jewell p...@csjewell.fastmail.uswrote:

 So the build process can't symlink without checking for support for it
 first. (Catalyst DOES run on Win32, after all, as well as the Unixen.)


Of course.


Here's an svn export of an app:

$ find . | wc -l
35677

$ fgrep 'model name' /proc/cpuinfo | uniq -c
  8 model name  : Intel(R) Xeon(R) CPU   E5335  @ 2.00GHz

(not that the number of cores makes a difference here)

$ time perl Makefile.PL
...
real4m25.784s
user0m4.670s
sys 0m5.110s


See any situations where symlink (as in attached diff) would not work?









 On Fri, 30 Jul 2010 07:46 -0700, Bill Moseley mose...@hank.org
 wrote:
  When I run Makefile.PL the Module::Install::Catalyst step can take a
  number
  of minutes -- it just took five minutes on one machine just now. I assume
  that's because of the recursive copy.
 
  Does the build process require actual copies or could symlinks be used to
  speed up this process?
 --
 Curtis Jewell
 csjew...@cpan.org   http://csjewell.dreamwidth.org/
 p...@csjewell.fastmail.us   http://csjewell.comyr.org/perl/

 Your random numbers are not that random -- perl-5.10.1.tar.gz/util.c

 Strawberry Perl for Windows betas: http://strawberryperl.com/beta/


 ___
 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/




-- 
Bill Moseley
mose...@hank.org


Module-Install-Catalyst.diff
Description: Binary data
___
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: [Catalyst] Module::Install::Catalyst very slow

2010-08-16 Thread Bill Moseley
Oh, that patch will break when used on an existing tree, so don't use.  And
I'm not clear how distclean will work with the symlinks.

So, if destination is already a symlink is there anything to do?  Assume
it's already linked.
And if it's a regular dir then do the rcopy?

I'm using this just to speed up places where people are running the
Makefile.PL script somewhat often.
But, as a replacement for rcopy a bit more testing is needed to see what
might break.

Sorry for the noise.





On Mon, Aug 16, 2010 at 5:03 PM, Bill Moseley mose...@hank.org wrote:

 On Fri, Jul 30, 2010 at 8:13 AM, Curtis Jewell 
 p...@csjewell.fastmail.uswrote:

 So the build process can't symlink without checking for support for it
 first. (Catalyst DOES run on Win32, after all, as well as the Unixen.)


 Of course.


 Here's an svn export of an app:

  $ find . | wc -l
 35677

 $ fgrep 'model name' /proc/cpuinfo | uniq -c
   8 model name  : Intel(R) Xeon(R) CPU   E5335  @ 2.00GHz

 (not that the number of cores makes a difference here)

 $ time perl Makefile.PL
 ...
 real4m25.784s
 user0m4.670s
 sys 0m5.110s


 See any situations where symlink (as in attached diff) would not work?









 On Fri, 30 Jul 2010 07:46 -0700, Bill Moseley mose...@hank.org
 wrote:
  When I run Makefile.PL the Module::Install::Catalyst step can take a
  number
  of minutes -- it just took five minutes on one machine just now. I
 assume
  that's because of the recursive copy.
 
  Does the build process require actual copies or could symlinks be used
 to
  speed up this process?
 --
 Curtis Jewell
 csjew...@cpan.org   http://csjewell.dreamwidth.org/
 p...@csjewell.fastmail.us   http://csjewell.comyr.org/perl/

 Your random numbers are not that random -- perl-5.10.1.tar.gz/util.c

 Strawberry Perl for Windows betas: http://strawberryperl.com/beta/


 ___
 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/




 --
 Bill Moseley
 mose...@hank.org




-- 
Bill Moseley
mose...@hank.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/


<    1   2   3   4   >