update distar url
[catagits/Catalyst-Runtime.git] / lib / Catalyst.pm
index b085a6c..de488a4 100644 (file)
@@ -27,7 +27,7 @@ use HTML::Entities;
 use Tree::Simple qw/use_weak_refs/;
 use Tree::Simple::Visitor::FindByUID;
 use Class::C3::Adopt::NEXT;
-use List::MoreUtils qw/uniq/;
+use List::Util qw/uniq/;
 use attributes;
 use String::RewritePrefix;
 use Catalyst::EngineLoader;
@@ -51,6 +51,10 @@ use Catalyst::Middleware::Stash;
 use Plack::Util;
 use Class::Load 'load_class';
 use Encode 2.21 'decode_utf8', 'encode_utf8';
+use Scalar::Util;
+
+our $VERSION = '5.90128';
+$VERSION =~ tr/_//d;
 
 BEGIN { require 5.008003; }
 
@@ -67,6 +71,7 @@ has request => (
         my $composed_request_class = $class->composed_request_class;
         return $composed_request_class->new( $self->_build_request_constructor_args);
     },
+    predicate => 'has_request',
     lazy => 1,
 );
 sub _build_request_constructor_args {
@@ -112,6 +117,7 @@ has response => (
         my $composed_response_class = $class->composed_response_class;
         return $composed_response_class->new( $self->_build_response_constructor_args);
     },
+    predicate=>'has_response',
     lazy => 1,
 );
 sub _build_response_constructor_args {
@@ -124,7 +130,7 @@ sub _build_response_constructor_args {
 sub composed_response_class {
   my $class = shift;
   return $class->_composed_response_class if $class->_composed_response_class;
-  
+
   my @traits = (@{$class->response_class_traits||[]}, @{$class->config->{response_class_traits}||[]});
 
   my $trait_ns = 'TraitFor::Response';
@@ -164,7 +170,7 @@ our $RECURSION = 1000;
 our $DETACH    = Catalyst::Exception::Detach->new;
 our $GO        = Catalyst::Exception::Go->new;
 
-#I imagine that very few of these really 
+#I imagine that very few of these really
 #need to be class variables. if any.
 #maybe we should just make them attributes with a default?
 __PACKAGE__->mk_classdata($_)
@@ -203,10 +209,6 @@ sub composed_stats_class {
 
 __PACKAGE__->_encode_check(Encode::FB_CROAK | Encode::LEAVE_SRC);
 
-# Remember to update this in Catalyst::Runtime as well!
-our $VERSION = '5.90106';
-$VERSION = eval $VERSION if $VERSION =~ /_/; # numify for warning-free dev releases
-
 sub import {
     my ( $class, @arguments ) = @_;
 
@@ -246,11 +248,6 @@ sub _application { $_[0] }
 
 Catalyst - The Elegant MVC Web Application Framework
 
-=for html
-<a href="https://badge.fury.io/pl/Catalyst-Runtime"><img src="https://badge.fury.io/pl/Catalyst-Runtime.svg" alt="CPAN version" height="18"></a>
-<a href="https://travis-ci.org/perl-catalyst/catalyst-runtime/"><img src="https://api.travis-ci.org/perl-catalyst/catalyst-runtime.png" alt="Catalyst></a>
-<a href="http://cpants.cpanauthors.org/dist/Catalyst-Runtime"><img src="http://cpants.cpanauthors.org/dist/Catalyst-Runtime.png" alt='Kwalitee Score' /></a>
-
 =head1 SYNOPSIS
 
 See the L<Catalyst::Manual> distribution for comprehensive
@@ -413,6 +410,10 @@ Returns the current L<Catalyst::Request> object, giving access to
 information about the current client request (including parameters,
 cookies, HTTP headers, etc.). See L<Catalyst::Request>.
 
+There is a predicate method C<has_request> that returns true if the
+request object has been created.  This is something you might need to
+check if you are writing plugins that run before a request is finalized.
+
 =head2 REQUEST FLOW HANDLING
 
 =head2 $c->forward( $action [, \@arguments ] )
@@ -474,7 +475,7 @@ or stash it like so:
 
 and access it from the stash.
 
-Keep in mind that the C<end> method used is that of the caller action. So a C<$c-E<gt>detach> inside a forwarded action would run the C<end> method from the original action requested.
+Keep in mind that the C<end> method used is that of the caller action. So a C<< $c->detach >> inside a forwarded action would run the C<end> method from the original action requested.
 
 =cut
 
@@ -561,6 +562,10 @@ sub go { my $c = shift; $c->dispatcher->go( $c, @_ ) }
 
 Returns the current L<Catalyst::Response> object, see there for details.
 
+There is a predicate method C<has_response> that returns true if the
+request object has been created.  This is something you might need to
+check if you are writing plugins that run before a request is finalized.
+
 =head2 $c->stash
 
 Returns a hashref to the stash, which may be used to store data and pass
@@ -1436,9 +1441,9 @@ EOF
         }
 
         my @middleware = map {
-          ref $_ eq 'CODE' ? 
-            "Inline Coderef" : 
-              (ref($_) .'  '. ($_->can('VERSION') ? $_->VERSION || '' : '') 
+          ref $_ eq 'CODE' ?
+            "Inline Coderef" :
+              (ref($_) .'  '. ($_->can('VERSION') ? $_->VERSION || '' : '')
                 || '')  } $class->registered_middlewares;
 
         if (@middleware) {
@@ -1605,11 +1610,11 @@ sub uri_for {
         $path .= '/';
     }
 
-    my $fragment =  ((scalar(@args) && ref($args[-1]) eq 'SCALAR') ? pop @args : undef );
+    my $fragment =  ((scalar(@args) && ref($args[-1]) eq 'SCALAR') ? ${pop @args} : undef );
 
     unless(blessed $path) {
       if (defined($path) and $path =~ s/#(.+)$//)  {
-        if(defined($1) and $fragment) {
+        if(defined($1) and defined $fragment) {
           carp "Abiguious fragment declaration: You cannot define a fragment in '$path' and as an argument '$fragment'";
         }
         if(defined($1)) {
@@ -1638,14 +1643,15 @@ sub uri_for {
         my $num_captures = $expanded_action->number_of_captures;
 
         # ->uri_for( $action, \@captures_and_args, \%query_values? )
-        if( !@args && $action->number_of_args ) {
+        if( !@args && $action->number_of_args && @$captures > $num_captures ) {
           unshift @args, splice @$captures, $num_captures;
         }
 
         if($num_captures) {
           unless($expanded_action->match_captures_constraints($c, $captures)) {
-            carp "captures [@{$captures}] do not match the type constraints in actionchain ending with '$expanded_action'";
-            return;
+            $c->log->debug("captures [@{$captures}] do not match the type constraints in actionchain ending with '$expanded_action'")
+                if $c->debug;
+            return undef;
           }
         }
 
@@ -1660,8 +1666,9 @@ sub uri_for {
         # At this point @encoded_args is the remaining Args (all captures removed).
         if($expanded_action->has_args_constraints) {
           unless($expanded_action->match_args($c,\@args)) {
-             carp "args [@args] do not match the type constraints in action '$expanded_action'";
-             return;
+             $c->log->debug("args [@args] do not match the type constraints in action '$expanded_action'")
+                if $c->debug;
+             return undef;
           }
         }
     }
@@ -1705,23 +1712,20 @@ sub uri_for {
       # somewhat lifted from URI::_query's query_form
       $query = '?'.join('&', map {
           my $val = $params->{$_};
-          #s/([;\/?:@&=+,\$\[\]%])/$URI::Escape::escapes{$1}/go; ## Commented out because seems to lead to double encoding - JNAP
-          s/ /+/g;
-          my $key = $_;
+          my $key = encode_utf8($_);
+          # using the URI::Escape pattern here so utf8 chars survive
+          $key =~ s/([^A-Za-z0-9\-_.!~*'() ])/$URI::Escape::escapes{$1}/go;
+          $key =~ s/ /+/g;
+
           $val = '' unless defined $val;
           (map {
-              my $param = "$_";
-              $param = encode_utf8($param);
+              my $param = encode_utf8($_);
               # using the URI::Escape pattern here so utf8 chars survive
               $param =~ s/([^A-Za-z0-9\-_.!~*'() ])/$URI::Escape::escapes{$1}/go;
               $param =~ s/ /+/g;
 
-              $key = encode_utf8($key);
-              # using the URI::Escape pattern here so utf8 chars survive
-              $key =~ s/([^A-Za-z0-9\-_.!~*'() ])/$URI::Escape::escapes{$1}/go;
-              $key =~ s/ /+/g;
-
-              "${key}=$param"; } ( ref $val eq 'ARRAY' ? @$val : $val ));
+              "${key}=$param";
+          } ( ref $val eq 'ARRAY' ? @$val : $val ));
       } @keys);
     }
 
@@ -1732,7 +1736,7 @@ sub uri_for {
 
     if(defined $fragment) {
       if(blessed $path) {
-        $fragment = encode_utf8(${$fragment});
+        $fragment = encode_utf8($fragment);
         $fragment =~ s/([^A-Za-z0-9\-_.!~*'() ])/$URI::Escape::escapes{$1}/go;
         $fragment =~ s/ /+/g;
       }
@@ -1776,7 +1780,7 @@ and it will create the URI /users/the-list.
 
 =item \@captures_and_args?
 
-Optional array reference of Captures (i.e. C<<CaptureArgs or $c->req->captures>)
+Optional array reference of Captures (i.e. C<CaptureArgs> or C<< $c->req->captures >>)
 and arguments to the request. Usually used with L<Catalyst::DispatchType::Chained>
 to interpolate all the parameters in the URI.
 
@@ -2201,16 +2205,27 @@ sub finalize {
 
     $c->log_response;
 
-    if ($c->use_stats) {
-        my $elapsed = $c->stats->elapsed;
-        my $av = $elapsed == 0 ? '??' : sprintf '%.3f', 1 / $elapsed;
-        $c->log->info(
-            "Request took ${elapsed}s ($av/s)\n" . $c->stats->report . "\n" );
-    }
+    $c->log_stats if $c->use_stats;
 
     return $c->response->status;
 }
 
+=head2 $c->log_stats
+
+Logs statistics.
+
+=cut
+
+sub log_stats {
+    my $c = shift;
+
+    my $elapsed = $c->stats->elapsed;
+    my $av = $elapsed == 0 ? '??' : sprintf '%.3f', 1 / $elapsed;
+    $c->log->info(
+        "Request took ${elapsed}s ($av/s)\n" . $c->stats->report . "\n" );
+}
+
+
 =head2 $c->finalize_body
 
 Finalizes body.
@@ -2307,7 +2322,7 @@ sub finalize_encoding {
     # to do this early since encodable_response is false for this condition and we need
     # to match the debug output for backcompat (there's a test for this...) -JNAP
     if(
-      $res->content_type_charset and $c->encoding and 
+      $res->content_type_charset and $c->encoding and
       (uc($c->encoding->mime_name) ne uc($res->content_type_charset))
     ) {
         my $ct = lc($res->content_type_charset);
@@ -2321,10 +2336,14 @@ sub finalize_encoding {
       (defined($res->body)) and
       (ref(\$res->body) eq 'SCALAR')
     ) {
+        # if you are finding yourself here and your body is already encoded correctly
+        # and you want to turn this off, use $c->clear_encoding to prevent encoding
+        # at this step, or set encoding to undef in the config to do so for the whole
+        # application.  See the ENCODING documentaiton for better notes.
         $c->res->body( $c->encoding->encode( $c->res->body, $c->_encode_check ) );
 
         # Set the charset if necessary.  This might be a bit bonkers since encodable response
-        # is false when the set charset is not the same as the encoding mimetype (maybe 
+        # is false when the set charset is not the same as the encoding mimetype (maybe
         # confusing action at a distance here..
         # Don't try to set the charset if one already exists or if headers are already finalized
         $c->res->content_type($c->res->content_type . "; charset=" . $c->encoding->mime_name)
@@ -2490,6 +2509,8 @@ sub prepare {
     };
 
     $c->log_request;
+    $c->{stash} = $c->stash;
+    Scalar::Util::weaken($c->{stash});
 
     return $c;
 }
@@ -2738,9 +2759,16 @@ sub log_request_parameters {
         next if ! keys %$params;
         my $t = Text::SimpleTable->new( [ 35, 'Parameter' ], [ $column_width, 'Value' ] );
         for my $key ( sort keys %$params ) {
-            my $param = $params->{$key};
-            my $value = defined($param) ? $param : '';
-            $t->row( $key, ref $value eq 'ARRAY' ? ( join ', ', @$value ) : $value );
+            my @values = ();
+            if(ref $params eq 'Hash::MultiValue') {
+                @values = $params->get_all($key);
+            } else {
+                my $param = $params->{$key};
+                if( defined($param) ) {
+                    @values = ref $param eq 'ARRAY' ? @$param : $param;
+                }
+            }
+            $t->row( $key.( scalar @values > 1 ? ' [multiple]' : ''), join(', ', @values) );
         }
         $c->log->debug( ucfirst($type) . " Parameters are:\n" . $t->draw );
     }
@@ -2871,7 +2899,7 @@ We try each possible role in turn (and throw an error if none load)
 The namespace part 'TraitFor::Request' was chosen to assist in backwards
 compatibility with L<CatalystX::RoleApplicator> which previously provided
 these features in a stand alone package.
-  
+
 =head2 $app->composed_request_class
 
 This is the request class which has been composed with any request_class_traits.
@@ -3231,7 +3259,7 @@ sub setup_component {
       $class->components->{ $component } = $class->setup_component($component);
     }
 
-    return $instance; 
+    return $instance;
 }
 
 =head2 $app->config_for( $component_name )
@@ -3246,7 +3274,7 @@ component or component object. Example:
 
     my $config = MyApp->config_for('MyApp::Model::Foo');
 
-In this case $config is the hashref C< {a=>1, b=>2} >.
+In this case $config is the hashref C<< {a=>1, b=>2} >>.
 
 This is also handy for looking up configuration for a plugin, to make sure you follow
 existing L<Catalyst> standards for where a plugin should put its configuration.
@@ -3356,7 +3384,7 @@ sub setup_engine {
     return;
 }
 
-## This exists just to supply a prebuild psgi app for mod_perl and for the 
+## This exists just to supply a prebuild psgi app for mod_perl and for the
 ## build in server support (back compat support for pre psgi port behavior).
 ## This is so that we don't build a new psgi app for each request when using
 ## the mod_perl handler or the built in servers (http and fcgi, etc).
@@ -3373,7 +3401,7 @@ sub _finalized_psgi_app {
 }
 
 ## Look for a psgi file like 'myapp_web.psgi' (if the app is MyApp::Web) in the
-## home directory and load that and return it (just assume it is doing the 
+## home directory and load that and return it (just assume it is doing the
 ## right thing :) ).  If that does not exist, call $app->psgi_app, wrap that
 ## in default_middleware and return it ( this is for backward compatibility
 ## with pre psgi port behavior ).
@@ -3459,7 +3487,7 @@ sub apply_default_middlewares {
           condition => sub {
               my ($env) = @_;
               return if $app->config->{ignore_frontend_proxy};
-              return $env->{REMOTE_ADDR} eq '127.0.0.1';
+              return $env->{REMOTE_ADDR} && $env->{REMOTE_ADDR} eq '127.0.0.1';
           },
       );
     }
@@ -3571,18 +3599,23 @@ sub setup_encoding {
 
 =head2 handle_unicode_encoding_exception
 
-Hook to let you customize how encoding errors are handled.  By default
-we just throw an exception.  Receives a hashref of debug information.
-Example of call:
+Hook to let you customize how encoding errors are handled. By default
+we just throw an exception and the default error page will pick it up.
+Receives a hashref of debug information. Example of call (from the
+Catalyst internals):
 
-    $c->handle_unicode_encoding_exception({
+  my $decoded_after_fail = $c->handle_unicode_encoding_exception({
         param_value => $value,
         error_msg => $_,
         encoding_step => 'params',
-        });
+   });
 
-You can override this for custom handling of unicode errors.  If you want a
-custom response here, one approach is to throw an HTTP style exception:
+The calling code expects to receive a decoded string or an exception.
+
+You can override this for custom handling of unicode errors. By
+default we just die. If you want a custom response here, one approach
+is to throw an HTTP style exception, instead of returning a decoded
+string or throwing a generic exception.
 
     sub handle_unicode_encoding_exception {
       my ($c, $params) = @_;
@@ -3595,9 +3628,16 @@ in your application:
     sub handle_unicode_encoding_exception {
       my ($c, $params) = @_;
       $c->stash(BAD_UNICODE_DATA=>$params);
+      # return a dummy string.
       return 1;
     }
 
+<B>NOTE:</b> Please keep in mind that once an error like this occurs,
+the request setup is still ongoing, which means the state of C<$c> and
+related context parts like the request and response may not be setup
+up correctly (since we haven't finished the setup yet). If you throw
+an exception the setup is aborted.
+
 =cut
 
 sub handle_unicode_encoding_exception {
@@ -3637,16 +3677,20 @@ sub _handle_unicode_decoding {
 }
 
 sub _handle_param_unicode_decoding {
-    my ( $self, $value ) = @_;
+    my ( $self, $value, $check ) = @_;
     return unless defined $value; # not in love with just ignoring undefs - jnap
     return $value if blessed($value); #don't decode when the value is an object.
 
     my $enc = $self->encoding;
+
+    return $value unless $enc; # don't decode if no encoding is specified
+
+    $check ||= $self->_encode_check;
     return try {
-      $enc->decode( $value, $self->_encode_check );
+      $enc->decode( $value, $check);
     }
     catch {
-        $self->handle_unicode_encoding_exception({
+        return $self->handle_unicode_encoding_exception({
             param_value => $value,
             error_msg => $_,
             encoding_step => 'params',
@@ -3992,14 +4036,14 @@ only two default data handlers, for 'application/json' and an alternative to
 L<CGI::Struct> or via L<CGI::Struct::XS> IF you've installed it.
 
 The 'application/json' data handler is used to parse incoming JSON into a Perl
-data structure.  It used either L<JSON::MaybeXS> or L<JSON>, depending on which
-is installed.  This allows you to fail back to L<JSON:PP>, which is a Pure Perl
-JSON decoder, and has the smallest dependency impact.
+data structure.  It uses L<JSON::MaybeXS>.  This allows you to fail back to
+L<JSON::PP>, which is a Pure Perl JSON decoder, and has the smallest dependency
+impact.
 
 Because we don't wish to add more dependencies to L<Catalyst>, if you wish to
-use this new feature we recommend installing L<JSON> or L<JSON::MaybeXS> in
-order to get the best performance.  You should add either to your dependency
-list (Makefile.PL, dist.ini, cpanfile, etc.)
+use this new feature we recommend installing L<Cpanel::JSON::XS> in order to get
+the best performance.  You should add either to your dependency list
+(Makefile.PL, dist.ini, cpanfile, etc.)
 
 =cut
 
@@ -4034,12 +4078,12 @@ sub default_data_handlers {
       },
       'application/json' => sub {
           my ($fh, $req) = @_;
-          my $parser = Class::Load::load_first_existing_class('JSON::MaybeXS', 'JSON');
+          require JSON::MaybeXS;
           my $slurped;
-          return eval { 
+          return eval {
             local $/;
             $slurped = $fh->getline;
-            $parser->can("decode_json")->($slurped); # decode_json does utf8 decoding for us
+            JSON::MaybeXS::decode_json($slurped); # decode_json does utf8 decoding for us
           } || Catalyst::Exception->throw(sprintf "Error Parsing POST '%s', Error: %s", (defined($slurped) ? $slurped : 'undef') ,$@);
         },
     };
@@ -4073,7 +4117,7 @@ L<Catalyst::Stats|Catalyst::Stats>, but can be set otherwise with
 L<< stats_class|/"$c->stats_class" >>.
 
 Even if L<< -Stats|/"-Stats" >> is not enabled, the stats object is still
-available. By enabling it with C< $c->stats->enabled(1) >, it can be used to
+available. By enabling it with C<< $c->stats->enabled(1) >>, it can be used to
 profile explicitly, although MyApp.pm still won't profile nor output anything
 by itself.
 
@@ -4281,18 +4325,20 @@ value to undef.
 
 C<abort_chain_on_error_fix>
 
-When there is an error in an action chain, the default behavior is to continue
-processing the remaining actions and then catch the error upon chain end.  This
-can lead to running actions when the application is in an unexpected state.  If
-you have this issue, setting this config value to true will promptly exit a
-chain when there is an error raised in any action (thus terminating the chain
-early.)
+Defaults to true.
+
+When there is an error in an action chain, the default behavior is to
+abort the processing of the remaining actions to avoid running them
+when the application is in an unexpected state.
 
-use like:
+Before version 5.90070, the default used to be false. To keep the old
+behaviour, you can explicitly set the value to false. E.g.
 
-    __PACKAGE__->config(abort_chain_on_error_fix => 1);
+    __PACKAGE__->config(abort_chain_on_error_fix => 0);
+
+If this setting is set to false, then the remaining actions are
+performed and the error is caught at the end of the chain.
 
-In the future this might become the default behavior.
 
 =item *
 
@@ -4323,7 +4369,7 @@ that does not contain uploads, but instead contains inlined complex data
 (very uncommon) we cannot reliably convert that into field => value pairs.  So
 instead we create an instance of L<Catalyst::Request::PartData>.  If this causes
 issue for you, you can disable this by setting C<skip_complex_post_part_handling>
-to true (default is false).  
+to true (default is false).
 
 =item *
 
@@ -4344,11 +4390,19 @@ request URL query or keywords.  Most readings of the relevant specifications
 suggest these should be UTF-* encoded, which is the default that L<Catalyst>
 will use, however if you are creating a lot of URLs manually or have external
 evil clients, this might cause you trouble.  If you find the changes introduced
-in Catalyst version 5.90080+ break some of your query code, you may disable 
+in Catalyst version 5.90080+ break some of your query code, you may disable
 the UTF-8 decoding globally using this configuration.
 
-This setting takes precedence over C<default_query_encoding> and
-C<decode_query_using_global_encoding>
+This setting takes precedence over C<default_query_encoding>
+
+=item *
+
+C<do_not_check_query_encoding>
+
+Catalyst versions 5.90080 - 5.90106 would decode query parts of an incoming
+request but would not raise an exception when the decoding failed due to
+incorrect unicode.  It now does, but if this change is giving you trouble
+you may disable it by setting this configuration to true.
 
 =item *
 
@@ -4359,15 +4413,6 @@ is our reading of the relevant specifications.  This setting allows one to
 specify a fixed value for how to decode your query.  You might need this if
 you are doing a lot of custom encoding of your URLs and not using UTF-8.
 
-This setting take precedence over C<decode_query_using_global_encoding>.
-
-=item *
-
-C<decode_query_using_global_encoding>
-
-Setting this to true will default your query decoding to whatever your
-general global encoding is (the default is UTF-8).
-
 =item *
 
 C<use_chained_args_0_special_case>
@@ -4562,21 +4607,21 @@ option, C<data_handlers>, which lets you associate a content type with a coderef
 that parses that content type into something Perl can readily access.
 
     package MyApp::Web;
+
     use Catalyst;
-    use JSON::Maybe;
+    use JSON::MaybeXS;
+
     __PACKAGE__->config(
       data_handlers => {
         'application/json' => sub { local $/; decode_json $_->getline },
       },
       ## Any other configuration.
     );
+
     __PACKAGE__->setup;
 
 By default L<Catalyst> comes with a generic JSON data handler similar to the
-example given above, which uses L<JSON::Maybe> to provide either L<JSON::PP>
+example given above, which uses L<JSON::MaybeXS> to provide either L<JSON::PP>
 (a pure Perl, dependency free JSON parser) or L<Cpanel::JSON::XS> if you have
 it installed (if you want the faster XS parser, add it to you project Makefile.PL
 or dist.ini, cpanfile, etc.)
@@ -4598,12 +4643,12 @@ arrayref under the configuration key C<psgi_middleware>.  Here's an example
 with details to follow:
 
     package MyApp::Web;
+
     use Catalyst;
     use Plack::Middleware::StackTrace;
+
     my $stacktrace_middleware = Plack::Middleware::StackTrace->new;
+
     __PACKAGE__->config(
       'psgi_middleware', [
         'Debug',
@@ -4620,7 +4665,7 @@ with details to follow:
         },
       ],
     );
+
     __PACKAGE__->setup;
 
 So the general form is:
@@ -4646,26 +4691,26 @@ middleware will wrap closer to the application).  Keep this in mind since in
 some cases the order of middleware is important.
 
 The two approaches are not exclusive.
+
 =over 4
+
 =item Middleware Object
+
 An already initialized object that conforms to the L<Plack::Middleware>
 specification:
+
     my $stacktrace_middleware = Plack::Middleware::StackTrace->new;
+
     __PACKAGE__->config(
       'psgi_middleware', [
         $stacktrace_middleware,
       ]);
+
+
 =item coderef
+
 A coderef that is an inlined middleware:
+
     __PACKAGE__->config(
       'psgi_middleware', [
         sub {
@@ -4682,11 +4727,11 @@ A coderef that is an inlined middleware:
          },
       },
     ]);
+
+
+
 =item a scalar
+
 We assume the scalar refers to a namespace after normalizing it using the
 following rules:
 
@@ -4717,12 +4762,12 @@ Examples:
         '+MyApp::Custom',  ## MyApp::Custom->wrap
       ],
     );
+
 =item a scalar followed by a hashref
+
 Just like the previous, except the following C<HashRef> is used as arguments
 to initialize the middleware object.
+
     __PACKAGE__->config(
       'psgi_middleware', [
          'Session' => {store => 'File'},
@@ -4747,6 +4792,11 @@ the encoding configuration to undef.
 
 This is recommended for temporary backwards compatibility only.
 
+To turn it off for a single request use the L<clear_encoding>
+method to turn off encoding for this request.  This can be useful
+when you are setting the body to be an arbitrary block of bytes,
+especially if that block happens to be a block of UTF8 text.
+
 Encoding is automatically applied when the content-type is set to
 a type that can be encoded.  Currently we encode when the content type
 matches the following regular expression:
@@ -4869,7 +4919,7 @@ andrewalker: André Walker <andre@cpan.org>
 
 Andrew Bramble
 
-Andrew Ford E<lt>A.Ford@ford-mason.co.ukE<gt>
+Andrew Ford <A.Ford@ford-mason.co.uk>
 
 Andrew Ruthven
 
@@ -4883,19 +4933,19 @@ Caelum: Rafael Kitover <rkitover@io.com>
 
 chansen: Christian Hansen
 
-Chase Venters C<chase.venters@gmail.com>
+Chase Venters <chase.venters@gmail.com>
 
 chicks: Christopher Hicks
 
-Chisel Wright C<pause@herlpacker.co.uk>
+Chisel Wright <pause@herlpacker.co.uk>
 
-Danijel Milicevic C<me@danijel.de>
+Danijel Milicevic <me@danijel.de>
 
 davewood: David Schmidt <davewood@cpan.org>
 
-David Kamholz E<lt>dkamholz@cpan.orgE<gt>
+David Kamholz <dkamholz@cpan.org>
 
-David Naughton, C<naughton@umn.edu>
+David Naughton <naughton@umn.edu>
 
 David E. Wheeler
 
@@ -4917,7 +4967,7 @@ gabb: Danijel Milicevic
 
 Gary Ashton Jones
 
-Gavin Henry C<ghenry@perl.me.uk>
+Gavin Henry <ghenry@perl.me.uk>
 
 Geoff Richards
 
@@ -4929,7 +4979,7 @@ ilmari: Dagfinn Ilmari MannsÃ¥ker <ilmari@ilmari.org>
 
 jcamacho: Juan Camacho
 
-jester: Jesse Sheidlower C<jester@panix.com>
+jester: Jesse Sheidlower <jester@panix.com>
 
 jhannah: Jay Hannah <jay@jays.net>
 
@@ -4939,9 +4989,9 @@ Johan Lindstrom
 
 jon: Jon Schutz <jjschutz@cpan.org>
 
-Jonathan Rockway C<< <jrockway@cpan.org> >>
+Jonathan Rockway <jrockway@cpan.org>
 
-Kieren Diment C<kd@totaldatasolution.com>
+Kieren Diment <kd@totaldatasolution.com>
 
 konobi: Scott McWhirter <konobi@cpan.org>
 
@@ -4977,7 +5027,11 @@ rafl: Florian Ragwitz <rafl@debian.org>
 
 random: Roland Lammel <lammel@cpan.org>
 
-Robert Sedlacek C<< <rs@474.at> >>
+revmischa: Mischa Spiegelmock <revmischa@cpan.org>
+
+Robert Sedlacek <rs@474.at>
+
+rrwo: Robert Rothenberg <rrwo@cpan.org>
 
 SpiceMan: Marcel Montes
 
@@ -4991,17 +5045,17 @@ Ulf Edvinsson
 
 vanstyn: Henry Van Styn <vanstyn@cpan.org>
 
-Viljo Marrandi C<vilts@yahoo.com>
+Viljo Marrandi <vilts@yahoo.com>
 
-Will Hawes C<info@whawes.co.uk>
+Will Hawes <info@whawes.co.uk>
 
 willert: Sebastian Willert <willert@cpan.org>
 
 wreis: Wallace Reis <wreis@cpan.org>
 
-Yuval Kogman, C<nothingmuch@woobling.org>
+Yuval Kogman <nothingmuch@woobling.org>
 
-rainboxx: Matthias Dietrich, C<perl@rainboxx.de>
+rainboxx: Matthias Dietrich <perl@rainboxx.de>
 
 dd070: Dhaval Dhanani <dhaval070@gmail.com>