Item10824: HEAD requests should return early.
Priority: Enhancement
Current State: Closed
Released In: 2.0.0
Target Release: major
At the moment, when Foswiki receives a HEAD request, it will generate the entire page, as it does with a GET. So it will generate the HTML, execute plugins, etc.
However, all a HEAD request needs to do is check permissions and send the appropriate response. Generating the HTML is a waste of time, especially on pages with a big %SEARCH or using an expensive plugin.
To solve this, I did the following...
Index: View.pm
===================================================================
--- View.pm (revision 11801)
+++ View.pm (working copy)
@@ -186,6 +186,10 @@
$revIt = new Foswiki::ListIterator( [1] );
}
+ if($session->{request}->method eq 'HEAD'){
+ return $session->writeCompletePage( '', 'view', 'text/plain' );
+ }
+
if ($raw) {
$indexableView = 0;
$logEntry .= ' raw=' . $raw;
(patch against 01x01)
This seems to be working fine. Foswiki checks authentication correctly, and returns the appropriate response. I have been using it for months on our internal wiki without any issues.
I want to check this in, but would like to have someone with more knowledge of the FW internals to check it over first.
Background
This became a problem for us as we use the Google Search Appliance. To do its authentication, it sends up to 15
HEAD requests to the 15 top results with the users credentials. When 15 requests hit our wiki at the same time, it becomes very slow...
--
AndrewJones - 01 Jun 2011
This seems simple enough. There are probably some ordering questions though.
- If the page is in the PageCache, Should it just follow the normal path since it will be fast?
- Or should we skip all cache processing for HEAD requests.
--
GeorgeClark - 30 May 2014
Revised patch
commit 8d50207a0b5ffbdeb633a36f72a6668f933aa188
Merge: 48197a0 2f14679
Author: George Clark <geonwiki@fenachrone.com>
Date: Fri May 30 00:45:15 2014 -0400
On master: Item10824 HEAD processing
diff --combined core/lib/Foswiki/UI/View.pm
index 9dd0403,9dd0403..4111431
--- a/core/lib/Foswiki/UI/View.pm
+++ b/core/lib/Foswiki/UI/View.pm
@@@ -73,6 -73,6 +73,8 @@@ sub view
my $cache = $session->{cache};
my $response = $session->{response};
++ my $method = $session->{request}->method || '';
++
my $cachedPage;
$cachedPage = $cache->getPage( $web, $topic ) if $cache;
if ($cachedPage) {
@@@ -285,10 -285,10 +287,14 @@@
level => 'info',
action => 'view',
webTopic => $topicObject->web . '.' . $topicObject->topic,
-- extra => $logEntry,
++ extra => $logEntry . " ($method)"
}
);
++ if ( $method && $method eq 'HEAD' ) {
++ return $session->writeCompletePage( '', 'view', 'text/plain' );
++ }
++
# Note; must enter all contexts before the template is read, as
# TMPL:P is expanded on the fly in the template reader. :-(
my ( $revTitle, $revArg ) = ( '', '' );
My concern is the positioning of this. Should it be ahead of the cache work, or following it.
--
GeorgeClark - 04 Aug 2014
Testing with
$.ajax({type:"HEAD", url: "http://.../bin/view ..."});
The above patch isn't complete yet. First, there's a cache collision between GET and HEAD which means a HEAD request to a cached page will still receive the cached HTML of a previous GET to the same url. We don't have the same problem with POST as they are excluded in
Foswiki::PageCache::isCacheable()
. HEAD requests should be excluded from being cached. There's no need to cache an empty reply.
diff --git a/lib/Foswiki/PageCache.pm b/lib/Foswiki/PageCache.pm
index 1a471f1..c6000fc 100644
--- a/lib/Foswiki/PageCache.pm
+++ b/lib/Foswiki/PageCache.pm
@@ -386,9 +386,9 @@ sub isCacheable {
my $session = $Foswiki::Plugins::SESSION;
- # POSTs aren't cacheable
+ # POSTs and HEADs aren't cacheable
my $method = $session->{request}->method;
- $isCacheable = 0 if $method && $method eq 'POST';
+ $isCacheable = 0 if $method && $method =~ /^(?:POST|HEAD)$/;
if ($isCacheable) {
With this patch in place, where to check for HEAD in
View.pm
doesn't matter anymore. It must be located after the existence and access checks anyway.
--
MichaelDaum - 05 Aug 2014
I've implemented these patches along with some unit tests.
I don't think that the unit test is quite right, as even with the HEAD patch disabled, it still passes. However the patch is clearly working, as HEAD requests for a search page like System/Macros goes from 7+ seconds to around 500ms.
--
GeorgeClark - 23 Aug 2014