NAME
Plack::Middleware::Debugger::Injector - Middleware for injecting content into a web request
VERSION
version 0.03
DESCRIPTION
This middleware is used to inject some content into the body of a given web request right before the closing <body
> tag. Its primary use-case is to inject a <script
> tag which will then create the Plack::Debugger debugging UI.
Since this middleware will run on every request it has to decide if injection is sensible or not. It does this by checking the HTTP status code, some HTTP headers and finally the content-type of the response.
Status codes
Most status codes not in the 2xx
range are ignored since they rarely contain a body that is of consequence to this module. The only exception being 204 - No Content
, which will not have a body and so is ignored.
Headers
Currently we only handle one header, X-Plack-Debugger-Parent-Request-UID
, which is a custom header that we add into AJAX requests that are associated with a given request. If we see this header, we will not bother injecting content since we can assume that it is meant to be debugged via the parent page.
Content-Types
The following content-types are handled in the following order:
- No content-type specified
-
This currently throws an exception, perhaps this is not sensible, but then again not specifying your content-type is not very sensible either.
text/html
,application/xhtml
, etc.-
Given a content-type that looks like HTML, this will PSGI responses in the most sensible way possible.
If we detect a PSGI response which is an array of strings, we will process it (in reverse) looking for the closing
<body
> tag and inject the content accordingly.All other PSGI responses will be handled as if they are streaming responses, in which case we simple return a
CODE
reference that will process the stream and if a closing<body
> tag is found, inject accordingly. application/json
-
While we have a specific handler for this content-type, we do not do anything but just let it pass through. This is handled in this way specifically in case someone decides it is sensible to inject some kind of data into a JSON response.
It is left as an exercise to the reader to decide if this is sensible or not.
application/*
,text/*
,image/*
-
These three content types are fairly common, but there is no obvious way to inject content into them. So instead of guessing, we just let them pass through without modification. If there is any need to inject data into these response types it is simply a matter of overriding the
pass_through_content_type
method in a subclass and then doing your own content-type dispatching. - Unknown content-type
-
If none of these content-types match then we throw an exception and complain that we are not use what to actually do. Again, as with the lack of a content-type, this may not be sensible, if you disagree please give me a use case.
METHODS
new (%args)
-
This expects a
content
key in%args
which is either a string or a CODE reference that will accept a PSGI$env
as its only argument. call ($env)
-
This is just overriding the Plack::Middleware
call
method. get_content_to_insert ($env)
-
This will return the
content
specified innew
and will just do the appropriate thing depending on if thecontent
was a string or a CODE reference. - HTTP Request predicates
-
The remaining methods deal with processing the HTTP request to determine if we should inject the
content
or not.should_ignore_status ($env, $resp)
-
This filters based on the HTTP status code, see the "Status Codes" section above for more details.
has_parent_request_uid ($env, $resp)
-
If the request has the HTTP header that indicates it is a sub-request (typically an AJAX call from the browser) then it should be injected into, this method determines this. See the Headers section above for more details.
- Content-Type handlers
-
It only makes sense to inject the debugger
content
into certain types of responses, these methods determine how and when to do this. See the Content-Types section above for more details.
TODO
The following is a list of things this module might want to try and do, but which currently are not important to me. If one or more of these features would be useful to you, please feel free to send patches.
- Detect User-Agents where injection is not sensible.
-
Injecting Javascript code into pages being viewed by browsers like Lynx or tools like c<cURL> or
wget
would not make any sense.
ACKNOWLEDGMENT
This module was originally developed for Booking.com. With approval from Booking.com, this module was generalized and published on CPAN, for which the authors would like to express their gratitude.
AUTHOR
Stevan Little <stevan@cpan.org>
COPYRIGHT AND LICENSE
This software is copyright (c) 2014 by Stevan Little.
This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.