Nexcessnet_Turpentine - Version 0.6.5

Version Notes

Supports Magento v1.6 and later

Download this release

Release Info

Developer Chris Wells
Extension Nexcessnet_Turpentine
Version 0.6.5
Comparing to
See all releases


Code changes from version 0.6.4 to 0.6.5

Files changed (21) hide show
  1. app/code/community/Nexcessnet/Turpentine/Block/Core/Messages.php +6 -5
  2. app/code/community/Nexcessnet/Turpentine/Block/Product/Compared.php +34 -0
  3. app/code/community/Nexcessnet/Turpentine/Block/Product/Viewed.php +32 -0
  4. app/code/community/Nexcessnet/Turpentine/Helper/Esi.php +4 -1
  5. app/code/community/Nexcessnet/Turpentine/Model/Config/Select/LoadBalancing.php +34 -0
  6. app/code/community/Nexcessnet/Turpentine/Model/Config/Select/Version.php +6 -5
  7. app/code/community/Nexcessnet/Turpentine/Model/Observer/Esi.php +4 -0
  8. app/code/community/Nexcessnet/Turpentine/Model/Varnish/Admin.php +24 -7
  9. app/code/community/Nexcessnet/Turpentine/Model/Varnish/Admin/Socket.php +42 -24
  10. app/code/community/Nexcessnet/Turpentine/Model/Varnish/Configurator/Abstract.php +122 -8
  11. app/code/community/Nexcessnet/Turpentine/Model/Varnish/Configurator/Abstract.php~ +0 -769
  12. app/code/community/Nexcessnet/Turpentine/Model/Varnish/Configurator/Version4.php +60 -0
  13. app/code/community/Nexcessnet/Turpentine/etc/config.xml +18 -1
  14. app/code/community/Nexcessnet/Turpentine/etc/config.xml~ +529 -0
  15. app/code/community/Nexcessnet/Turpentine/etc/system.xml +62 -1
  16. app/code/community/Nexcessnet/Turpentine/misc/version-2.vcl +3 -0
  17. app/code/community/Nexcessnet/Turpentine/misc/version-3.vcl +3 -0
  18. app/code/community/Nexcessnet/Turpentine/misc/version-4.vcl +409 -0
  19. app/design/frontend/base/default/layout/turpentine_esi.xml +18 -0
  20. app/design/frontend/base/default/template/turpentine/ajax.phtml +29 -22
  21. package.xml +1 -1
app/code/community/Nexcessnet/Turpentine/Block/Core/Messages.php CHANGED
@@ -198,16 +198,17 @@ class Nexcessnet_Turpentine_Block_Core_Messages extends Mage_Core_Block_Messages
198
  } else {
199
  $this->_loadMessages();
200
  $this->_loadSavedMessages();
201
- $html = $this->_real_toHtml();
 
 
 
 
 
202
  }
203
  } else {
204
  $html = $this->_real_toHtml();
205
  }
206
  $this->_directCall = false;
207
-
208
- if (count($this->getMessages()) == 0) {
209
- return '';
210
- }
211
  return $html;
212
  }
213
 
198
  } else {
199
  $this->_loadMessages();
200
  $this->_loadSavedMessages();
201
+ if ( count($this->getMessages()) ) {
202
+ $html = $this->_real_toHtml();
203
+ } else {
204
+ // Prevent returning an empty <ul></ul>
205
+ $html = '';
206
+ }
207
  }
208
  } else {
209
  $html = $this->_real_toHtml();
210
  }
211
  $this->_directCall = false;
 
 
 
 
212
  return $html;
213
  }
214
 
app/code/community/Nexcessnet/Turpentine/Block/Product/Compared.php ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Nexcess.net Turpentine Extension for Magento
5
+ * Copyright (C) 2012 Nexcess.net L.L.C.
6
+ *
7
+ * This program is free software; you can redistribute it and/or modify
8
+ * it under the terms of the GNU General Public License as published by
9
+ * the Free Software Foundation; either version 2 of the License, or
10
+ * (at your option) any later version.
11
+ *
12
+ * This program is distributed in the hope that it will be useful,
13
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
+ * GNU General Public License for more details.
16
+ *
17
+ * You should have received a copy of the GNU General Public License along
18
+ * with this program; if not, write to the Free Software Foundation, Inc.,
19
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20
+ */
21
+
22
+ class Nexcessnet_Turpentine_Block_Product_Compared extends Mage_Reports_Block_Product_Compared {
23
+
24
+ protected function _toHtml()
25
+ {
26
+ if (!$this->getCount()) {
27
+ return $this->renderView();
28
+ }
29
+
30
+ $this->setRecentlyComparedProducts($this->getItemsCollection());
31
+
32
+ return parent::_toHtml();
33
+ }
34
+ }
app/code/community/Nexcessnet/Turpentine/Block/Product/Viewed.php ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Nexcess.net Turpentine Extension for Magento
5
+ * Copyright (C) 2012 Nexcess.net L.L.C.
6
+ *
7
+ * This program is free software; you can redistribute it and/or modify
8
+ * it under the terms of the GNU General Public License as published by
9
+ * the Free Software Foundation; either version 2 of the License, or
10
+ * (at your option) any later version.
11
+ *
12
+ * This program is distributed in the hope that it will be useful,
13
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
+ * GNU General Public License for more details.
16
+ *
17
+ * You should have received a copy of the GNU General Public License along
18
+ * with this program; if not, write to the Free Software Foundation, Inc.,
19
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20
+ */
21
+
22
+ class Nexcessnet_Turpentine_Block_Product_Viewed extends Mage_Reports_Block_Product_Viewed {
23
+
24
+ protected function _toHtml()
25
+ {
26
+ if (!$this->getCount()) {
27
+ return $this->renderView();
28
+ }
29
+ $this->setRecentlyViewedProducts($this->getItemsCollection());
30
+ return parent::_toHtml();
31
+ }
32
+ }
app/code/community/Nexcessnet/Turpentine/Helper/Esi.php CHANGED
@@ -357,7 +357,10 @@ class Nexcessnet_Turpentine_Helper_Esi extends Mage_Core_Helper_Abstract {
357
  $this->getEsiScopeParam() => 'global',
358
  $this->getEsiCacheTypeParam() => 'private',
359
  );
360
- return Mage::getUrl( 'turpentine/esi/getFormKey', $urlOptions );
 
 
 
361
  }
362
 
363
  /**
357
  $this->getEsiScopeParam() => 'global',
358
  $this->getEsiCacheTypeParam() => 'private',
359
  );
360
+ $esiUrl = Mage::getUrl( 'turpentine/esi/getFormKey', $urlOptions );
361
+ // setting [web/unsecure/base_url] can be https://... but ESI can never be HTTPS
362
+ $esiUrl = preg_replace( '|^https://|i', 'http://', $esiUrl );
363
+ return $esiUrl;
364
  }
365
 
366
  /**
app/code/community/Nexcessnet/Turpentine/Model/Config/Select/LoadBalancing.php ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Nexcess.net Turpentine Extension for Magento
5
+ * Copyright (C) 2012 Nexcess.net L.L.C.
6
+ *
7
+ * This program is free software; you can redistribute it and/or modify
8
+ * it under the terms of the GNU General Public License as published by
9
+ * the Free Software Foundation; either version 2 of the License, or
10
+ * (at your option) any later version.
11
+ *
12
+ * This program is distributed in the hope that it will be useful,
13
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
+ * GNU General Public License for more details.
16
+ *
17
+ * You should have received a copy of the GNU General Public License along
18
+ * with this program; if not, write to the Free Software Foundation, Inc.,
19
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20
+ */
21
+
22
+ class Nexcessnet_Turpentine_Model_Config_Select_LoadBalancing {
23
+ /**
24
+ * @return array
25
+ */
26
+ public function toOptionArray() {
27
+ $helper = Mage::helper('turpentine');
28
+ return array(
29
+ array('value'=>'no', 'label'=>$helper->__('No, use only one backend server')),
30
+ array('value'=>'yes', 'label'=>$helper->__('Yes, use load balancing')),
31
+ array('value'=>'yes_admin', 'label'=>$helper->__('Yes, with separate settings for Admin')),
32
+ );
33
+ }
34
+ }
app/code/community/Nexcessnet/Turpentine/Model/Config/Select/Version.php CHANGED
@@ -1,23 +1,23 @@
1
  <?php
2
 
3
- /**
4
  * Nexcess.net Turpentine Extension for Magento
5
  * Copyright (C) 2012 Nexcess.net L.L.C.
6
- *
7
  * This program is free software; you can redistribute it and/or modify
8
  * it under the terms of the GNU General Public License as published by
9
  * the Free Software Foundation; either version 2 of the License, or
10
  * (at your option) any later version.
11
- *
12
  * This program is distributed in the hope that it will be useful,
13
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
  * GNU General Public License for more details.
16
- *
17
  * You should have received a copy of the GNU General Public License along
18
  * with this program; if not, write to the Free Software Foundation, Inc.,
19
  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20
- */
21
 
22
  class Nexcessnet_Turpentine_Model_Config_Select_Version {
23
  public function toOptionArray() {
@@ -25,6 +25,7 @@ class Nexcessnet_Turpentine_Model_Config_Select_Version {
25
  return array(
26
  array( 'value' => '2.1', 'label' => $helper->__( '2.1.x' ) ),
27
  array( 'value' => '3.0', 'label' => $helper->__( '3.0.x' ) ),
 
28
  array( 'value' => 'auto', 'label' => $helper->__( 'Auto' ) ),
29
  );
30
  }
1
  <?php
2
 
3
+ /**
4
  * Nexcess.net Turpentine Extension for Magento
5
  * Copyright (C) 2012 Nexcess.net L.L.C.
6
+ *
7
  * This program is free software; you can redistribute it and/or modify
8
  * it under the terms of the GNU General Public License as published by
9
  * the Free Software Foundation; either version 2 of the License, or
10
  * (at your option) any later version.
11
+ *
12
  * This program is distributed in the hope that it will be useful,
13
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
  * GNU General Public License for more details.
16
+ *
17
  * You should have received a copy of the GNU General Public License along
18
  * with this program; if not, write to the Free Software Foundation, Inc.,
19
  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20
+ */
21
 
22
  class Nexcessnet_Turpentine_Model_Config_Select_Version {
23
  public function toOptionArray() {
25
  return array(
26
  array( 'value' => '2.1', 'label' => $helper->__( '2.1.x' ) ),
27
  array( 'value' => '3.0', 'label' => $helper->__( '3.0.x' ) ),
28
+ array( 'value' => '4.0', 'label' => $helper->__( '4.0.x' ) ),
29
  array( 'value' => 'auto', 'label' => $helper->__( 'Auto' ) ),
30
  );
31
  }
app/code/community/Nexcessnet/Turpentine/Model/Observer/Esi.php CHANGED
@@ -286,6 +286,10 @@ class Nexcessnet_Turpentine_Model_Observer_Esi extends Varien_Event_Observer {
286
  }
287
 
288
  $esiUrl = Mage::getUrl( 'turpentine/esi/getBlock', $urlOptions );
 
 
 
 
289
  $blockObject->setEsiUrl( $esiUrl );
290
  // avoid caching the ESI template output to prevent the double-esi-
291
  // include/"ESI processing not enabled" bug
286
  }
287
 
288
  $esiUrl = Mage::getUrl( 'turpentine/esi/getBlock', $urlOptions );
289
+ if( $esiOptions[$methodParam] == 'esi' ) {
290
+ // setting [web/unsecure/base_url] can be https://... but ESI can never be HTTPS
291
+ $esiUrl = preg_replace( '|^https://|i', 'http://', $esiUrl );
292
+ }
293
  $blockObject->setEsiUrl( $esiUrl );
294
  // avoid caching the ESI template output to prevent the double-esi-
295
  // include/"ESI processing not enabled" bug
app/code/community/Nexcessnet/Turpentine/Model/Varnish/Admin.php CHANGED
@@ -138,22 +138,39 @@ class Nexcessnet_Turpentine_Model_Varnish_Admin {
138
  $result = false;
139
 
140
  if( $helper->csrfFixupNeeded() ) {
141
- $value = $socket->param_show( 'esi_syntax' );
142
- if( preg_match( '~(\d)\s+\[bitmap\]~', $value['text'], $match ) ) {
143
- $value = hexdec( $match[1] );
144
- if( $value & self::MASK_ESI_SYNTAX ) { //bitwise intentional
145
- // setting is correct, all is fine
146
  $result = true;
147
  } else {
148
- $session->addWarning( 'Varnish <em>esi_syntax</em> param is ' .
149
  'not set correctly, please see <a target="_blank" href="' .
150
  self::URL_ESI_SYNTAX_FIX . '">these instructions</a> ' .
151
  'to fix this warning.' );
152
  }
153
  } else {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
154
  // error
155
  Mage::helper( 'turpentine/debug' )->logWarn(
156
- 'Failed to parse param.show output to check esi_syntax value' );
157
  $result = true;
158
  }
159
  } else {
138
  $result = false;
139
 
140
  if( $helper->csrfFixupNeeded() ) {
141
+ if ( $socket->getVersion()==='4.0' ) {
142
+ $paramName = 'feature';
143
+ $value = $socket->param_show( $paramName );
144
+ $value = explode("\n", $value['text']);
145
+ if ( isset($value[1]) && strpos($value[1], '+esi_ignore_other_elements')!==false ) {
146
  $result = true;
147
  } else {
148
+ $session->addWarning( 'Varnish <em>feature</em> param is ' .
149
  'not set correctly, please see <a target="_blank" href="' .
150
  self::URL_ESI_SYNTAX_FIX . '">these instructions</a> ' .
151
  'to fix this warning.' );
152
  }
153
  } else {
154
+ $paramName = 'esi_syntax';
155
+ $value = $socket->param_show( $paramName );
156
+ if( preg_match( '~(\d)\s+\[bitmap\]~', $value['text'], $match ) ) {
157
+ $value = hexdec( $match[1] );
158
+ if( $value & self::MASK_ESI_SYNTAX ) { //bitwise intentional
159
+ // setting is correct, all is fine
160
+ $result = true;
161
+ } else {
162
+ $session->addWarning( 'Varnish <em>esi_syntax</em> param is ' .
163
+ 'not set correctly, please see <a target="_blank" href="' .
164
+ self::URL_ESI_SYNTAX_FIX . '">these instructions</a> ' .
165
+ 'to fix this warning.' );
166
+ }
167
+ }
168
+ }
169
+
170
+ if ( $result===false ) {
171
  // error
172
  Mage::helper( 'turpentine/debug' )->logWarn(
173
+ sprintf('Failed to parse param.show output to check %s value', $paramName ) );
174
  $result = true;
175
  }
176
  } else {
app/code/community/Nexcessnet/Turpentine/Model/Varnish/Admin/Socket.php CHANGED
@@ -84,10 +84,16 @@ class Nexcessnet_Turpentine_Model_Varnish_Admin_Socket {
84
  // and used
85
  const CLI_CMD_LENGTH_LIMIT = 8192;
86
 
 
 
 
 
 
 
87
  /**
88
  * VCL config versions, should match config select values
89
  */
90
- static protected $_VERSIONS = array( '2.1', '3.0' );
91
 
92
  /**
93
  * Varnish socket connection
@@ -257,8 +263,8 @@ class Nexcessnet_Turpentine_Model_Varnish_Admin_Socket {
257
  * @return string
258
  */
259
  public function getVersion() {
260
- if( is_null( $this->_version ) ) {
261
- $this->_version = $this->_determineVersion();
262
  }
263
  return $this->_version;
264
  }
@@ -331,15 +337,35 @@ class Nexcessnet_Turpentine_Model_Varnish_Admin_Socket {
331
  $challenge = substr( $banner['text'], 0, 32 );
332
  $response = hash( 'sha256', sprintf( "%s\n%s%s\n", $challenge,
333
  $this->_authSecret, $challenge ) );
334
- $this->_command( 'auth', self::CODE_OK, $response );
335
- } else if( $banner['code'] !== self::CODE_OK ) {
 
 
336
  Mage::throwException( 'Varnish admin authentication failed: ' .
337
  $banner['text'] );
338
  }
339
 
 
 
340
  return $this->isConnected();
341
  }
342
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
343
  /**
344
  * Close the connection (if we're connected)
345
  *
@@ -367,9 +393,17 @@ class Nexcessnet_Turpentine_Model_Varnish_Admin_Socket {
367
  $dataLength = strlen( $data );
368
  if( $dataLength >= self::CLI_CMD_LENGTH_LIMIT ) {
369
  $cliBufferResponse = $this->param_show( 'cli_buffer' );
370
- if( preg_match( '~^cli_buffer\s+(\d+)\s+\[bytes\]~',
371
- $cliBufferResponse['text'], $match ) ) {
 
 
 
 
372
  $realLimit = (int)$match[1];
 
 
 
 
373
  } else {
374
  Mage::helper( 'turpentine/debug' )->logWarn(
375
  'Failed to determine Varnish cli_buffer limit, using default' );
@@ -470,6 +504,7 @@ class Nexcessnet_Turpentine_Model_Varnish_Admin_Socket {
470
  case '2.1':
471
  $command = str_replace( 'ban', 'purge', $command );
472
  break;
 
473
  case '3.0':
474
  $command = str_replace( 'purge', 'ban', $command );
475
  break;
@@ -479,21 +514,4 @@ class Nexcessnet_Turpentine_Model_Varnish_Admin_Socket {
479
  }
480
  return $command;
481
  }
482
-
483
- /**
484
- * Guess the Varnish version based on the availability of the 'banner' command
485
- *
486
- * @return string
487
- */
488
- protected function _determineVersion() {
489
- $resp = $this->_write( 'help' )->_read();
490
- if( strpos( $resp['text'], 'ban.url' ) !== false ) {
491
- return '3.0';
492
- } elseif( strpos( $resp['text'], 'purge.url' ) !== false &&
493
- strpos( $resp['text'], 'banner' ) ) {
494
- return '2.1';
495
- } else {
496
- Mage::throwException( 'Unable to determine instance version' );
497
- }
498
- }
499
  }
84
  // and used
85
  const CLI_CMD_LENGTH_LIMIT = 8192;
86
 
87
+ /**
88
+ * Regexp to detect the varnish version number
89
+ * @var string
90
+ */
91
+ const REGEXP_VARNISH_VERSION = '/^varnish\-(?P<vmajor>\d)\.(?P<vminor>\d)\.(?P<vsub>\d) revision (?P<vhash>[0-9a-f]+)$/';
92
+
93
  /**
94
  * VCL config versions, should match config select values
95
  */
96
+ static protected $_VERSIONS = array( '2.1', '3.0', '4.0' );
97
 
98
  /**
99
  * Varnish socket connection
263
  * @return string
264
  */
265
  public function getVersion() {
266
+ if ( !$this->isConnected() ) {
267
+ $this->_connect();
268
  }
269
  return $this->_version;
270
  }
337
  $challenge = substr( $banner['text'], 0, 32 );
338
  $response = hash( 'sha256', sprintf( "%s\n%s%s\n", $challenge,
339
  $this->_authSecret, $challenge ) );
340
+ $banner = $this->_command( 'auth', self::CODE_OK, $response );
341
+ }
342
+
343
+ if( $banner['code'] !== self::CODE_OK ) {
344
  Mage::throwException( 'Varnish admin authentication failed: ' .
345
  $banner['text'] );
346
  }
347
 
348
+ $this->_version = $this->_determineVersion($banner['text']);
349
+
350
  return $this->isConnected();
351
  }
352
 
353
+ protected function _determineVersion($bannerText) {
354
+ $bannerText = array_filter(explode("\n", $bannerText));
355
+ if ( count($bannerText)<6 ) {
356
+ // Varnish 2.0 does not spit out a banner on connect
357
+ Mage::throwException('Varnish versions before 2.1 are not supported');
358
+ }
359
+ if ( count($bannerText)<7 ) {
360
+ // Varnish before 3.0 does not spit out a version number
361
+ return '2.1';
362
+ } elseif ( preg_match(self::REGEXP_VARNISH_VERSION, $bannerText[4], $matches)===1 ) {
363
+ return $matches['vmajor'] . '.' . $matches['vminor'];
364
+ } else {
365
+ Mage::throwException('Unable to detect varnish version');
366
+ }
367
+ }
368
+
369
  /**
370
  * Close the connection (if we're connected)
371
  *
393
  $dataLength = strlen( $data );
394
  if( $dataLength >= self::CLI_CMD_LENGTH_LIMIT ) {
395
  $cliBufferResponse = $this->param_show( 'cli_buffer' );
396
+ $regexp = '~^cli_buffer\s+(\d+)\s+\[bytes\]~';
397
+ if ( $this->getVersion()==='4.0' ) {
398
+ // Varnish4 supports "16k" style notation
399
+ $regexp = '~^cli_buffer\s+Value is:\s+(\d+)([k|m|g]{1})?\s+\[bytes\]~';
400
+ }
401
+ if( preg_match( $regexp, $cliBufferResponse['text'], $match ) ) {
402
  $realLimit = (int)$match[1];
403
+ if ( isset($match[2]) ) {
404
+ $factors = array('k'=>1,'m'=>2,'g'=>3);
405
+ $realLimit *= pow(1024, $factors[$match[2]]);
406
+ }
407
  } else {
408
  Mage::helper( 'turpentine/debug' )->logWarn(
409
  'Failed to determine Varnish cli_buffer limit, using default' );
504
  case '2.1':
505
  $command = str_replace( 'ban', 'purge', $command );
506
  break;
507
+ case '4.0':
508
  case '3.0':
509
  $command = str_replace( 'purge', 'ban', $command );
510
  break;
514
  }
515
  return $command;
516
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
517
  }
app/code/community/Nexcessnet/Turpentine/Model/Varnish/Configurator/Abstract.php CHANGED
@@ -39,6 +39,11 @@ abstract class Nexcessnet_Turpentine_Model_Varnish_Configurator_Abstract {
39
  return null;
40
  }
41
  switch( $version ) {
 
 
 
 
 
42
  case '3.0':
43
  return Mage::getModel(
44
  'turpentine/varnish_configurator_version3',
@@ -287,10 +292,14 @@ abstract class Nexcessnet_Turpentine_Model_Varnish_Configurator_Abstract {
287
  'first_byte_timeout' => $timeout . 's',
288
  'between_bytes_timeout' => $timeout . 's',
289
  );
290
- return $this->_vcl_backend( 'default',
291
- Mage::getStoreConfig( 'turpentine_vcl/backend/backend_host' ),
292
- Mage::getStoreConfig( 'turpentine_vcl/backend/backend_port' ),
293
- $default_options );
 
 
 
 
294
  }
295
 
296
  /**
@@ -304,10 +313,14 @@ abstract class Nexcessnet_Turpentine_Model_Varnish_Configurator_Abstract {
304
  'first_byte_timeout' => $timeout . 's',
305
  'between_bytes_timeout' => $timeout . 's',
306
  );
307
- return $this->_vcl_backend( 'admin',
308
- Mage::getStoreConfig( 'turpentine_vcl/backend/backend_host' ),
309
- Mage::getStoreConfig( 'turpentine_vcl/backend/backend_port' ),
310
- $admin_options );
 
 
 
 
311
  }
312
 
313
  /**
@@ -587,6 +600,107 @@ EOS;
587
  return $str;
588
  }
589
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
590
  /**
591
  * Format a VCL ACL declaration
592
  *
39
  return null;
40
  }
41
  switch( $version ) {
42
+ case '4.0':
43
+ return Mage::getModel(
44
+ 'turpentine/varnish_configurator_version4',
45
+ array( 'socket' => $socket ) );
46
+
47
  case '3.0':
48
  return Mage::getModel(
49
  'turpentine/varnish_configurator_version3',
292
  'first_byte_timeout' => $timeout . 's',
293
  'between_bytes_timeout' => $timeout . 's',
294
  );
295
+ if ( Mage::getStoreConfigFlag( 'turpentine_vcl/backend/load_balancing' ) ) {
296
+ return $this->_vcl_director( 'default', $default_options );
297
+ } else {
298
+ return $this->_vcl_backend( 'default',
299
+ Mage::getStoreConfig( 'turpentine_vcl/backend/backend_host' ),
300
+ Mage::getStoreConfig( 'turpentine_vcl/backend/backend_port' ),
301
+ $default_options );
302
+ }
303
  }
304
 
305
  /**
313
  'first_byte_timeout' => $timeout . 's',
314
  'between_bytes_timeout' => $timeout . 's',
315
  );
316
+ if ( Mage::getStoreConfigFlag( 'turpentine_vcl/backend/load_balancing' ) ) {
317
+ return $this->_vcl_director( 'admin', $admin_options );
318
+ } else {
319
+ return $this->_vcl_backend( 'admin',
320
+ Mage::getStoreConfig( 'turpentine_vcl/backend/backend_host' ),
321
+ Mage::getStoreConfig( 'turpentine_vcl/backend/backend_port' ),
322
+ $admin_options );
323
+ }
324
  }
325
 
326
  /**
600
  return $str;
601
  }
602
 
603
+ /**
604
+ * Format a VCL director declaration, for load balancing
605
+ *
606
+ * @param string $name name of the director, also used to select config settings
607
+ * @param array $backendOptions options for each backend
608
+ * @return string
609
+ */
610
+ protected function _vcl_director( $name, $backendOptions ) {
611
+ $tpl = <<<EOS
612
+ director {{name}} round-robin {
613
+ {{backends}}
614
+ }
615
+ EOS;
616
+ if ( 'admin' == $name && 'yes_admin' == Mage::getStoreConfig( 'turpentine_vcl/backend/load_balancing' ) ) {
617
+ $backendNodes = Mage::helper( 'turpentine/data' )->cleanExplode( PHP_EOL,
618
+ Mage::getStoreConfig( 'turpentine_vcl/backend/backend_nodes_admin' ) );
619
+ $probeUrl = Mage::getStoreConfig( 'turpentine_vcl/backend/backend_probe_url_admin' );
620
+ } else {
621
+ $backendNodes = Mage::helper( 'turpentine/data' )->cleanExplode( PHP_EOL,
622
+ Mage::getStoreConfig( 'turpentine_vcl/backend/backend_nodes' ) );
623
+ $probeUrl = Mage::getStoreConfig( 'turpentine_vcl/backend/backend_probe_url' );
624
+ }
625
+ $backends = '';
626
+ foreach ( $backendNodes as $backendNode ) {
627
+ $parts = explode( ':', $backendNode, 2 );
628
+ $host = ( empty($parts[0]) ) ? '127.0.0.1' : $parts[0];
629
+ $port = ( empty($parts[1]) ) ? '80' : $parts[1];
630
+ $backends .= $this->_vcl_director_backend( $host, $port, $probeUrl, $backendOptions );
631
+ }
632
+ $vars = array(
633
+ 'name' => $name,
634
+ 'backends' => $backends
635
+ );
636
+ return $this->_formatTemplate( $tpl, $vars );
637
+ }
638
+
639
+ /**
640
+ * Format a VCL backend declaration to put inside director
641
+ *
642
+ * @param string $host backend host
643
+ * @param string $port backend port
644
+ * @param string $probeUrl URL to check if backend is up
645
+ * @param array $options extra options for backend
646
+ * @return string
647
+ */
648
+ protected function _vcl_director_backend( $host, $port, $probeUrl='', $options=array() ) {
649
+ $tpl = <<<EOS
650
+ {
651
+ .backend = {
652
+ .host = "{{host}}";
653
+ .port = "{{port}}";
654
+ {{probe}}
655
+
656
+ EOS;
657
+ $vars = array(
658
+ 'host' => $host,
659
+ 'port' => $port,
660
+ 'probe' => ''
661
+ );
662
+ if ( !empty( $probeUrl ) ) {
663
+ $vars['probe'] = $this->_vcl_get_probe( $probeUrl );
664
+ }
665
+ $str = $this->_formatTemplate( $tpl, $vars );
666
+ foreach( $options as $key => $value ) {
667
+ $str .= sprintf( ' .%s = %s;', $key, $value ) . PHP_EOL;
668
+ }
669
+ $str .= <<<EOS
670
+ }
671
+ }
672
+ EOS;
673
+ return $str;
674
+ }
675
+
676
+ /**
677
+ * Format a VCL probe declaration to put in backend which is in director
678
+ *
679
+ * @param string $probeUrl URL to check if backend is up
680
+ * @return string
681
+ */
682
+ protected function _vcl_get_probe( $probeUrl ) {
683
+ $urlParts = parse_url( $probeUrl );
684
+ if ( empty( $urlParts ) ) {
685
+ // Malformed URL
686
+ return '';
687
+ } else {
688
+ $tpl = <<<EOS
689
+ .probe = {
690
+ .request =
691
+ "GET {{probe_path}} HTTP/1.1"
692
+ "Host: {{probe_host}}"
693
+ "Connection: close";
694
+ }
695
+ EOS;
696
+ $vars = array(
697
+ 'probe_host' => $urlParts['host'],
698
+ 'probe_path' => $urlParts['path']
699
+ );
700
+ return $this->_formatTemplate( $tpl, $vars );
701
+ }
702
+ }
703
+
704
  /**
705
  * Format a VCL ACL declaration
706
  *
app/code/community/Nexcessnet/Turpentine/Model/Varnish/Configurator/Abstract.php~ DELETED
@@ -1,769 +0,0 @@
1
- <?php
2
-
3
- /**
4
- * Nexcess.net Turpentine Extension for Magento
5
- * Copyright (C) 2012 Nexcess.net L.L.C.
6
- *
7
- * This program is free software; you can redistribute it and/or modify
8
- * it under the terms of the GNU General Public License as published by
9
- * the Free Software Foundation; either version 2 of the License, or
10
- * (at your option) any later version.
11
- *
12
- * This program is distributed in the hope that it will be useful,
13
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
- * GNU General Public License for more details.
16
- *
17
- * You should have received a copy of the GNU General Public License along
18
- * with this program; if not, write to the Free Software Foundation, Inc.,
19
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20
- */
21
-
22
- abstract class Nexcessnet_Turpentine_Model_Varnish_Configurator_Abstract {
23
-
24
- const VCL_CUSTOM_C_CODE_FILE = 'uuid.c';
25
-
26
- /**
27
- * Get the correct version of a configurator from a socket
28
- *
29
- * @param Nexcessnet_Turpentine_Model_Varnish_Admin_Socket $socket
30
- * @return Nexcessnet_Turpentine_Model_Varnish_Configurator_Abstract
31
- */
32
- static public function getFromSocket( $socket ) {
33
- try {
34
- $version = $socket->getVersion();
35
- } catch( Mage_Core_Exception $e ) {
36
- Mage::getSingleton( 'core/session' )
37
- ->addError( 'Error determining Varnish version: ' .
38
- $e->getMessage() );
39
- return null;
40
- }
41
- switch( $version ) {
42
- case '3.0':
43
- return Mage::getModel(
44
- 'turpentine/varnish_configurator_version3',
45
- array( 'socket' => $socket ) );
46
- case '2.1':
47
- return Mage::getModel(
48
- 'turpentine/varnish_configurator_version2',
49
- array( 'socket' => $socket ) );
50
- default:
51
- Mage::throwException( 'Unsupported Varnish version' );
52
- }
53
- }
54
-
55
- /**
56
- * The socket this configurator is based on
57
- *
58
- * @var Nexcessnet_Turpentine_Model_Varnish_Admin_Socket
59
- */
60
- protected $_socket = null;
61
- /**
62
- * options array
63
- *
64
- * @var array
65
- */
66
- protected $_options = array(
67
- 'vcl_template' => null,
68
- );
69
-
70
- public function __construct( $options=array() ) {
71
- $this->_options = array_merge( $this->_options, $options );
72
- }
73
-
74
- abstract public function generate($doClean=true);
75
- // abstract protected function _getTemplateVars();
76
-
77
- /**
78
- * Save the generated config to the file specified in Magento config
79
- *
80
- * @param string $generatedConfig config generated by @generate
81
- * @return null
82
- */
83
- public function save( $generatedConfig ) {
84
- $filename = $this->_getVclFilename();
85
- $dir = dirname( $filename );
86
- if( !is_dir( $dir ) ) {
87
- // this umask is probably redundant, but just in case...
88
- if( !mkdir( $dir, 0777 & ~umask(), true ) ) {
89
- $err = error_get_last();
90
- return array( false, $err );
91
- }
92
- }
93
- if( strlen( $generatedConfig ) !==
94
- file_put_contents( $filename, $generatedConfig ) ) {
95
- $err = error_get_last();
96
- return array( false, $err );
97
- }
98
- return array( true, null );
99
- }
100
-
101
- /**
102
- * Get the full path for a given template filename
103
- *
104
- * @param string $baseFilename
105
- * @return string
106
- */
107
- protected function _getVclTemplateFilename( $baseFilename ) {
108
- $extensionDir = Mage::getModuleDir( '', 'Nexcessnet_Turpentine' );
109
- return sprintf( '%s/misc/%s', $extensionDir, $baseFilename );
110
- }
111
-
112
- /**
113
- * Get the name of the file to save the VCL to
114
- *
115
- * @return string
116
- */
117
- protected function _getVclFilename() {
118
- return $this->_formatTemplate(
119
- Mage::getStoreConfig( 'turpentine_varnish/servers/config_file' ),
120
- array( 'root_dir' => Mage::getBaseDir() ) );
121
- }
122
-
123
- /**
124
- * Get the name of the custom include VCL file
125
- *
126
- * @return string
127
- */
128
- protected function _getCustomIncludeFilename() {
129
- return $this->_formatTemplate(
130
- Mage::getStoreConfig( 'turpentine_varnish/servers/custom_include_file' ),
131
- array( 'root_dir' => Mage::getBaseDir() ) );
132
- }
133
-
134
- /**
135
- * Format a template string, replacing {{keys}} with the appropriate values
136
- * and remove unspecified keys
137
- *
138
- * @param string $template template string to operate on
139
- * @param array $vars array of key => value replacements
140
- * @return string
141
- */
142
- protected function _formatTemplate( $template, array $vars ) {
143
- $needles = array_map( create_function( '$k', 'return "{{".$k."}}";' ),
144
- array_keys( $vars ) );
145
- $replacements = array_values( $vars );
146
- // do replacements, then delete unused template vars
147
- return preg_replace( '~{{[^}]+}}~', '',
148
- str_replace( $needles, $replacements, $template ) );
149
- }
150
-
151
- /**
152
- * Format a VCL subroutine call
153
- *
154
- * @param string $subroutine subroutine name
155
- * @return string
156
- */
157
- protected function _vcl_call( $subroutine ) {
158
- return sprintf( 'call %s;', $subroutine );
159
- }
160
-
161
- /**
162
- * Get the Magento admin frontname
163
- *
164
- * This is just the plain string, not in URL format. ex:
165
- * http://example.com/magento/admin -> admin
166
- *
167
- * @return string
168
- */
169
- protected function _getAdminFrontname() {
170
- if( Mage::getStoreConfig( 'admin/url/use_custom_path' ) ) {
171
- return Mage::getStoreConfig( 'admin/url/custom_path' );
172
- } else {
173
- return (string)Mage::getConfig()->getNode(
174
- 'admin/routers/adminhtml/args/frontName' );
175
- }
176
- }
177
-
178
- /**
179
- * Get the hostname for host normalization from Magento's base URL
180
- *
181
- * @return string
182
- */
183
- protected function _getNormalizeHostTarget() {
184
- $configHost = trim( Mage::getStoreConfig(
185
- 'turpentine_vcl/normalization/host_target' ) );
186
- if( $configHost ) {
187
- return $configHost;
188
- } else {
189
- $baseUrl = parse_url( Mage::getBaseUrl() );
190
- if( isset( $baseUrl['port'] ) ) {
191
- return sprintf( '%s:%d', $baseUrl['host'], $baseUrl['port'] );
192
- } else {
193
- return $baseUrl['host'];
194
- }
195
- }
196
- }
197
-
198
- /**
199
- * Get hosts as regex
200
- *
201
- * ex: base_url: example.com
202
- * path_regex: (example.com|example.net)
203
- *
204
- * @return string
205
- */
206
- public function getAllowedHostsRegex() {
207
- $hosts = array();
208
- foreach( Mage::app()->getStores() as $store ) {
209
- $hosts[] = parse_url( $store->getBaseUrl( Mage_Core_Model_Store::URL_TYPE_WEB , false ), PHP_URL_HOST );
210
- }
211
-
212
- $hosts = array_values(array_unique( $hosts ));
213
-
214
- $pattern = '('.implode('|', array_map("preg_quote", $hosts)).')';
215
- return $pattern;
216
- }
217
-
218
- /**
219
- * Get the base url path regex
220
- *
221
- * ex: base_url: http://example.com/magento/
222
- * path_regex: /magento/(?:(?:index|litespeed)\.php/)?
223
- *
224
- * @return string
225
- */
226
- public function getBaseUrlPathRegex() {
227
- $pattern = '^(%s)(?:(?:index|litespeed)\\.php/)?';
228
- return sprintf( $pattern, implode( '|',
229
- array_map( create_function( '$x', 'return preg_quote($x,"|");' ),
230
- $this->_getBaseUrlPaths() ) ) );
231
- }
232
-
233
- /**
234
- * Get the path part of each store's base URL and static file URLs
235
- *
236
- * @return array
237
- */
238
- protected function _getBaseUrlPaths() {
239
- $paths = array();
240
- $linkTypes = array( Mage_Core_Model_Store::URL_TYPE_LINK,
241
- Mage_Core_Model_Store::URL_TYPE_JS,
242
- Mage_Core_Model_Store::URL_TYPE_SKIN,
243
- Mage_Core_Model_Store::URL_TYPE_MEDIA );
244
- foreach( Mage::app()->getStores() as $store ) {
245
- foreach( $linkTypes as $linkType ) {
246
- $paths[] = parse_url( $store->getBaseUrl( $linkType , false ),
247
- PHP_URL_PATH );
248
- $paths[] = parse_url( $store->getBaseUrl( $linkType , true ),
249
- PHP_URL_PATH );
250
- }
251
- }
252
- $paths = array_unique( $paths );
253
- usort( $paths, create_function( '$a, $b',
254
- 'return strlen( $b ) - strlen( $a );' ) );
255
- return array_values( $paths );
256
- }
257
-
258
- /**
259
- * Format the URL exclusions for insertion in a regex. Admin frontname and
260
- * API are automatically added.
261
- *
262
- * @return string
263
- */
264
- protected function _getUrlExcludes() {
265
- $urls = Mage::getStoreConfig( 'turpentine_vcl/urls/url_blacklist' );
266
- return implode( '|', array_merge( array( $this->_getAdminFrontname(), 'api' ),
267
- Mage::helper( 'turpentine/data' )->cleanExplode( PHP_EOL, $urls ) ) );
268
- }
269
-
270
- /**
271
- * Get the default cache TTL from Magento config
272
- *
273
- * @return string
274
- */
275
- protected function _getDefaultTtl() {
276
- return Mage::helper( 'turpentine/varnish' )->getDefaultTtl();
277
- }
278
-
279
- /**
280
- * Get the default backend configuration string
281
- *
282
- * @return string
283
- */
284
- protected function _getDefaultBackend() {
285
- $timeout = Mage::getStoreConfig( 'turpentine_vcl/backend/frontend_timeout' );
286
- $default_options = array(
287
- 'first_byte_timeout' => $timeout . 's',
288
- 'between_bytes_timeout' => $timeout . 's',
289
- );
290
- return $this->_vcl_backend( 'default',
291
- Mage::getStoreConfig( 'turpentine_vcl/backend/backend_host' ),
292
- Mage::getStoreConfig( 'turpentine_vcl/backend/backend_port' ),
293
- $default_options );
294
- }
295
-
296
- /**
297
- * Get the admin backend configuration string
298
- *
299
- * @return string
300
- */
301
- protected function _getAdminBackend() {
302
- $timeout = Mage::getStoreConfig( 'turpentine_vcl/backend/admin_timeout' );
303
- $admin_options = array(
304
- 'first_byte_timeout' => $timeout . 's',
305
- 'between_bytes_timeout' => $timeout . 's',
306
- );
307
- return $this->_vcl_backend( 'admin',
308
- Mage::getStoreConfig( 'turpentine_vcl/backend/backend_host' ),
309
- Mage::getStoreConfig( 'turpentine_vcl/backend/backend_port' ),
310
- $admin_options );
311
- }
312
-
313
- /**
314
- * Get the grace period for vcl_fetch
315
- *
316
- * This is curently hardcoded to 15 seconds, will be configurable at some
317
- * point
318
- *
319
- * @return string
320
- */
321
- protected function _getGracePeriod() {
322
- return Mage::getStoreConfig( 'turpentine_vcl/ttls/grace_period' );
323
- }
324
-
325
- /**
326
- * Get whether debug headers should be enabled or not
327
- *
328
- * @return string
329
- */
330
- protected function _getEnableDebugHeaders() {
331
- return Mage::getStoreConfig( 'turpentine_varnish/general/varnish_debug' )
332
- ? 'true' : 'false';
333
- }
334
-
335
- /**
336
- * Format the GET variable excludes for insertion in a regex
337
- *
338
- * @return string
339
- */
340
- protected function _getGetParamExcludes() {
341
- return implode( '|', Mage::helper( 'turpentine/data' )->cleanExplode( ',',
342
- Mage::getStoreConfig( 'turpentine_vcl/params/get_params' ) ) );
343
- }
344
-
345
- protected function _getIgnoreGetParameters()
346
- {
347
- /** @var Nexcessnet_Turpentine_Helper_Data $helper */
348
- $helper = Mage::helper('turpentine');
349
- $ignoredParameters = $helper->cleanExplode(',', Mage::getStoreConfig( 'turpentine_vcl/params/ignore_get_params'));
350
- return implode( '|', $ignoredParameters);
351
- }
352
-
353
- /**
354
- * Get the Generate Session
355
- *
356
- * @return string
357
- */
358
- protected function _getGenerateSessionStart() {
359
- return Mage::getStoreConfig( 'turpentine_varnish/general/vcl_fix' )
360
- ? '/* -- REMOVED' : '';
361
- }
362
-
363
- /**
364
- * Get the Generate Session
365
- *
366
- * @return string
367
- */
368
- protected function _getGenerateSessionEnd() {
369
- return Mage::getStoreConfig( 'turpentine_varnish/general/vcl_fix' )
370
- ? '-- */' : '';
371
- }
372
-
373
-
374
- /**
375
- * Get the Generate Session
376
- *
377
- * @return string
378
- */
379
- protected function _getGenerateSession() {
380
- return Mage::getStoreConfig( 'turpentine_varnish/general/vcl_fix' )
381
- ? '# call generate_session' : 'call generate_session;';
382
- }
383
-
384
-
385
- /**
386
- * Get the Generate Session Expires
387
- *
388
- * @return string
389
- */
390
- protected function _getGenerateSessionExpires() {
391
- return Mage::getStoreConfig( 'turpentine_varnish/general/vcl_fix' )
392
- ? '# call generate_session_expires' : 'call generate_session_expires;';
393
- }
394
-
395
- /**
396
- * Get the Force Static Caching option
397
- *
398
- * @return string
399
- */
400
- protected function _getForceCacheStatic() {
401
- return Mage::getStoreConfig( 'turpentine_vcl/static/force_static' )
402
- ? 'true' : 'false';
403
- }
404
-
405
- /**
406
- * Format the list of static cache extensions
407
- *
408
- * @return string
409
- */
410
- protected function _getStaticExtensions() {
411
- return implode( '|', Mage::helper( 'turpentine/data' )->cleanExplode( ',',
412
- Mage::getStoreConfig( 'turpentine_vcl/static/exts' ) ) );
413
- }
414
-
415
- /**
416
- * Get the static caching TTL
417
- *
418
- * @return string
419
- */
420
- protected function _getStaticTtl() {
421
- return Mage::getStoreConfig( 'turpentine_vcl/ttls/static_ttl' );
422
- }
423
-
424
- /**
425
- * Format the by-url TTL value list
426
- *
427
- * @return string
428
- */
429
- protected function _getUrlTtls() {
430
- $str = array();
431
- $configTtls = Mage::helper( 'turpentine/data' )->cleanExplode( PHP_EOL,
432
- Mage::getStoreConfig( 'turpentine_vcl/ttls/url_ttls' ) );
433
- $ttls = array();
434
- foreach( $configTtls as $line ) {
435
- $ttls[] = explode( ',', trim( $line ) );
436
- }
437
- foreach( $ttls as $ttl ) {
438
- $str[] = sprintf( 'if (bereq.url ~ "%s%s") { set beresp.ttl = %ds; }',
439
- $this->getBaseUrlPathRegex(), $ttl[0], $ttl[1] );
440
- }
441
- $str = implode( ' else ', $str );
442
- if( $str ) {
443
- $str .= sprintf( ' else { set beresp.ttl = %ds; }',
444
- $this->_getDefaultTtl() );
445
- } else {
446
- $str = sprintf( 'set beresp.ttl = %ds;', $this->_getDefaultTtl() );
447
- }
448
- return $str;
449
- }
450
-
451
- /**
452
- * Get the Enable Caching value
453
- *
454
- * @return string
455
- */
456
- protected function _getEnableCaching() {
457
- return Mage::helper( 'turpentine/varnish' )->getVarnishEnabled() ?
458
- 'true' : 'false';
459
- }
460
-
461
- /**
462
- * Get the list of allowed debug IPs
463
- *
464
- * @return array
465
- */
466
- protected function _getDebugIps() {
467
- return Mage::helper( 'turpentine/data' )->cleanExplode( ',',
468
- Mage::getStoreConfig( 'dev/restrict/allow_ips' ) );
469
- }
470
-
471
- /**
472
- * Get the list of crawler IPs
473
- *
474
- * @return array
475
- */
476
- protected function _getCrawlerIps() {
477
- return Mage::helper( 'turpentine/data' )->cleanExplode( ',',
478
- Mage::getStoreConfig( 'turpentine_vcl/backend/crawlers' ) );
479
- }
480
-
481
- /**
482
- * Get the regex formatted list of crawler user agents
483
- *
484
- * @return string
485
- */
486
- protected function _getCrawlerUserAgents() {
487
- return implode( '|', Mage::helper( 'turpentine/data' )
488
- ->cleanExplode( ',',
489
- Mage::getStoreConfig(
490
- 'turpentine_vcl/backend/crawler_user_agents' ) ) );
491
- }
492
-
493
- /**
494
- * Get the time to increase a cached objects TTL on cache hit (in seconds).
495
- *
496
- * This should be set very low since it gets added to every hit.
497
- *
498
- * @return string
499
- */
500
- protected function _getLruFactor() {
501
- return Mage::getStoreConfig( 'turpentine_vcl/ttls/lru_factor' );
502
- }
503
-
504
- /**
505
- * Get the advanced session validation restrictions
506
- *
507
- * Note that if User-Agent Normalization is on then the normalized user-agent
508
- * is used for user-agent validation instead of the full user-agent
509
- *
510
- * @return string
511
- */
512
- protected function _getAdvancedSessionValidationTargets() {
513
- $validation = array();
514
- if( Mage::getStoreConfig( 'web/session/use_remote_addr' ) ) {
515
- $validation[] = 'client.ip';
516
- }
517
- if( Mage::getStoreConfig( 'web/session/use_http_via' ) ) {
518
- $validation[] = 'req.http.Via';
519
- }
520
- if( Mage::getStoreConfig( 'web/session/use_http_x_forwarded_for' ) ) {
521
- $validation[] = 'req.http.X-Forwarded-For';
522
- }
523
- if( Mage::getStoreConfig(
524
- 'web/session/use_http_user_agent' ) &&
525
- !Mage::getStoreConfig(
526
- 'turpentine_vcl/normalization/user_agent' ) ) {
527
- $validation[] = 'req.http.User-Agent';
528
- }
529
- return $validation;
530
- }
531
-
532
- /**
533
- * Remove empty and commented out lines from the generated VCL
534
- *
535
- * @param string $dirtyVcl generated vcl
536
- * @return string
537
- */
538
- protected function _cleanVcl( $dirtyVcl ) {
539
- return implode( PHP_EOL,
540
- array_filter(
541
- Mage::helper( 'turpentine/data' )
542
- ->cleanExplode( PHP_EOL, $dirtyVcl ),
543
- array( $this, '_cleanVclHelper' )
544
- )
545
- );
546
- }
547
-
548
- /**
549
- * Helper to filter out blank/commented lines for VCL cleaning
550
- *
551
- * @param string $line
552
- * @return bool
553
- */
554
- protected function _cleanVclHelper( $line ) {
555
- return $line &&
556
- ( ( substr( $line, 0, 1 ) != '#' &&
557
- substr( $line, 0, 2 ) != '//' ) ||
558
- substr( $line, 0, 8 ) == '#include' );
559
- }
560
-
561
- /**
562
- * Format a VCL backend declaration
563
- *
564
- * @param string $name name of the backend
565
- * @param string $host backend host
566
- * @param string $port backend port
567
- * @param array $options options
568
- * @return string
569
- */
570
- protected function _vcl_backend( $name, $host, $port, $options=array() ) {
571
- $tpl = <<<EOS
572
- backend {{name}} {
573
- .host = "{{host}}";
574
- .port = "{{port}}";
575
-
576
- EOS;
577
- $vars = array(
578
- 'host' => $host,
579
- 'port' => $port,
580
- 'name' => $name,
581
- );
582
- $str = $this->_formatTemplate( $tpl, $vars );
583
- foreach( $options as $key => $value ) {
584
- $str .= sprintf( ' .%s = %s;', $key, $value ) . PHP_EOL;
585
- }
586
- $str .= '}' . PHP_EOL;
587
- return $str;
588
- }
589
-
590
- /**
591
- * Format a VCL ACL declaration
592
- *
593
- * @param string $name ACL name
594
- * @param array $hosts list of hosts to add to the ACL
595
- * @return string
596
- */
597
- protected function _vcl_acl( $name, array $hosts ) {
598
- $tpl = <<<EOS
599
- acl {{name}} {
600
- {{hosts}}
601
- }
602
- EOS;
603
- $fmtHost = create_function( '$h', 'return sprintf(\'"%s";\',$h);' );
604
- $vars = array(
605
- 'name' => $name,
606
- 'hosts' => implode( "\n ", array_map( $fmtHost, $hosts ) ),
607
- );
608
- return $this->_formatTemplate( $tpl, $vars );
609
- }
610
-
611
- /**
612
- * Get the User-Agent normalization sub routine
613
- *
614
- * @return string
615
- */
616
- protected function _vcl_sub_normalize_user_agent() {
617
- /**
618
- * Mobile regex from
619
- * @link http://magebase.com/magento-tutorials/magento-design-exceptions-explained/
620
- */
621
- $tpl = <<<EOS
622
- if (req.http.User-Agent ~ "iP(?:hone|ad|od)|BlackBerry|Palm|Googlebot-Mobile|Mobile|mobile|mobi|Windows Mobile|Safari Mobile|Android|Opera (?:Mini|Mobi)") {
623
- set req.http.X-Normalized-User-Agent = "mobile";
624
- } else if (req.http.User-Agent ~ "MSIE") {
625
- set req.http.X-Normalized-User-Agent = "msie";
626
- } else if (req.http.User-Agent ~ "Firefox") {
627
- set req.http.X-Normalized-User-Agent = "firefox";
628
- } else if (req.http.User-Agent ~ "Chrome") {
629
- set req.http.X-Normalized-User-Agent = "chrome";
630
- } else if (req.http.User-Agent ~ "Safari") {
631
- set req.http.X-Normalized-User-Agent = "safari";
632
- } else if (req.http.User-Agent ~ "Opera") {
633
- set req.http.X-Normalized-User-Agent = "opera";
634
- } else {
635
- set req.http.X-Normalized-User-Agent = "other";
636
- }
637
-
638
- EOS;
639
- return $tpl;
640
- }
641
-
642
- /**
643
- * Get the Accept-Encoding normalization sub routine
644
- *
645
- * @return string
646
- */
647
- protected function _vcl_sub_normalize_encoding() {
648
- $tpl = <<<EOS
649
- if (req.http.Accept-Encoding) {
650
- if (req.http.Accept-Encoding ~ "gzip") {
651
- set req.http.Accept-Encoding = "gzip";
652
- } else if (req.http.Accept-Encoding ~ "deflate") {
653
- set req.http.Accept-Encoding = "deflate";
654
- } else {
655
- # unknown algorithm
656
- unset req.http.Accept-Encoding;
657
- }
658
- }
659
-
660
- EOS;
661
- return $tpl;
662
- }
663
-
664
- /**
665
- * Get the Host normalization sub routine
666
- *
667
- * @return string
668
- */
669
- protected function _vcl_sub_normalize_host() {
670
- $tpl = <<<EOS
671
- set req.http.Host = "{{normalize_host_target}}";
672
-
673
- EOS;
674
- return $this->_formatTemplate( $tpl, array(
675
- 'normalize_host_target' => $this->_getNormalizeHostTarget() ) );
676
- }
677
-
678
- /**
679
- * Get the hostname for cookie normalization
680
- *
681
- * @return string
682
- */
683
- protected function _getNormalizeCookieTarget() {
684
- return trim( Mage::getStoreConfig(
685
- 'turpentine_vcl/normalization/cookie_target' ) );
686
- }
687
-
688
- /**
689
- * Get the regex for cookie normalization
690
- *
691
- * @return string
692
- */
693
- protected function _getNormalizeCookieRegex() {
694
- return trim( Mage::getStoreConfig(
695
- 'turpentine_vcl/normalization/cookie_regex' ) );
696
- }
697
-
698
- /**
699
- * Build the list of template variables to apply to the VCL template
700
- *
701
- * @return array
702
- */
703
- protected function _getTemplateVars() {
704
- $vars = array(
705
- 'default_backend' => $this->_getDefaultBackend(),
706
- 'admin_backend' => $this->_getAdminBackend(),
707
- 'admin_frontname' => $this->_getAdminFrontname(),
708
- 'normalize_host_target' => $this->_getNormalizeHostTarget(),
709
- 'url_base_regex' => $this->getBaseUrlPathRegex(),
710
- 'allowed_hosts_regex' => $this->getAllowedHostsRegex(),
711
- 'url_excludes' => $this->_getUrlExcludes(),
712
- 'get_param_excludes' => $this->_getGetParamExcludes(),
713
- 'get_param_ignored' => $this->_getIgnoreGetParameters(),
714
- 'default_ttl' => $this->_getDefaultTtl(),
715
- 'enable_get_excludes' => ($this->_getGetParamExcludes() ? 'true' : 'false'),
716
- 'enable_get_ignored' => ($this->_getIgnoreGetParameters()) ? 'true' : 'false',
717
- 'debug_headers' => $this->_getEnableDebugHeaders(),
718
- 'grace_period' => $this->_getGracePeriod(),
719
- 'force_cache_static' => $this->_getForceCacheStatic(),
720
- 'generate_session_expires' => $this->_getGenerateSessionExpires(),
721
- 'generate_session' => $this->_getGenerateSession(),
722
- 'generate_session_start' => $this->_getGenerateSessionStart(),
723
- 'generate_session_end' => $this->_getGenerateSessionEnd(),
724
- 'static_extensions' => $this->_getStaticExtensions(),
725
- 'static_ttl' => $this->_getStaticTtl(),
726
- 'url_ttls' => $this->_getUrlTtls(),
727
- 'enable_caching' => $this->_getEnableCaching(),
728
- 'crawler_acl' => $this->_vcl_acl( 'crawler_acl',
729
- $this->_getCrawlerIps() ),
730
- 'esi_cache_type_param' =>
731
- Mage::helper( 'turpentine/esi' )->getEsiCacheTypeParam(),
732
- 'esi_method_param' =>
733
- Mage::helper( 'turpentine/esi' )->getEsiMethodParam(),
734
- 'esi_ttl_param' => Mage::helper( 'turpentine/esi' )->getEsiTtlParam(),
735
- 'secret_handshake' => Mage::helper( 'turpentine/varnish' )
736
- ->getSecretHandshake(),
737
- 'crawler_user_agent_regex' => $this->_getCrawlerUserAgents(),
738
- // 'lru_factor' => $this->_getLruFactor(),
739
- 'debug_acl' => $this->_vcl_acl( 'debug_acl',
740
- $this->_getDebugIps() ),
741
- 'custom_c_code' => file_get_contents(
742
- $this->_getVclTemplateFilename( self::VCL_CUSTOM_C_CODE_FILE ) ),
743
- 'esi_private_ttl' => Mage::helper( 'turpentine/esi' )
744
- ->getDefaultEsiTtl(),
745
- );
746
- if( Mage::getStoreConfig( 'turpentine_vcl/normalization/encoding' ) ) {
747
- $vars['normalize_encoding'] = $this->_vcl_sub_normalize_encoding();
748
- }
749
- if( Mage::getStoreConfig( 'turpentine_vcl/normalization/user_agent' ) ) {
750
- $vars['normalize_user_agent'] = $this->_vcl_sub_normalize_user_agent();
751
- }
752
- if( Mage::getStoreConfig( 'turpentine_vcl/normalization/host' ) ) {
753
- $vars['normalize_host'] = $this->_vcl_sub_normalize_host();
754
- }
755
- if( Mage::getStoreConfig( 'turpentine_vcl/normalization/cookie_regex' ) ) {
756
- $vars['normalize_cookie_regex'] = $this->_getNormalizeCookieRegex();
757
- }
758
- if( Mage::getStoreConfig( 'turpentine_vcl/normalization/cookie_target' ) ) {
759
- $vars['normalize_cookie_target'] = $this->_getNormalizeCookieTarget();
760
- }
761
-
762
- $customIncludeFile = $this->_getCustomIncludeFilename();
763
- if( is_readable( $customIncludeFile ) ) {
764
- $vars['custom_vcl_include'] = file_get_contents( $customIncludeFile );
765
- }
766
-
767
- return $vars;
768
- }
769
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/community/Nexcessnet/Turpentine/Model/Varnish/Configurator/Version4.php ADDED
@@ -0,0 +1,60 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Nexcess.net Turpentine Extension for Magento
5
+ * Copyright (C) 2012 Nexcess.net L.L.C.
6
+ *
7
+ * This program is free software; you can redistribute it and/or modify
8
+ * it under the terms of the GNU General Public License as published by
9
+ * the Free Software Foundation; either version 2 of the License, or
10
+ * (at your option) any later version.
11
+ *
12
+ * This program is distributed in the hope that it will be useful,
13
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
+ * GNU General Public License for more details.
16
+ *
17
+ * You should have received a copy of the GNU General Public License along
18
+ * with this program; if not, write to the Free Software Foundation, Inc.,
19
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20
+ */
21
+
22
+ class Nexcessnet_Turpentine_Model_Varnish_Configurator_Version4
23
+ extends Nexcessnet_Turpentine_Model_Varnish_Configurator_Abstract {
24
+
25
+ const VCL_TEMPLATE_FILE = 'version-4.vcl';
26
+
27
+ /**
28
+ * Generate the Varnish 4.0-compatible VCL
29
+ *
30
+ * @param bool $doClean if true, VCL will be cleaned (whitespaces stripped, etc.)
31
+ * @return string
32
+ */
33
+ public function generate($doClean=true) {
34
+ $tplFile = $this->_getVclTemplateFilename( self::VCL_TEMPLATE_FILE );
35
+ $vcl = $this->_formatTemplate( file_get_contents( $tplFile ),
36
+ $this->_getTemplateVars() );
37
+ return $doClean ? $this->_cleanVcl( $vcl ) : $vcl;
38
+ }
39
+
40
+ // TODO: Check this
41
+ protected function _getAdvancedSessionValidation() {
42
+ $validation = '';
43
+ foreach( $this->_getAdvancedSessionValidationTargets() as $target ) {
44
+ $validation .= sprintf( 'hash_data(%s);' . PHP_EOL, $target );
45
+ }
46
+ return $validation;
47
+ }
48
+
49
+ /**
50
+ * Build the list of template variables to apply to the VCL template
51
+ *
52
+ * @return array
53
+ */
54
+ protected function _getTemplateVars() {
55
+ $vars = parent::_getTemplateVars();
56
+ $vars['advanced_session_validation'] =
57
+ $this->_getAdvancedSessionValidation();
58
+ return $vars;
59
+ }
60
+ }
app/code/community/Nexcessnet/Turpentine/etc/config.xml CHANGED
@@ -20,7 +20,7 @@
20
  <config>
21
  <modules>
22
  <Nexcessnet_Turpentine>
23
- <version>0.6.4</version>
24
  </Nexcessnet_Turpentine>
25
  </modules>
26
  <default>
@@ -49,8 +49,13 @@
49
  </turpentine_varnish>
50
  <turpentine_vcl>
51
  <backend>
 
52
  <backend_host>127.0.0.1</backend_host>
53
  <backend_port>8080</backend_port>
 
 
 
 
54
  <frontend_timeout>300</frontend_timeout>
55
  <admin_timeout>21600</admin_timeout>
56
  <crawlers>127.0.0.1</crawlers>
@@ -131,6 +136,18 @@
131
  <activePoll>Nexcessnet_Turpentine_Block_Poll_ActivePoll</activePoll>
132
  </rewrite>
133
  </poll>
 
 
 
 
 
 
 
 
 
 
 
 
134
  <adminhtml>
135
  <rewrite>
136
  <cache_grid>Nexcessnet_Turpentine_Block_Adminhtml_Cache_Grid</cache_grid>
20
  <config>
21
  <modules>
22
  <Nexcessnet_Turpentine>
23
+ <version>0.6.5</version>
24
  </Nexcessnet_Turpentine>
25
  </modules>
26
  <default>
49
  </turpentine_varnish>
50
  <turpentine_vcl>
51
  <backend>
52
+ <load_balancing>no</load_balancing>
53
  <backend_host>127.0.0.1</backend_host>
54
  <backend_port>8080</backend_port>
55
+ <backend_nodes>127.0.0.1:8080</backend_nodes>
56
+ <backend_probe_url></backend_probe_url>
57
+ <backend_nodes_admin>127.0.0.1:8080</backend_nodes_admin>
58
+ <backend_probe_url_admin></backend_probe_url_admin>
59
  <frontend_timeout>300</frontend_timeout>
60
  <admin_timeout>21600</admin_timeout>
61
  <crawlers>127.0.0.1</crawlers>
136
  <activePoll>Nexcessnet_Turpentine_Block_Poll_ActivePoll</activePoll>
137
  </rewrite>
138
  </poll>
139
+
140
+ <!--
141
+ Rewrite the compared and viewed product block. Default behavior returns '' if
142
+ no items to display, which prevents display of the ESI url, causing caching problems
143
+ -->
144
+ <reports>
145
+ <rewrite>
146
+ <product_compared>Nexcessnet_Turpentine_Block_Product_Compared</product_compared>
147
+ <product_viewed>Nexcessnet_Turpentine_Block_Product_Viewed</product_viewed>
148
+ </rewrite>
149
+ </reports>
150
+
151
  <adminhtml>
152
  <rewrite>
153
  <cache_grid>Nexcessnet_Turpentine_Block_Adminhtml_Cache_Grid</cache_grid>
app/code/community/Nexcessnet/Turpentine/etc/config.xml~ ADDED
@@ -0,0 +1,529 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <!--
3
+ Nexcess.net Turpentine Extension for Magento
4
+ Copyright (C) 2012 Nexcess.net L.L.C.
5
+
6
+ This program is free software; you can redistribute it and/or modify
7
+ it under the terms of the GNU General Public License as published by
8
+ the Free Software Foundation; either version 2 of the License, or
9
+ (at your option) any later version.
10
+
11
+ This program is distributed in the hope that it will be useful,
12
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ GNU General Public License for more details.
15
+
16
+ You should have received a copy of the GNU General Public License along
17
+ with this program; if not, write to the Free Software Foundation, Inc.,
18
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19
+ -->
20
+ <config>
21
+ <modules>
22
+ <Nexcessnet_Turpentine>
23
+ <version>0.6.4</version>
24
+ </Nexcessnet_Turpentine>
25
+ </modules>
26
+ <default>
27
+ <turpentine_varnish>
28
+ <general>
29
+ <auto_apply_on_save>1</auto_apply_on_save>
30
+ <strip_vcl_whitespace>always</strip_vcl_whitespace>
31
+ <varnish_debug>0</varnish_debug>
32
+ <vcl_fix>1</vcl_fix>
33
+ <block_debug>0</block_debug>
34
+ <ajax_messages>1</ajax_messages>
35
+ <fix_product_toolbar>0</fix_product_toolbar>
36
+ <crawler_enable>0</crawler_enable>
37
+ <crawler_debug>0</crawler_debug>
38
+ </general>
39
+ <logging>
40
+ <use_custom_log_file>0</use_custom_log_file>
41
+ <custom_log_file_name>turpentine.log</custom_log_file_name>
42
+ </logging>
43
+ <servers>
44
+ <version>auto</version>
45
+ <server_list>127.0.0.1:6082</server_list>
46
+ <config_file>{{root_dir}}/var/default.vcl</config_file>
47
+ <custom_include_file>{{root_dir}}/app/code/community/Nexcessnet/Turpentine/misc/custom_include.vcl</custom_include_file>
48
+ </servers>
49
+ </turpentine_varnish>
50
+ <turpentine_vcl>
51
+ <backend>
52
+ <load_balancing>no</load_balancing>
53
+ <backend_host>127.0.0.1</backend_host>
54
+ <backend_port>8080</backend_port>
55
+ <backend_nodes>127.0.0.1:8080</backend_nodes>
56
+ <backend_probe_url></backend_probe_url>
57
+ <backend_nodes_admin>127.0.0.1:8080</backend_nodes_admin>
58
+ <backend_probe_url_admin></backend_probe_url_admin>
59
+ <frontend_timeout>300</frontend_timeout>
60
+ <admin_timeout>21600</admin_timeout>
61
+ <crawlers>127.0.0.1</crawlers>
62
+ <crawler_user_agents><![CDATA[ApacheBench/.*,.*Googlebot.*,JoeDog/.*Siege.*,magespeedtest\.com,Nexcessnet_Turpentine/.*]]></crawler_user_agents>
63
+ </backend>
64
+ <normalization>
65
+ <encoding>1</encoding>
66
+ <user_agent>0</user_agent>
67
+ <host>0</host>
68
+ </normalization>
69
+ <ttls>
70
+ <grace_period>15</grace_period>
71
+ <default_ttl>3600</default_ttl>
72
+ <static_ttl>28800</static_ttl>
73
+ <!--
74
+ <lru_factor>15</lru_factor>
75
+ -->
76
+ </ttls>
77
+ <urls>
78
+ <url_blacklist><![CDATA[cron\.php]]></url_blacklist>
79
+ </urls>
80
+ <params>
81
+ <get_params>__SID,XDEBUG_PROFILE</get_params>
82
+ <ignore_get_params>utm_source,utm_medium,utm_campaign,utm_content,utm_term,gclid,cx,ie,cof,siteurl</ignore_get_params>
83
+ </params>
84
+ <static>
85
+ <force_static>1</force_static>
86
+ <exts>css,js,jpe?g,png,gif,ico,swf</exts>
87
+ </static>
88
+ </turpentine_vcl>
89
+ </default>
90
+ <global>
91
+ <!--
92
+ This disables Magento visitor logging for Turpentine ESI
93
+ requests. The logging was pointless and caused AJAX blocks to
94
+ take much more time then they otherwise would to load (most of
95
+ the time was spent doing database writes)
96
+ -->
97
+ <!-- Disabled because if the visitor doesn't have any entries in the
98
+ visitor log the product comparison block won't work for non-logged-in
99
+ visitors.
100
+ @see Mage/Catalog/controllers/Product/CompareController.php#79
101
+
102
+ <ignoredModules>
103
+ <entities>
104
+ <turpentine/>
105
+ </entities>
106
+ </ignoredModules>
107
+ -->
108
+ <blocks>
109
+ <turpentine>
110
+ <class>Nexcessnet_Turpentine_Block</class>
111
+ </turpentine>
112
+ <!--
113
+ The core/messages block is rewritten because it doesn't use a
114
+ template we can replace with an ESI include tag, just dumps out a
115
+ block of hard-coded HTML and also frequently skips the toHtml method
116
+
117
+ However, since class rewrites aren't conditional and we only want to
118
+ do this rewrite if the Enable Flash Messages option is enabled the
119
+ rewrite is actually added at runtime (controller_front_init_before),
120
+ see observer_esi::addMessagesBlockRewrite . Leaving this rewrite
121
+ here but commented out for clarity
122
+ -->
123
+ <!--
124
+ <core>
125
+ <rewrite>
126
+ <messages>Nexcessnet_Turpentine_Block_Core_Messages</messages>
127
+ </rewrite>
128
+ </core>
129
+ -->
130
+ <!--
131
+ Rewrite the poll ActivePoll block, as it uses its own custom
132
+ template setting methods.
133
+ -->
134
+ <poll>
135
+ <rewrite>
136
+ <activePoll>Nexcessnet_Turpentine_Block_Poll_ActivePoll</activePoll>
137
+ </rewrite>
138
+ </poll>
139
+
140
+ <!--
141
+ Rewrite the compared and viewed product block. Default behavior returns '' if
142
+ no items to display, which prevents display of the ESI url, causing caching problems
143
+ -->
144
+ <reports>
145
+ <rewrite>
146
+ <product_compared>Nexcessnet_Turpentine_Block_Product_Compared</product_compared>
147
+ <product_viewed>Nexcessnet_Turpentine_Block_Product_Viewed</product_viewed>
148
+ </rewrite>
149
+ </reports>
150
+
151
+ <adminhtml>
152
+ <rewrite>
153
+ <cache_grid>Nexcessnet_Turpentine_Block_Adminhtml_Cache_Grid</cache_grid>
154
+ </rewrite>
155
+ </adminhtml>
156
+ </blocks>
157
+ <helpers>
158
+ <turpentine>
159
+ <class>Nexcessnet_Turpentine_Helper</class>
160
+ </turpentine>
161
+ </helpers>
162
+ <models>
163
+ <turpentine>
164
+ <class>Nexcessnet_Turpentine_Model</class>
165
+ </turpentine>
166
+ <core>
167
+ <rewrite>
168
+ <session>Nexcessnet_Turpentine_Model_Core_Session</session>
169
+ </rewrite>
170
+ </core>
171
+ </models>
172
+ <cache>
173
+ <types>
174
+ <!--
175
+ These aren't used to actually store anything in Magento's cache,
176
+ we just use them to signal Varnish to purge it's cache. Note
177
+ that the type names must match the MAGE_CACHE_NAME constant in
178
+ the Varnish and ESI helpers.
179
+ -->
180
+ <turpentine_pages>
181
+ <label>Varnish Pages</label>
182
+ <description>Full pages cached in Varnish (will also flush ESI blocks)</description>
183
+ <tags>TURPENTINE_FAKE_PAGE_TAG</tags>
184
+ </turpentine_pages>
185
+ <turpentine_esi_blocks>
186
+ <label>Varnish ESI Blocks</label>
187
+ <description>ESI blocks cached in Varnish (this should not be disabled except for debugging)</description>
188
+ <!--
189
+ This is helpful to prevent blocks from being double ESI-
190
+ included, which ends up resulting in the "ESI processing
191
+ not enabled" error
192
+ -->
193
+ <tags>BLOCK_HTML</tags>
194
+ </turpentine_esi_blocks>
195
+ </types>
196
+ </cache>
197
+ <events>
198
+ <!-- Varnish Events -->
199
+ <http_response_send_before>
200
+ <observers>
201
+ <turpentine_varnish_http_response_send_before>
202
+ <class>turpentine/observer_varnish</class>
203
+ <method>setCacheFlagHeader</method>
204
+ </turpentine_varnish_http_response_send_before>
205
+ </observers>
206
+ </http_response_send_before>
207
+
208
+ <admin_system_config_changed_section_turpentine_varnish>
209
+ <observers>
210
+ <turpentine_varnish_admin_system_config_changed_section_turpentine_varnish>
211
+ <class>turpentine/observer_varnish</class>
212
+ <method>adminSystemConfigChangedSection</method>
213
+ </turpentine_varnish_admin_system_config_changed_section_turpentine_varnish>
214
+ </observers>
215
+ </admin_system_config_changed_section_turpentine_varnish>
216
+ <admin_system_config_changed_section_turpentine_vcl>
217
+ <observers>
218
+ <turpentine_varnish_admin_system_config_changed_section_turpentine_vcl>
219
+ <class>turpentine/observer_varnish</class>
220
+ <method>adminSystemConfigChangedSection</method>
221
+ </turpentine_varnish_admin_system_config_changed_section_turpentine_vcl>
222
+ </observers>
223
+ </admin_system_config_changed_section_turpentine_vcl>
224
+
225
+ <!-- ESI Events -->
226
+ <core_block_abstract_to_html_before>
227
+ <observers>
228
+ <turpentine_esi_core_block_abstract_to_html_before>
229
+ <type>singleton</type>
230
+ <class>turpentine/observer_esi</class>
231
+ <method>injectEsi</method>
232
+ </turpentine_esi_core_block_abstract_to_html_before>
233
+ </observers>
234
+ </core_block_abstract_to_html_before>
235
+ <http_response_send_before>
236
+ <observers>
237
+ <turpentine_esi_http_response_send_before>
238
+ <class>turpentine/observer_esi</class>
239
+ <method>setFlagHeaders</method>
240
+ </turpentine_esi_http_response_send_before>
241
+ <turpentine_esi_replace_form_key_placeholder>
242
+ <class>turpentine/observer_esi</class>
243
+ <method>replaceFormKeyPlaceholder</method>
244
+ </turpentine_esi_replace_form_key_placeholder>
245
+ </observers>
246
+ </http_response_send_before>
247
+ <controller_action_layout_generate_blocks_after>
248
+ <observers>
249
+ <turpentine_esi_controller_action_layout_generate_blocks_after>
250
+ <class>turpentine/observer_esi</class>
251
+ <method>checkCacheFlag</method>
252
+ </turpentine_esi_controller_action_layout_generate_blocks_after>
253
+ </observers>
254
+ </controller_action_layout_generate_blocks_after>
255
+ <customer_login>
256
+ <observers>
257
+ <turpentine_customer_login_cookie>
258
+ <class>turpentine/observer_esi</class>
259
+ <method>setCustomerGroupCookie</method>
260
+ </turpentine_customer_login_cookie>
261
+ </observers>
262
+ </customer_login>
263
+ <customer_logout>
264
+ <observers>
265
+ <turpentine_customer_logout_remove_cookie>
266
+ <class>turpentine/observer_esi</class>
267
+ <method>removeCustomerGroupCookie</method>
268
+ </turpentine_customer_logout_remove_cookie>
269
+ </observers>
270
+ </customer_logout>
271
+ <!--
272
+ Magento sometimes sees the last URL as being the
273
+ turpentine/esi/getBlock url, and then redirects to it which is not
274
+ good. We need to check and intercept it if it happens
275
+ -->
276
+ <controller_response_redirect>
277
+ <observers>
278
+ <turpentine_esi_controller_response_redirect>
279
+ <class>turpentine/observer_esi</class>
280
+ <method>checkRedirectUrl</method>
281
+ </turpentine_esi_controller_response_redirect>
282
+ </observers>
283
+ </controller_response_redirect>
284
+
285
+ <!--
286
+ Load the ESI client cache clear events from stored config at
287
+ runtime
288
+ -->
289
+ <controller_front_init_before>
290
+ <observers>
291
+ <turpentine_esi_controller_front_init_before>
292
+ <class>turpentine/observer_esi</class>
293
+ <method>loadCacheClearEvents</method>
294
+ </turpentine_esi_controller_front_init_before>
295
+ <turpentine_esi_controller_front_init_before2>
296
+ <class>turpentine/observer_esi</class>
297
+ <method>addMessagesBlockRewrite</method>
298
+ </turpentine_esi_controller_front_init_before2>
299
+ <turpentine_varnish_controller_front_init_before>
300
+ <class>turpentine/observer_varnish</class>
301
+ <method>addProductListToolbarRewrite</method>
302
+ </turpentine_varnish_controller_front_init_before>
303
+ <turpentine_esi_set_replace_form_key_flag>
304
+ <class>turpentine/observer_esi</class>
305
+ <method>setReplaceFormKeyFlag</method>
306
+ </turpentine_esi_set_replace_form_key_flag>
307
+ </observers>
308
+ </controller_front_init_before>
309
+
310
+ <!-- Varnish cache clear events -->
311
+ <catalog_product_save_commit_after>
312
+ <observers>
313
+ <turpentine_varnish_catalog_product_save_commit_after>
314
+ <class>turpentine/observer_ban</class>
315
+ <method>banProductPageCache</method>
316
+ </turpentine_varnish_catalog_product_save_commit_after>
317
+ </observers>
318
+ </catalog_product_save_commit_after>
319
+ <review_save_after>
320
+ <observers>
321
+ <turpentine_varnish_review_save_after>
322
+ <class>turpentine/observer_ban</class>
323
+ <method>banProductReview</method>
324
+ </turpentine_varnish_review_save_after>
325
+ </observers>
326
+ </review_save_after>
327
+ <cataloginventory_stock_item_save_after>
328
+ <observers>
329
+ <turpentine_varnish_cataloginventory_stock_item_save_after>
330
+ <class>turpentine/observer_ban</class>
331
+ <method>banProductPageCacheCheckStock</method>
332
+ </turpentine_varnish_cataloginventory_stock_item_save_after>
333
+ </observers>
334
+ </cataloginventory_stock_item_save_after>
335
+ <catalog_category_save_commit_after>
336
+ <observers>
337
+ <turpentine_varnish_catalog_category_save_commit_after>
338
+ <class>turpentine/observer_ban</class>
339
+ <method>banCategoryCache</method>
340
+ </turpentine_varnish_catalog_category_save_commit_after>
341
+ </observers>
342
+ </catalog_category_save_commit_after>
343
+ <!--
344
+ This is disabled because it causes broken images on cached pages
345
+ -->
346
+ <!--
347
+ <clean_media_cache_after>
348
+ <observers>
349
+ <turpentine_varnish_clean_media_cache_after>
350
+ <class>turpentine/observer_ban</class>
351
+ <method>banMediaCache</method>
352
+ </turpentine_varnish_clean_media_cache_after>
353
+ </observers>
354
+ </clean_media_cache_after>
355
+ <clean_catalog_images_cache_after>
356
+ <observers>
357
+ <turpentine_varnish_clean_catalog_images_cache_after>
358
+ <class>turpentine/observer_ban</class>
359
+ <method>banCatalogImagesCache</method>
360
+ </turpentine_varnish_clean_catalog_images_cache_after>
361
+ </observers>
362
+ </clean_catalog_images_cache_after>
363
+ -->
364
+ <cms_page_save_commit_after>
365
+ <observers>
366
+ <turpentine_varnish_cms_page_save_commit_after>
367
+ <class>turpentine/observer_ban</class>
368
+ <method>banCmsPageCache</method>
369
+ </turpentine_varnish_cms_page_save_commit_after>
370
+ </observers>
371
+ </cms_page_save_commit_after>
372
+ <enterprise_cms_revision_save_commit_after>
373
+ <observers>
374
+ <turpentine_varnish_enterprise_cms_revision_save_commit_after>
375
+ <class>turpentine/observer_ban</class>
376
+ <method>banCmsPageRevisionCache</method>
377
+ <type>singleton</type>
378
+ </turpentine_varnish_enterprise_cms_revision_save_commit_after>
379
+ </observers>
380
+ </enterprise_cms_revision_save_commit_after>
381
+ <adminhtml_cache_flush_system>
382
+ <observers>
383
+ <turpentine_varnish_adminhtml_cache_flush_system>
384
+ <class>turpentine/observer_ban</class>
385
+ <method>banAllCache</method>
386
+ </turpentine_varnish_adminhtml_cache_flush_system>
387
+ </observers>
388
+ </adminhtml_cache_flush_system>
389
+ <adminhtml_cache_flush_all>
390
+ <observers>
391
+ <turpentine_varnish_adminhtml_cache_flush_all>
392
+ <class>turpentine/observer_ban</class>
393
+ <method>banAllCache</method>
394
+ </turpentine_varnish_adminhtml_cache_flush_all>
395
+ </observers>
396
+ </adminhtml_cache_flush_all>
397
+ <adminhtml_cache_refresh_type>
398
+ <observers>
399
+ <turpentine_varnish_adminhtml_cache_refresh_type>
400
+ <class>turpentine/observer_ban</class>
401
+ <method>banCacheType</method>
402
+ </turpentine_varnish_adminhtml_cache_refresh_type>
403
+ </observers>
404
+ </adminhtml_cache_refresh_type>
405
+ <!-- Cron/Crawler events -->
406
+ <turpentine_ban_all_cache>
407
+ <observers>
408
+ <turpentine_cron_turpentine_ban_all_cache>
409
+ <class>turpentine/observer_cron</class>
410
+ <method>queueAllUrls</method>
411
+ </turpentine_cron_turpentine_ban_all_cache>
412
+ </observers>
413
+ </turpentine_ban_all_cache>
414
+ </events>
415
+ </global>
416
+ <frontend>
417
+ <routers>
418
+ <turpentine>
419
+ <use>standard</use>
420
+ <args>
421
+ <module>Nexcessnet_Turpentine</module>
422
+ <frontName>turpentine</frontName>
423
+ </args>
424
+ </turpentine>
425
+ </routers>
426
+ <layout>
427
+ <updates>
428
+ <!--
429
+ This file should never be edited by a user since it will
430
+ be overwritten on extension updates
431
+ -->
432
+ <turpentine_esi module="turpentine">
433
+ <file>turpentine_esi.xml</file>
434
+ </turpentine_esi>
435
+ </updates>
436
+ </layout>
437
+ <events>
438
+ <controller_action_predispatch>
439
+ <observers>
440
+ <controller_action_before>
441
+ <class>turpentine/observer_esi</class>
442
+ <method>hookToControllerActionPreDispatch</method>
443
+ </controller_action_before>
444
+ </observers>
445
+ </controller_action_predispatch>
446
+ <!--controller_action_postdispatch>
447
+ <observers>
448
+ <controller_action_after>
449
+ <class>turpentine/observer_esi</class>
450
+ <method>hookToControllerActionPostDispatch</method>
451
+ </controller_action_after>
452
+ </observers>
453
+ </controller_action_postdispatch-->
454
+ <add_to_cart_before>
455
+ <observers>
456
+ <add_to_cart_before>
457
+ <class>turpentine/observer_esi</class>
458
+ <method>hookToAddToCartBefore</method>
459
+ </add_to_cart_before>
460
+ </observers>
461
+ </add_to_cart_before>
462
+ <!--add_to_cart_after>
463
+ <observers>
464
+ <add_to_cart_after>
465
+ <class>turpentine/observer_esi</class>
466
+ <method>hookToAddToCartAfter</method>
467
+ </add_to_cart_after>
468
+ </observers>
469
+ </add_to_cart_after-->
470
+ </events>
471
+ </frontend>
472
+ <admin>
473
+ <routers>
474
+ <adminhtml>
475
+ <args>
476
+ <modules>
477
+ <turpentine after="Mage_Adminhtml">Nexcessnet_Turpentine</turpentine>
478
+ </modules>
479
+ </args>
480
+ </adminhtml>
481
+ </routers>
482
+ </admin>
483
+ <adminhtml>
484
+ <layout>
485
+ <updates>
486
+ <turpentine module="turpentine">
487
+ <file>turpentine.xml</file>
488
+ </turpentine>
489
+ </updates>
490
+ </layout>
491
+ <acl>
492
+ <resources>
493
+ <admin>
494
+ <children>
495
+ <system>
496
+ <children>
497
+ <turpentine translate="title" module="turpentine">
498
+ <title>Turpentine Varnish Management</title>
499
+ </turpentine>
500
+ <config>
501
+ <children>
502
+ <turpentine_varnish translate="title" module="turpentine">
503
+ <title>Turpentine Varnish Options</title>
504
+ </turpentine_varnish>
505
+ <turpentine_vcl translate="title" module="turpentine">
506
+ <title>Turpentine Caching Options</title>
507
+ </turpentine_vcl>
508
+ </children>
509
+ </config>
510
+ </children>
511
+ </system>
512
+ </children>
513
+ </admin>
514
+ </resources>
515
+ </acl>
516
+ </adminhtml>
517
+ <crontab>
518
+ <jobs>
519
+ <turpentine_crawl_urls>
520
+ <schedule>
521
+ <cron_expr>0,10,20,30,40,50 * * * *</cron_expr>
522
+ </schedule>
523
+ <run>
524
+ <model>turpentine/observer_cron::crawlUrls</model>
525
+ </run>
526
+ </turpentine_crawl_urls>
527
+ </jobs>
528
+ </crontab>
529
+ </config>
app/code/community/Nexcessnet/Turpentine/etc/system.xml CHANGED
@@ -239,6 +239,15 @@
239
  <show_in_website>0</show_in_website>
240
  <show_in_store>0</show_in_store>
241
  <fields>
 
 
 
 
 
 
 
 
 
242
  <backend_host translate="label" module="turpentine">
243
  <label>Backend Host</label>
244
  <frontend_type>text</frontend_type>
@@ -246,6 +255,9 @@
246
  <show_in_default>1</show_in_default>
247
  <show_in_website>0</show_in_website>
248
  <show_in_store>0</show_in_store>
 
 
 
249
  </backend_host>
250
  <backend_port translate="label" module="turpentine">
251
  <label>Backend Port</label>
@@ -255,7 +267,56 @@
255
  <show_in_default>1</show_in_default>
256
  <show_in_website>0</show_in_website>
257
  <show_in_store>0</show_in_store>
 
 
 
258
  </backend_port>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
259
  <frontend_timeout translate="label" module="turpentine">
260
  <label>Frontend Timeout</label>
261
  <frontend_type>text</frontend_type>
@@ -280,7 +341,7 @@
280
  <label>Crawler IP Addresses</label>
281
  <frontend_type>text</frontend_type>
282
  <sort_order>50</sort_order>
283
- <comment>Comma-separated list of IPs to serve cached pages to on initial visit</comment>
284
  <show_in_default>1</show_in_default>
285
  <show_in_website>0</show_in_website>
286
  <show_in_store>0</show_in_store>
239
  <show_in_website>0</show_in_website>
240
  <show_in_store>0</show_in_store>
241
  <fields>
242
+ <load_balancing translate="label" module="turpentine">
243
+ <label>Load Balancing</label>
244
+ <frontend_type>select</frontend_type>
245
+ <source_model>turpentine/config_select_loadBalancing</source_model>
246
+ <sort_order>05</sort_order>
247
+ <show_in_default>1</show_in_default>
248
+ <show_in_website>0</show_in_website>
249
+ <show_in_store>0</show_in_store>
250
+ </load_balancing>
251
  <backend_host translate="label" module="turpentine">
252
  <label>Backend Host</label>
253
  <frontend_type>text</frontend_type>
255
  <show_in_default>1</show_in_default>
256
  <show_in_website>0</show_in_website>
257
  <show_in_store>0</show_in_store>
258
+ <depends>
259
+ <load_balancing>no</load_balancing>
260
+ </depends>
261
  </backend_host>
262
  <backend_port translate="label" module="turpentine">
263
  <label>Backend Port</label>
267
  <show_in_default>1</show_in_default>
268
  <show_in_website>0</show_in_website>
269
  <show_in_store>0</show_in_store>
270
+ <depends>
271
+ <load_balancing>no</load_balancing>
272
+ </depends>
273
  </backend_port>
274
+ <backend_nodes translate="label comment" module="turpentine">
275
+ <label>Backend Server List</label>
276
+ <frontend_type>textarea</frontend_type>
277
+ <comment>A list of HOST:PORT pairs of the backend web servers, one per line</comment>
278
+ <sort_order>22</sort_order>
279
+ <show_in_default>1</show_in_default>
280
+ <show_in_website>0</show_in_website>
281
+ <show_in_store>0</show_in_store>
282
+ <depends>
283
+ <load_balancing separator="|">yes|yes_admin</load_balancing>
284
+ </depends>
285
+ </backend_nodes>
286
+ <backend_probe_url translate="label comment" module="turpentine">
287
+ <label>Backend Check URL</label>
288
+ <comment>URL where Varnish can probe if a node is available. Leave empty to disable probing.</comment>
289
+ <frontend_type>text</frontend_type>
290
+ <sort_order>23</sort_order>
291
+ <show_in_default>1</show_in_default>
292
+ <show_in_website>0</show_in_website>
293
+ <show_in_store>0</show_in_store>
294
+ <depends>
295
+ <load_balancing separator="|">yes|yes_admin</load_balancing>
296
+ </depends>
297
+ </backend_probe_url>
298
+ <backend_nodes_admin translate="label" module="turpentine">
299
+ <label>Backend Server List for Admin</label>
300
+ <frontend_type>textarea</frontend_type>
301
+ <sort_order>25</sort_order>
302
+ <show_in_default>1</show_in_default>
303
+ <show_in_website>0</show_in_website>
304
+ <show_in_store>0</show_in_store>
305
+ <depends>
306
+ <load_balancing>yes_admin</load_balancing>
307
+ </depends>
308
+ </backend_nodes_admin>
309
+ <backend_probe_url_admin translate="label" module="turpentine">
310
+ <label>Backend Check URL for Admin</label>
311
+ <frontend_type>text</frontend_type>
312
+ <sort_order>27</sort_order>
313
+ <show_in_default>1</show_in_default>
314
+ <show_in_website>0</show_in_website>
315
+ <show_in_store>0</show_in_store>
316
+ <depends>
317
+ <load_balancing>yes_admin</load_balancing>
318
+ </depends>
319
+ </backend_probe_url_admin>
320
  <frontend_timeout translate="label" module="turpentine">
321
  <label>Frontend Timeout</label>
322
  <frontend_type>text</frontend_type>
341
  <label>Crawler IP Addresses</label>
342
  <frontend_type>text</frontend_type>
343
  <sort_order>50</sort_order>
344
+ <comment>Comma-separated list of IP addresses that should bypass Turpentine's frontend cookie requirement. Also useful for performance testing tools as they also typically don't support cookies. Note - if you are using something like Pound to terminate SSL before Varnish, setting this to the same IP could cause users to end up sharing the crawler session.</comment>
345
  <show_in_default>1</show_in_default>
346
  <show_in_website>0</show_in_website>
347
  <show_in_store>0</show_in_store>
app/code/community/Nexcessnet/Turpentine/misc/version-2.vcl CHANGED
@@ -119,6 +119,9 @@ sub vcl_recv {
119
  if (req.http.X-Opt-Enable-Caching != "true" || req.http.Authorization ||
120
  !(req.request ~ "^(GET|HEAD|OPTIONS)$") ||
121
  req.http.Cookie ~ "varnish_bypass={{secret_handshake}}") {
 
 
 
122
  return (pipe);
123
  }
124
 
119
  if (req.http.X-Opt-Enable-Caching != "true" || req.http.Authorization ||
120
  !(req.request ~ "^(GET|HEAD|OPTIONS)$") ||
121
  req.http.Cookie ~ "varnish_bypass={{secret_handshake}}") {
122
+ if (req.url ~ "{{url_base_regex}}{{admin_frontname}}") {
123
+ set req.backend = admin;
124
+ }
125
  return (pipe);
126
  }
127
 
app/code/community/Nexcessnet/Turpentine/misc/version-3.vcl CHANGED
@@ -121,6 +121,9 @@ sub vcl_recv {
121
  if (!{{enable_caching}} || req.http.Authorization ||
122
  req.request !~ "^(GET|HEAD|OPTIONS)$" ||
123
  req.http.Cookie ~ "varnish_bypass={{secret_handshake}}") {
 
 
 
124
  return (pipe);
125
  }
126
 
121
  if (!{{enable_caching}} || req.http.Authorization ||
122
  req.request !~ "^(GET|HEAD|OPTIONS)$" ||
123
  req.http.Cookie ~ "varnish_bypass={{secret_handshake}}") {
124
+ if (req.url ~ "{{url_base_regex}}{{admin_frontname}}") {
125
+ set req.backend = admin;
126
+ }
127
  return (pipe);
128
  }
129
 
app/code/community/Nexcessnet/Turpentine/misc/version-4.vcl ADDED
@@ -0,0 +1,409 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ vcl 4.0;
2
+ # Nexcess.net Turpentine Extension for Magento
3
+ # Copyright (C) 2012 Nexcess.net L.L.C.
4
+ #
5
+ # This program is free software; you can redistribute it and/or modify
6
+ # it under the terms of the GNU General Public License as published by
7
+ # the Free Software Foundation; either version 2 of the License, or
8
+ # (at your option) any later version.
9
+ #
10
+ # This program is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ # GNU General Public License for more details.
14
+ #
15
+ # You should have received a copy of the GNU General Public License along
16
+ # with this program; if not, write to the Free Software Foundation, Inc.,
17
+ # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18
+
19
+ ## Nexcessnet_Turpentine Varnish v3 VCL Template
20
+
21
+ ## Custom C Code
22
+
23
+ C{
24
+ # @source app/code/community/Nexcessnet/Turpentine/misc/uuid.c
25
+ {{custom_c_code}}
26
+ }C
27
+
28
+ ## Imports
29
+
30
+ import std;
31
+
32
+ ## Custom VCL Logic
33
+
34
+ {{custom_vcl_include}}
35
+
36
+ ## Backends
37
+
38
+ {{default_backend}}
39
+
40
+ {{admin_backend}}
41
+
42
+ ## ACLs
43
+
44
+ {{crawler_acl}}
45
+
46
+ {{debug_acl}}
47
+
48
+ ## Custom Subroutines
49
+
50
+ {{generate_session_start}}
51
+ sub generate_session {
52
+ # generate a UUID and add `frontend=$UUID` to the Cookie header, or use SID
53
+ # from SID URL param
54
+ if (req.url ~ ".*[&?]SID=([^&]+).*") {
55
+ set req.http.X-Varnish-Faked-Session = regsub(
56
+ req.url, ".*[&?]SID=([^&]+).*", "frontend=\1");
57
+ } else {
58
+ C{
59
+ char uuid_buf [50];
60
+ generate_uuid(uuid_buf);
61
+ static const struct gethdr_s VGC_HDR_REQ_VARNISH_FAKED_SESSION =
62
+ { HDR_REQ, "\030X-Varnish-Faked-Session:"};
63
+ VRT_SetHdr(ctx,
64
+ &VGC_HDR_REQ_VARNISH_FAKED_SESSION,
65
+ uuid_buf,
66
+ vrt_magic_string_end
67
+ );
68
+ }C
69
+ }
70
+ if (req.http.Cookie) {
71
+ # client sent us cookies, just not a frontend cookie. try not to blow
72
+ # away the extra cookies
73
+ std.collect(req.http.Cookie);
74
+ set req.http.Cookie = req.http.X-Varnish-Faked-Session +
75
+ "; " + req.http.Cookie;
76
+ } else {
77
+ set req.http.Cookie = req.http.X-Varnish-Faked-Session;
78
+ }
79
+ }
80
+
81
+ sub generate_session_expires {
82
+ # sets X-Varnish-Cookie-Expires to now + esi_private_ttl in format:
83
+ # Tue, 19-Feb-2013 00:14:27 GMT
84
+ # this isn't threadsafe but it shouldn't matter in this case
85
+ C{
86
+ time_t now = time(NULL);
87
+ struct tm now_tm = *gmtime(&now);
88
+ now_tm.tm_sec += {{esi_private_ttl}};
89
+ mktime(&now_tm);
90
+ char date_buf [50];
91
+ strftime(date_buf, sizeof(date_buf)-1, "%a, %d-%b-%Y %H:%M:%S %Z", &now_tm);
92
+ static const struct gethdr_s VGC_HDR_RESP_COOKIE_EXPIRES =
93
+ { HDR_RESP, "\031X-Varnish-Cookie-Expires:"};
94
+ VRT_SetHdr(ctx,
95
+ &VGC_HDR_RESP_COOKIE_EXPIRES,
96
+ date_buf,
97
+ vrt_magic_string_end
98
+ );
99
+ }C
100
+ }
101
+ {{generate_session_end}}
102
+ ## Varnish Subroutines
103
+
104
+ sub vcl_recv {
105
+ # this always needs to be done so it's up at the top
106
+ if (req.restarts == 0) {
107
+ if (req.http.X-Forwarded-For) {
108
+ set req.http.X-Forwarded-For =
109
+ req.http.X-Forwarded-For + ", " + client.ip;
110
+ } else {
111
+ set req.http.X-Forwarded-For = client.ip;
112
+ }
113
+ }
114
+
115
+ # We only deal with GET and HEAD by default
116
+ # we test this here instead of inside the url base regex section
117
+ # so we can disable caching for the entire site if needed
118
+ if (!{{enable_caching}} || req.http.Authorization ||
119
+ req.method !~ "^(GET|HEAD|OPTIONS)$" ||
120
+ req.http.Cookie ~ "varnish_bypass={{secret_handshake}}") {
121
+ return (pipe);
122
+ }
123
+
124
+ # remove double slashes from the URL, for higher cache hit rate
125
+ set req.url = regsuball(req.url, "(.*)//+(.*)", "\1/\2");
126
+
127
+ {{normalize_encoding}}
128
+ {{normalize_user_agent}}
129
+ {{normalize_host}}
130
+
131
+ # check if the request is for part of magento
132
+ if (req.url ~ "{{url_base_regex}}") {
133
+ # set this so Turpentine can see the request passed through Varnish
134
+ set req.http.X-Turpentine-Secret-Handshake = "{{secret_handshake}}";
135
+ # use the special admin backend and pipe if it's for the admin section
136
+ if (req.url ~ "{{url_base_regex}}{{admin_frontname}}") {
137
+ set req.backend_hint = admin;
138
+ return (pipe);
139
+ }
140
+ if (req.http.Cookie ~ "\bcurrency=") {
141
+ set req.http.X-Varnish-Currency = regsub(
142
+ req.http.Cookie, ".*\bcurrency=([^;]*).*", "\1");
143
+ }
144
+ if (req.http.Cookie ~ "\bstore=") {
145
+ set req.http.X-Varnish-Store = regsub(
146
+ req.http.Cookie, ".*\bstore=([^;]*).*", "\1");
147
+ }
148
+ # looks like an ESI request, add some extra vars for further processing
149
+ if (req.url ~ "/turpentine/esi/get(?:Block|FormKey)/") {
150
+ set req.http.X-Varnish-Esi-Method = regsub(
151
+ req.url, ".*/{{esi_method_param}}/(\w+)/.*", "\1");
152
+ set req.http.X-Varnish-Esi-Access = regsub(
153
+ req.url, ".*/{{esi_cache_type_param}}/(\w+)/.*", "\1");
154
+
155
+ # throw a forbidden error if debugging is off and a esi block is
156
+ # requested by the user (does not apply to ajax blocks)
157
+ if (req.http.X-Varnish-Esi-Method == "esi" && req.esi_level == 0 &&
158
+ !({{debug_headers}} || client.ip ~ debug_acl)) {
159
+ return (synth(403, "External ESI requests are not allowed"));
160
+ }
161
+ }
162
+ # if host is not allowed in magento pass to backend
163
+ if (req.http.host !~ "{{allowed_hosts_regex}}") {
164
+ return (pass);
165
+ }
166
+ # no frontend cookie was sent to us AND this is not an ESI or AJAX call
167
+ if (req.http.Cookie !~ "frontend=" && !req.http.X-Varnish-Esi-Method) {
168
+ if (client.ip ~ crawler_acl ||
169
+ req.http.User-Agent ~ "^(?:{{crawler_user_agent_regex}})$") {
170
+ # it's a crawler, give it a fake cookie
171
+ set req.http.Cookie = "frontend=crawler-session";
172
+ } else {
173
+ # it's a real user, make up a new session for them
174
+ {{generate_session}}# call generate_session;
175
+ return (pipe);
176
+ }
177
+ }
178
+ if ({{force_cache_static}} &&
179
+ req.url ~ ".*\.(?:{{static_extensions}})(?=\?|&|$)") {
180
+ # don't need cookies for static assets
181
+ unset req.http.Cookie;
182
+ unset req.http.X-Varnish-Faked-Session;
183
+ return (hash);
184
+ }
185
+ # this doesn't need a enable_url_excludes because we can be reasonably
186
+ # certain that cron.php at least will always be in it, so it will
187
+ # never be empty
188
+ if (req.url ~ "{{url_base_regex}}(?:{{url_excludes}})" ||
189
+ # user switched stores. we pipe this instead of passing below because
190
+ # switching stores doesn't redirect (302), just acts like a link to
191
+ # another page (200) so the Set-Cookie header would be removed
192
+ req.url ~ "\?.*__from_store=") {
193
+ return (pipe);
194
+ }
195
+ if ({{enable_get_excludes}} &&
196
+ req.url ~ "(?:[?&](?:{{get_param_excludes}})(?=[&=]|$))") {
197
+ # TODO: should this be pass or pipe?
198
+ return (pass);
199
+ }
200
+ if (req.url ~ "[?&](utm_source|utm_medium|utm_campaign|gclid|cx|ie|cof|siteurl)=") {
201
+ # Strip out Google related parameters
202
+ set req.url = regsuball(req.url, "(?:(\?)?|&)(?:utm_source|utm_medium|utm_campaign|gclid|cx|ie|cof|siteurl)=[^&]+", "\1");
203
+ set req.url = regsuball(req.url, "(?:(\?)&|\?$)", "\1");
204
+ }
205
+
206
+ if ({{enable_get_ignored}} && req.url ~ "[?&]({{get_param_ignored}})=") {
207
+ # Strip out Ignored GET parameters
208
+ set req.url = regsuball(req.url, "(?:(\?)?|&)(?:{{get_param_ignored}})=[^&]+", "\1");
209
+ set req.url = regsuball(req.url, "(?:(\?)&|\?$)", "\1");
210
+ }
211
+
212
+ # everything else checks out, try and pull from the cache
213
+ return (hash);
214
+ }
215
+ # else it's not part of magento so do default handling (doesn't help
216
+ # things underneath magento but we can't detect that)
217
+ }
218
+
219
+ sub vcl_pipe {
220
+ # since we're not going to do any stuff to the response we pretend the
221
+ # request didn't pass through Varnish
222
+ unset bereq.http.X-Turpentine-Secret-Handshake;
223
+ set bereq.http.Connection = "close";
224
+ }
225
+
226
+ # sub vcl_pass {
227
+ # return (pass);
228
+ # }
229
+
230
+ sub vcl_hash {
231
+ hash_data(req.url);
232
+ if (req.http.Host) {
233
+ hash_data(req.http.Host);
234
+ } else {
235
+ hash_data(server.ip);
236
+ }
237
+ hash_data(req.http.Ssl-Offloaded);
238
+ if (req.http.X-Normalized-User-Agent) {
239
+ hash_data(req.http.X-Normalized-User-Agent);
240
+ }
241
+ if (req.http.Accept-Encoding) {
242
+ # make sure we give back the right encoding
243
+ hash_data(req.http.Accept-Encoding);
244
+ }
245
+ if (req.http.X-Varnish-Store || req.http.X-Varnish-Currency) {
246
+ # make sure data is for the right store and currency based on the *store*
247
+ # and *currency* cookies
248
+ hash_data("s=" + req.http.X-Varnish-Store + "&c=" + req.http.X-Varnish-Currency);
249
+ }
250
+
251
+ if (req.http.X-Varnish-Esi-Access == "private" &&
252
+ req.http.Cookie ~ "frontend=") {
253
+ hash_data(regsub(req.http.Cookie, "^.*?frontend=([^;]*);*.*$", "\1"));
254
+ {{advanced_session_validation}}
255
+
256
+ }
257
+ return (lookup);
258
+ }
259
+
260
+ sub vcl_hit {
261
+ # this seems to cause cache object contention issues so removed for now
262
+ # TODO: use obj.hits % something maybe
263
+ # if (obj.hits > 0) {
264
+ # set obj.ttl = obj.ttl + {{lru_factor}}s;
265
+ # }
266
+ }
267
+
268
+ # sub vcl_miss {
269
+ # return (fetch);
270
+ # }
271
+
272
+ sub vcl_backend_response {
273
+ # set the grace period
274
+ set beresp.grace = {{grace_period}}s;
275
+
276
+ # Store the URL in the response object, to be able to do lurker friendly bans later
277
+ set beresp.http.X-Varnish-Host = bereq.http.host;
278
+ set beresp.http.X-Varnish-URL = bereq.url;
279
+
280
+ # if it's part of magento...
281
+ if (bereq.url ~ "{{url_base_regex}}") {
282
+ # we handle the Vary stuff ourselves for now, we'll want to actually
283
+ # use this eventually for compatibility with downstream proxies
284
+ # TODO: only remove the User-Agent field from this if it exists
285
+ unset beresp.http.Vary;
286
+ # we pretty much always want to do this
287
+ set beresp.do_gzip = true;
288
+
289
+ if (beresp.status != 200 && beresp.status != 404) {
290
+ # pass anything that isn't a 200 or 404
291
+ set beresp.ttl = {{grace_period}}s;
292
+ set beresp.uncacheable = true;
293
+ return (deliver);
294
+ } else {
295
+ # if Magento sent us a Set-Cookie header, we'll put it somewhere
296
+ # else for now
297
+ if (beresp.http.Set-Cookie) {
298
+ set beresp.http.X-Varnish-Set-Cookie = beresp.http.Set-Cookie;
299
+ unset beresp.http.Set-Cookie;
300
+ }
301
+ # we'll set our own cache headers if we need them
302
+ unset beresp.http.Cache-Control;
303
+ unset beresp.http.Expires;
304
+ unset beresp.http.Pragma;
305
+ unset beresp.http.Cache;
306
+ unset beresp.http.Age;
307
+
308
+ if (beresp.http.X-Turpentine-Esi == "1") {
309
+ set beresp.do_esi = true;
310
+ }
311
+ if (beresp.http.X-Turpentine-Cache == "0") {
312
+ set beresp.ttl = {{grace_period}}s;
313
+ set beresp.uncacheable = true;
314
+ return (deliver);
315
+ } else {
316
+ if ({{force_cache_static}} &&
317
+ bereq.url ~ ".*\.(?:{{static_extensions}})(?=\?|&|$)") {
318
+ # it's a static asset
319
+ set beresp.ttl = {{static_ttl}}s;
320
+ set beresp.http.Cache-Control = "max-age={{static_ttl}}";
321
+ } elseif (bereq.http.X-Varnish-Esi-Method) {
322
+ # it's a ESI request
323
+ if (bereq.http.X-Varnish-Esi-Access == "private" &&
324
+ bereq.http.Cookie ~ "frontend=") {
325
+ # set this header so we can ban by session from Turpentine
326
+ set beresp.http.X-Varnish-Session = regsub(bereq.http.Cookie,
327
+ "^.*?frontend=([^;]*);*.*$", "\1");
328
+ }
329
+ if (bereq.http.X-Varnish-Esi-Method == "ajax" &&
330
+ bereq.http.X-Varnish-Esi-Access == "public") {
331
+ set beresp.http.Cache-Control = "max-age=" + regsub(
332
+ bereq.url, ".*/{{esi_ttl_param}}/(\d+)/.*", "\1");
333
+ }
334
+ set beresp.ttl = std.duration(
335
+ regsub(
336
+ bereq.url, ".*/{{esi_ttl_param}}/(\d+)/.*", "\1s"),
337
+ 300s);
338
+ if (beresp.ttl == 0s) {
339
+ # this is probably faster than bothering with 0 ttl
340
+ # cache objects
341
+ set beresp.ttl = {{grace_period}}s;
342
+ set beresp.uncacheable = true;
343
+ return (deliver);
344
+ }
345
+ } else {
346
+ {{url_ttls}}
347
+ }
348
+ }
349
+ }
350
+ # we've done what we need to, send to the client
351
+ return (deliver);
352
+ }
353
+ # else it's not part of Magento so use the default Varnish handling
354
+ }
355
+
356
+ sub vcl_deliver {
357
+ if (req.http.X-Varnish-Faked-Session) {
358
+ # need to set the set-cookie header since we just made it out of thin air
359
+ {{generate_session_expires}}
360
+ set resp.http.Set-Cookie = req.http.X-Varnish-Faked-Session +
361
+ "; expires=" + resp.http.X-Varnish-Cookie-Expires + "; path=/";
362
+ if (req.http.Host) {
363
+ if (req.http.User-Agent ~ "^(?:{{crawler_user_agent_regex}})$") {
364
+ # it's a crawler, no need to share cookies
365
+ set resp.http.Set-Cookie = resp.http.Set-Cookie +
366
+ "; domain=" + regsub(req.http.Host, ":\d+$", "");
367
+ } else {
368
+ # it's a real user, allow sharing of cookies between stores
369
+ if(req.http.Host ~ "{{normalize_cookie_regex}}") {
370
+ set resp.http.Set-Cookie = resp.http.Set-Cookie +
371
+ "; domain={{normalize_cookie_target}}";
372
+ } else {
373
+ set resp.http.Set-Cookie = resp.http.Set-Cookie +
374
+ "; domain=" + regsub(req.http.Host, ":\d+$", "");
375
+ }
376
+ }
377
+ }
378
+ set resp.http.Set-Cookie = resp.http.Set-Cookie + "; httponly";
379
+ unset resp.http.X-Varnish-Cookie-Expires;
380
+ }
381
+ if (req.http.X-Varnish-Esi-Method == "ajax" && req.http.X-Varnish-Esi-Access == "private") {
382
+ set resp.http.Cache-Control = "no-cache";
383
+ }
384
+ if ({{debug_headers}} || client.ip ~ debug_acl) {
385
+ # debugging is on, give some extra info
386
+ set resp.http.X-Varnish-Hits = obj.hits;
387
+ set resp.http.X-Varnish-Esi-Method = req.http.X-Varnish-Esi-Method;
388
+ set resp.http.X-Varnish-Esi-Access = req.http.X-Varnish-Esi-Access;
389
+ set resp.http.X-Varnish-Currency = req.http.X-Varnish-Currency;
390
+ set resp.http.X-Varnish-Store = req.http.X-Varnish-Store;
391
+ } else {
392
+ # remove Varnish fingerprints
393
+ unset resp.http.X-Varnish;
394
+ unset resp.http.Via;
395
+ unset resp.http.X-Powered-By;
396
+ unset resp.http.Server;
397
+ unset resp.http.X-Turpentine-Cache;
398
+ unset resp.http.X-Turpentine-Esi;
399
+ unset resp.http.X-Turpentine-Flush-Events;
400
+ unset resp.http.X-Turpentine-Block;
401
+ unset resp.http.X-Varnish-Session;
402
+ unset resp.http.X-Varnish-Host;
403
+ unset resp.http.X-Varnish-URL;
404
+ # this header indicates the session that originally generated a cached
405
+ # page. it *must* not be sent to a client in production with lax
406
+ # session validation or that session can be hijacked
407
+ unset resp.http.X-Varnish-Set-Cookie;
408
+ }
409
+ }
app/design/frontend/base/default/layout/turpentine_esi.xml CHANGED
@@ -88,6 +88,8 @@
88
  <access>private</access>
89
  <flush_events>
90
  <catalog_product_compare_add_product/>
 
 
91
  </flush_events>
92
  </params>
93
  </action>
@@ -240,6 +242,22 @@
240
  <turpentine_cache_flag value="0"/>
241
  </checkout_onepage_progress>
242
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
243
  <checkout_onepage_paymentmethod>
244
  <turpentine_cache_flag value="0"/>
245
  </checkout_onepage_paymentmethod>
88
  <access>private</access>
89
  <flush_events>
90
  <catalog_product_compare_add_product/>
91
+ <catalog_product_compare_remove_product/>
92
+ <catalog_product_compare_item_collection_clear/>
93
  </flush_events>
94
  </params>
95
  </action>
242
  <turpentine_cache_flag value="0"/>
243
  </checkout_onepage_progress>
244
 
245
+ <checkout_onepage_progress_billing>
246
+ <turpentine_cache_flag value="0"/>
247
+ </checkout_onepage_progress_billing>
248
+
249
+ <checkout_onepage_progress_shipping>
250
+ <turpentine_cache_flag value="0"/>
251
+ </checkout_onepage_progress_shipping>
252
+
253
+ <checkout_onepage_progress_shipping_method>
254
+ <turpentine_cache_flag value="0"/>
255
+ </checkout_onepage_progress_shipping_method>
256
+
257
+ <checkout_onepage_progress_payment>
258
+ <turpentine_cache_flag value="0"/>
259
+ </checkout_onepage_progress_payment>
260
+
261
  <checkout_onepage_paymentmethod>
262
  <turpentine_cache_flag value="0"/>
263
  </checkout_onepage_paymentmethod>
app/design/frontend/base/default/template/turpentine/ajax.phtml CHANGED
@@ -32,6 +32,9 @@ if( $debugEnabled ) {
32
  * be an issue we'll have to go back to using Ajax.Request so the container
33
  * block is completely replaced which means no nice appear effect.
34
  *
 
 
 
35
  * @link http://prototypejs.org/doc/latest/ajax/index.html
36
  * @link http://prototypejs.org/doc/latest/ajax/Ajax/Request/index.html
37
  * @link http://prototypejs.org/doc/latest/dom/Element/replace/index.html
@@ -47,30 +50,34 @@ echo <<<HTML
47
  <script type="text/javascript">
48
  (function() {
49
  var blockTag = {$this->helper('core')->jsonEncode($blockTag)}, esiUrl = {$this->helper('core')->jsonEncode($this->getEsiUrl())};
50
- if (typeof Ajax === 'object' && typeof Ajax.Updater === 'function') {
51
- new Ajax.Updater(
52
- blockTag,
53
- esiUrl,
54
- {
55
- method: "get",
56
- evalScripts: true,
57
- {$_prototypeFunction}: function() {
58
- $(blockTag).appear({
59
- duration: 0.3
60
- });
 
 
61
  }
62
- }
63
- );
64
  } else if (typeof jQuery === 'function') {
65
- jQuery.ajax(
66
- {
67
- url: esiUrl,
68
- type: "get",
69
- dataType: "html"
70
- }
71
- ).{$_jQueryFunction}(function() {
72
- $(blockTag).fadeIn(300);
73
- });
 
 
74
  }
75
  })();
76
  </script>
32
  * be an issue we'll have to go back to using Ajax.Request so the container
33
  * block is completely replaced which means no nice appear effect.
34
  *
35
+ * The 10 ms delay after page load is to make sure the Ajax call is
36
+ * executed async so it does not delay DOMContentLoaded. Better for Google.
37
+ *
38
  * @link http://prototypejs.org/doc/latest/ajax/index.html
39
  * @link http://prototypejs.org/doc/latest/ajax/Ajax/Request/index.html
40
  * @link http://prototypejs.org/doc/latest/dom/Element/replace/index.html
50
  <script type="text/javascript">
51
  (function() {
52
  var blockTag = {$this->helper('core')->jsonEncode($blockTag)}, esiUrl = {$this->helper('core')->jsonEncode($this->getEsiUrl())};
53
+ if (typeof Ajax === 'object' && typeof Ajax.Updater === 'function' && typeof Event === 'function' ) {
54
+ Event.observe( window, "load", function() { setTimeout( function() {
55
+ new Ajax.Updater(
56
+ blockTag,
57
+ esiUrl,
58
+ {
59
+ method: "get",
60
+ evalScripts: true,
61
+ {$_prototypeFunction}: function() {
62
+ $(blockTag).appear({
63
+ duration: 0.3
64
+ });
65
+ }
66
  }
67
+ );
68
+ }, 10 ); } );
69
  } else if (typeof jQuery === 'function') {
70
+ jQuery(document).ready( function() { setTimeout( function() {
71
+ jQuery.ajax(
72
+ {
73
+ url: esiUrl,
74
+ type: "get",
75
+ dataType: "html"
76
+ }
77
+ ).{$_jQueryFunction}(function(data) {
78
+ jQuery('#'+blockTag).html(data).fadeIn(300);
79
+ });
80
+ }, 10 ); } );
81
  }
82
  })();
83
  </script>
package.xml CHANGED
@@ -1,2 +1,2 @@
1
  <?xml version='1.0' encoding='utf-8'?>
2
- <package><name>Nexcessnet_Turpentine</name><license uri="http://opensource.org/licenses/GPL-2.0">GPLv2</license><notes>Supports Magento v1.6 and later</notes><time>12:45:26</time><__packager>build_package.py v0.0.3</__packager><summary>Improves Magento support for Varnish caching and generates 2.1 and 3.0 compatible VCLs.</summary><stability>stable</stability><__commit_hash>feec575367627438a6c70ce7c457d09dddcf8d4d</__commit_hash><version>0.6.4</version><extends /><contents><target name="magedesign"><dir name="adminhtml"><dir name="default"><dir name="default"><dir name="layout"><file hash="a0bd4a5632b369b058c0ec5262e0cc49" name="turpentine.xml" /></dir><dir name="template"><dir name="turpentine"><file hash="b564606032d111537d02c8da63470c39" name="varnish_management.phtml" /></dir></dir></dir></dir></dir><dir name="frontend"><dir name="base"><dir name="default"><dir name="layout"><file hash="7b6eab8bd2e7528eafb647c3e2ba8634" name="turpentine_esi.xml" /></dir><dir name="template"><dir name="turpentine"><file hash="50798888953fd1550e4347c39e395d0a" name="notices.phtml" /><file hash="b268c48251ccfccf5c775d3e85513584" name="esi.phtml" /><file hash="252356c9ea115fca63e52d54f67d755f" name="ajax.phtml" /></dir></dir></dir></dir></dir></target><target name="mageetc"><dir name="modules"><file hash="58848d4d90973bfd63b466ea181352a5" name="Nexcessnet_Turpentine.xml" /></dir></target><target name="magecommunity"><dir name="Nexcessnet"><dir name="Turpentine"><dir name="Helper"><file hash="a7d1c51e24f9d35373fc8533871120a3" name="Esi.php" /><file hash="802e269b0c80131efbb070309fdc610f" name="Varnish.php" /><file hash="913d0762f9df7696f1217f82791f1b78" name="Cron.php" /><file hash="0ee525f0fba5236f05ad2289fe2f2292" name="Data.php" /><file hash="6b637be4eac4c924fc1f02b2d49699c3" name="Ban.php" /><file hash="4a448ad2fe5b5a253a37d3f4aa3dd1bb" name="Debug.php" /></dir><dir name="misc"><file hash="7c24835522ec526d212ea98add1ceb2a" name="version-3.vcl" /><file hash="ba5d5c7263cd90eea3785953e3549041" name="uuid.c" /><file hash="6298eb180a1ae61a79b0cf929be61144" name="version-2.vcl" /></dir><dir name="etc"><file hash="6dd44a194829f6e28daa977efe324f22" name="system.xml" /><file hash="3b608fbcca3d307833d10604dff23966" name="cache.xml" /><file hash="c1dc6245f39fbc925169dae62571e526" name="config.xml" /></dir><dir name="controllers"><file hash="3446129075986c4143e9d74d5154cf64" name="EsiController.php" /><dir name="Adminhtml"><file hash="fb44492ff908e0dd28a4fa62e382bd3e" name="CacheController.php" /></dir><dir name="Varnish"><file hash="625118bfe342139b7fd9464c05d1b0a6" name="ManagementController.php" /></dir></dir><dir name="Model"><file hash="c2cb79001524617febbfddf099d09f37" name="Session.php" /><dir name="Shim"><dir name="Mage"><dir name="Core"><file hash="9e5d87f0aa84c9fb1541db83aba69abd" name="Config.php" /><file hash="821bff6c2fb372e3ffb39abf6453b3f8" name="Layout.php" /><file hash="4a1aa246373520936f0e4b5b3a3baf25" name="App.php" /></dir></dir></dir><dir name="PageCache"><dir name="Container"><file hash="139e8a9bfa209316036e798fff654a8a" name="Notices.php" /></dir></dir><dir name="Dummy"><file hash="f6611808da53ffa00561a8f76b26016e" name="Request.php" /></dir><dir name="Varnish"><file hash="6c1a8e5e3f412bff082c6df136e5db1a" name="Admin.php" /><dir name="Admin"><file hash="c3d44d59ece358553d2cfa8f92964d39" name="Socket.php" /></dir><dir name="Configurator"><file hash="b831b872fcb05d9c723149159db0eed1" name="Version2.php" /><file hash="82d0abe0123272e59e6c319dfdd4e9dc" name="Version3.php" /><file hash="fd99025d6f79c2a2dfe5a910099b6ac6" name="Abstract.php~" /><file hash="d63b4714180cb963d81d32a3fa31e95e" name="Abstract.php" /></dir></dir><dir name="Observer"><file hash="4d97c660f6ad74162f842d5d2bfa53d7" name="Esi.php" /><file hash="7244a8ce600e980d612409595b9b6b9b" name="Varnish.php" /><file hash="a34e79218e8ca1fefad303b9399bda9d" name="Cron.php" /><file hash="5b6c57ab373444fcac7a42262f8178d5" name="Ban.php" /><file hash="9d57fad69ff42b71c66ca26bc3372317" name="Debug.php" /></dir><dir name="Core"><file hash="d4f63abc6d34c923c6e64a522b6fc36e" name="Session.php" /></dir><dir name="Config"><dir name="Select"><file hash="2e01b14592189b3f6a8a05be5ef4c69c" name="StripWhitespace.php" /><file hash="dc472f34c25b1688cfa9fa206958c536" name="Version.php" /><file hash="9348c5e58037fd97d89b84ccab4ef2d0" name="Toggle.php" /></dir></dir></dir><dir name="Block"><file hash="e9b03d651a8da9b1d32c4fd2f4781792" name="Management.php" /><file hash="390cf75d04b1b098cad562229b649c2d" name="Notices.php" /><dir name="Adminhtml"><dir name="Cache"><file hash="798cf7afa80e0a06be2b8c6cb2bef02b" name="Grid.php" /></dir></dir><dir name="Catalog"><dir name="Product"><dir name="List"><file hash="ce9fca4c273987759f284fe31c1597f5" name="Toolbar.php" /></dir></dir></dir><dir name="Core"><file hash="f9b035bb701943aa12755abdb029fa8f" name="Messages.php" /></dir><dir name="Poll"><file hash="bf9ca23a445776435e38e6c8be9976ea" name="ActivePoll.php" /></dir></dir></dir></dir></target></contents><dependencies><required><php><min>5.2.13</min><max>6.0.0</max></php></required></dependencies><authors><author><name>Chris Wells</name><user>nexcess_net</user><email>clwells@nexcess.net</email></author><author><name>Alex Headley</name><user>aheadley_nex</user><email>aheadley@nexcess.net</email></author></authors><date>2015-08-04</date><compatibile /><channel>community</channel><description>Turpentine is a Magento extension to improve Magento's compatibility with Varnish, a very-fast caching reverse-proxy. By default, Varnish doesn't cache requests with cookies and Magento sends the frontend cookie with every request causing a (near) zero hit-rate for Varnish's cache. Turpentine provides Varnish configuration files (VCLs) to work with Magento and modifies Magento's behaviour to significantly improve the cache hit rate.</description></package>
1
  <?xml version='1.0' encoding='utf-8'?>
2
+ <package><name>Nexcessnet_Turpentine</name><license uri="http://opensource.org/licenses/GPL-2.0">GPLv2</license><notes>Supports Magento v1.6 and later</notes><time>09:57:48</time><__packager>build_package.py v0.0.3</__packager><summary>Improves Magento support for Varnish caching and generates 2.1 and 3.0 compatible VCLs.</summary><stability>stable</stability><__commit_hash>c44ebcf355856322053b38214667f22d636c5345</__commit_hash><version>0.6.5</version><extends /><contents><target name="magedesign"><dir name="adminhtml"><dir name="default"><dir name="default"><dir name="layout"><file hash="a0bd4a5632b369b058c0ec5262e0cc49" name="turpentine.xml" /></dir><dir name="template"><dir name="turpentine"><file hash="b564606032d111537d02c8da63470c39" name="varnish_management.phtml" /></dir></dir></dir></dir></dir><dir name="frontend"><dir name="base"><dir name="default"><dir name="layout"><file hash="45405f2d1c0b5e915ffbd7da261d7ed0" name="turpentine_esi.xml" /></dir><dir name="template"><dir name="turpentine"><file hash="50798888953fd1550e4347c39e395d0a" name="notices.phtml" /><file hash="b268c48251ccfccf5c775d3e85513584" name="esi.phtml" /><file hash="02f341fdfd5194752e88cae9933cfcdb" name="ajax.phtml" /></dir></dir></dir></dir></dir></target><target name="mageetc"><dir name="modules"><file hash="58848d4d90973bfd63b466ea181352a5" name="Nexcessnet_Turpentine.xml" /></dir></target><target name="magecommunity"><dir name="Nexcessnet"><dir name="Turpentine"><dir name="Helper"><file hash="7934848bff8108cfc67e34e0571bd271" name="Esi.php" /><file hash="802e269b0c80131efbb070309fdc610f" name="Varnish.php" /><file hash="913d0762f9df7696f1217f82791f1b78" name="Cron.php" /><file hash="0ee525f0fba5236f05ad2289fe2f2292" name="Data.php" /><file hash="6b637be4eac4c924fc1f02b2d49699c3" name="Ban.php" /><file hash="4a448ad2fe5b5a253a37d3f4aa3dd1bb" name="Debug.php" /></dir><dir name="misc"><file hash="188d3de0cc3c40dfef352b7cffe60965" name="version-3.vcl" /><file hash="42f949d98347eb036ef91e7e80ea3de6" name="version-4.vcl" /><file hash="ba5d5c7263cd90eea3785953e3549041" name="uuid.c" /><file hash="cd7651be0ea4c3cc6635ce19c967145b" name="version-2.vcl" /></dir><dir name="etc"><file hash="66e868288c18f5720b6ddeb82ccd494b" name="system.xml" /><file hash="ee88bf92fea54da43f16dee2c167df5b" name="config.xml~" /><file hash="3b608fbcca3d307833d10604dff23966" name="cache.xml" /><file hash="2f1d31071be7034f6cd78083b8ac1430" name="config.xml" /></dir><dir name="controllers"><file hash="3446129075986c4143e9d74d5154cf64" name="EsiController.php" /><dir name="Adminhtml"><file hash="fb44492ff908e0dd28a4fa62e382bd3e" name="CacheController.php" /></dir><dir name="Varnish"><file hash="625118bfe342139b7fd9464c05d1b0a6" name="ManagementController.php" /></dir></dir><dir name="Model"><file hash="c2cb79001524617febbfddf099d09f37" name="Session.php" /><dir name="Shim"><dir name="Mage"><dir name="Core"><file hash="9e5d87f0aa84c9fb1541db83aba69abd" name="Config.php" /><file hash="821bff6c2fb372e3ffb39abf6453b3f8" name="Layout.php" /><file hash="4a1aa246373520936f0e4b5b3a3baf25" name="App.php" /></dir></dir></dir><dir name="PageCache"><dir name="Container"><file hash="139e8a9bfa209316036e798fff654a8a" name="Notices.php" /></dir></dir><dir name="Dummy"><file hash="f6611808da53ffa00561a8f76b26016e" name="Request.php" /></dir><dir name="Varnish"><file hash="d174c8dc29d3c4ab34ac0ee57f519d76" name="Admin.php" /><dir name="Admin"><file hash="95a2e178fd6e7a56925e7fe7d7bf9746" name="Socket.php" /></dir><dir name="Configurator"><file hash="b831b872fcb05d9c723149159db0eed1" name="Version2.php" /><file hash="82d0abe0123272e59e6c319dfdd4e9dc" name="Version3.php" /><file hash="179b9529f2eef55964d25e56b85291a7" name="Version4.php" /><file hash="3adadba3cf2fe1cbaf996cface330c7a" name="Abstract.php" /></dir></dir><dir name="Observer"><file hash="89d824842dc0194a8e29e97bbdab69ac" name="Esi.php" /><file hash="7244a8ce600e980d612409595b9b6b9b" name="Varnish.php" /><file hash="a34e79218e8ca1fefad303b9399bda9d" name="Cron.php" /><file hash="5b6c57ab373444fcac7a42262f8178d5" name="Ban.php" /><file hash="9d57fad69ff42b71c66ca26bc3372317" name="Debug.php" /></dir><dir name="Core"><file hash="d4f63abc6d34c923c6e64a522b6fc36e" name="Session.php" /></dir><dir name="Config"><dir name="Select"><file hash="2e01b14592189b3f6a8a05be5ef4c69c" name="StripWhitespace.php" /><file hash="15b5296a7f7bc719331f14d34308013b" name="Version.php" /><file hash="2a4648995fc87472b2ac33b35a7d69e5" name="LoadBalancing.php" /><file hash="9348c5e58037fd97d89b84ccab4ef2d0" name="Toggle.php" /></dir></dir></dir><dir name="Block"><file hash="e9b03d651a8da9b1d32c4fd2f4781792" name="Management.php" /><file hash="390cf75d04b1b098cad562229b649c2d" name="Notices.php" /><dir name="Adminhtml"><dir name="Cache"><file hash="798cf7afa80e0a06be2b8c6cb2bef02b" name="Grid.php" /></dir></dir><dir name="Catalog"><dir name="Product"><dir name="List"><file hash="ce9fca4c273987759f284fe31c1597f5" name="Toolbar.php" /></dir></dir></dir><dir name="Product"><file hash="56ac2e90d0eed7eaadaf4517c1ad77ff" name="Compared.php" /><file hash="f72d0718ccd2895cbf4fc1cbc24bf90c" name="Viewed.php" /></dir><dir name="Core"><file hash="b34cad980a3e5da9860b21a7aa7a0b0f" name="Messages.php" /></dir><dir name="Poll"><file hash="bf9ca23a445776435e38e6c8be9976ea" name="ActivePoll.php" /></dir></dir></dir></dir></target></contents><dependencies><required><php><min>5.2.13</min><max>6.0.0</max></php></required></dependencies><authors><author><name>Chris Wells</name><user>nexcess_net</user><email>clwells@nexcess.net</email></author><author><name>Alex Headley</name><user>aheadley_nex</user><email>aheadley@nexcess.net</email></author></authors><date>2015-08-27</date><compatibile /><channel>community</channel><description>Turpentine is a Magento extension to improve Magento's compatibility with Varnish, a very-fast caching reverse-proxy. By default, Varnish doesn't cache requests with cookies and Magento sends the frontend cookie with every request causing a (near) zero hit-rate for Varnish's cache. Turpentine provides Varnish configuration files (VCLs) to work with Magento and modifies Magento's behaviour to significantly improve the cache hit rate.</description></package>