A Varnish extension for Magento.

Overview

Nexcess.net Turpentine Extension for Magento

Build Status Scrutinizer

Turpentine is a full page cache extension for Magento that works 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 configures Varnish to work with Magento and modifies Magento's behaviour to significantly improve the cache hit rate.

Note that while this extension is now considered stable, it is strongly recommended that it be tested on a development/staging site before deploying on a production site due to the potential need to add custom ESI policies for blocks added by other extensions.

Features

  • Full Page Caching, with hole-punching via Varnish ESI and/or AJAX, even for logged in visitors
  • Configurable via standard Magento methods (Admin system configuration and layout XML), no manual editing of Varnish config required for most cases
  • Able to generate and apply new Varnish VCLs (configurations) on the fly, without restarting/changing Varnish's config files or flushing the cache
  • Blacklist requests from caching by URL or parameters (SID, store, etc)
  • Configure cache TTL by URL and individual block's TTL
  • Supports multiple Varnish instances for clustered usage
  • Automatic cache clearing on actions (clearing product/catalog/cms page after saving)
  • Supports non-root Magento installs (i.e. putting Magento in /store/ instead of /) and multi-store/multi-site setups
  • Support for site-crawlers for cache warming, and includes a (basic) built-in site-crawler
  • SSL support through Pound or Nginx

Requirements

  • Magento Community Edition 1.6+ or Magento Enterprise Edition 1.11+
  • Varnish 2.1+ (including 3.0+)

Installation & Usage

See the Installation and Usage pages.

Support

If you have an issue, please read the FAQ then if you still need help, open a bug report in GitHub's issue tracker.

Please do not use Magento Connect's Reviews or (especially) the Q&A for support. There isn't a way for me to reply to reviews and the Q&A moderation is very slow.

Contributing

If you have a fix or feature for Turpentine, submit a pull request through GitHub to the devel branch. The master branch is only for stable releases. Please make sure the new code follows the same style and conventions as already written code.

How it works

The extension works in two parts, page caching and block (ESI/AJAX) caching. A simplified look at how they work:

For pages, Varnish first checks whether the visitor sent a frontend cookie. If they didn't, then Varnish will generate a new session token for them. The page is then served from cache (or fetched from the backend if it's not already in the cache), with any blocks with ESI polices filled in via ESI. Note that the cookie checking is bypassed for clients identified as crawlers (see the Crawler IP Addresses and Crawler User Agents settings).

For blocks, the extension listens for the core_block_abstract_to_html_before event in Magento. When this event is triggered, the extension looks at the block attached to it and if an ESI policy has been defined for the block then the block's template is replaced with a simple ESI (or AJAX) template that tells Varnish to pull the block content from a separate URL. Varnish then does another request to that URL to get the content for that block, which can be cached separately from the page and may differ between different visitors/clients.

Notes and Caveats

  • Turpentine will not help (directly) with the speed of "actions" like adding things to the cart or checking out. It only caches, so it can only speed up page load speed for site browsing. It will remove a lot of load on the backend though so for heavily loaded sites it can free up enough backend resources to have a noticeable effect on "actions".
  • There are some technical limitations when using Varnish 2.1.x: External ESI requests are not blocked, and per-block TTLs in ESI policies are not honored (all blocks use the default TTL)
  • The core parts of Turpentine (caching and ESI/AJAX injection) work under Magento CE 1.5, but a significant portion of the auxiliary functionality doesn't work due to changes to event names. That said, it would be possible to use Turpentine with Magento CE 1.5 with an understanding that it is not supported and what actions need to be taken manually. Both cache flushing (both automatic an manual) and cache warming (due to missing events that trigger the cache flushing) do not work.
  • Anonymous blocks are not able to be hole-punched. For CMS pages, it is recommended that you include the block in the page's layout updates XML and give it a name, then it can have an ESI policy like normal

Known Issues

  • Logging and statistics will show all requests as coming from the same IP address (usually localhost/127.0.0.1). It should be possible to work around this using Apache's mod_remoteip or mod_rpaf.

Demo

See the Demo Sites wiki page.

If you use Turpentine (on a production site), feel free to add your site to the list!

License

The code is licensed under GPLv2+, much of the ESI-specific code is taken from Hugues Alary's Magento-Varnish extension, which is licensed as GPLv3.

Comments
  • Mage 1.8  - Add to Cart not working, Please help

    Mage 1.8 - Add to Cart not working, Please help

    Hello,

    At the outset, I will like to thank your team for a wonderful extension for caching Magento.

    I recently upgraded my install from 1.7 to 1.8 CE. After upgrade, when I add an item to a cart, the cart is empty.

    I have checked cookies - the cookie domain, path etc. are ok. Occassionaly I see that while switching between cached pages, the cookie frontend is available but path, domain etc. are blank.

    Can you please guide me how to resolve this problem? It is slightly urgent because I had to disable cache because cart stopped working.

    Regards,

    Akhil

    bug 
    opened by akh2013 103
  • Admin error with 1.9.3

    Admin error with 1.9.3

    Hello.

    I'm using Turpentine 0.6.6. I've just upgraded to Magento 1.9.3. I didn't do the SUPEE-7405 patch, I did a complete upgrade from 1.9.2 to 1.9.3. I can't get past the admin login screen. I'm getting the following error.

    Any advice would be greatly appreciated. Thanks in advance.

    a:5:{i:0;s:112:"Invalid method Nexcessnet_Turpentine_Model_Core_Session::validateFormKey(Array
    (
        [0] => HMsmqBAn5dm2gPuV
    )
    )";i:1;s:1930:"#0 /home/XXXX/domains/XXXX/app/code/core/Mage/Admin/Model/Observer.php(73): Varien_Object->__call('validateFormKey', Array)
    #1 /home/XXXX/domains/XXXX/app/code/core/Mage/Admin/Model/Observer.php(73): Nexcessnet_Turpentine_Model_Core_Session->validateFormKey('HMsmqBAn5dm2gPu...')
    #2 /home/XXXX/domains/XXXX/app/code/core/Mage/Core/Model/App.php(1358): Mage_Admin_Model_Observer->actionPreDispatchAdmin(Object(Varien_Event_Observer))
    #3 /home/XXXX/domains/XXXX/app/code/core/Mage/Core/Model/App.php(1337): Mage_Core_Model_App->_callObserverMethod(Object(Mage_Admin_Model_Observer), 'actionPreDispat...', Object(Varien_Event_Observer))
    #4 /home/XXXX/domains/XXXX/app/Mage.php(448): Mage_Core_Model_App->dispatchEvent('controller_acti...', Array)
    #5 /home/XXXX/domains/XXXX/app/code/core/Mage/Core/Controller/Varien/Action.php(527): Mage::dispatchEvent('controller_acti...', Array)
    #6 /home/XXXX/domains/XXXX/app/code/core/Mage/Adminhtml/Controller/Action.php(160): Mage_Core_Controller_Varien_Action->preDispatch()
    #7 /home/XXXX/domains/XXXX/app/code/core/Mage/Core/Controller/Varien/Action.php(407): Mage_Adminhtml_Controller_Action->preDispatch()
    #8 /home/XXXX/domains/XXXX/app/code/core/Mage/Core/Controller/Varien/Router/Standard.php(254): Mage_Core_Controller_Varien_Action->dispatch('index')
    #9 /home/XXXX/domains/XXXX/app/code/core/Mage/Core/Controller/Varien/Front.php(172): Mage_Core_Controller_Varien_Router_Standard->match(Object(Mage_Core_Controller_Request_Http))
    #10 /home/XXXX/domains/XXXX/app/code/core/Mage/Core/Model/App.php(365): Mage_Core_Controller_Varien_Front->dispatch()
    #11 /home/XXXX/domains/XXXX/app/Mage.php(684): Mage_Core_Model_App->run(Array)
    #12 /home/XXXX/domains/XXXX/index.php(83): Mage::run('', 'store')
    #13 {main}";s:3:"url";s:6:"/admin";s:11:"script_name";s:10:"/index.php";s:4:"skin";s:5:"admin";}
    
    
    question 
    opened by studio2f 54
  • Product remains in shopping cart after cancelling an order

    Product remains in shopping cart after cancelling an order

    Hi,

    let me say at first, we love Turpentine! :) It's really great and only true Varnish extension for Magento, It works out of the box. We are pretty satisfied and impressed with early results. We're getting in average 80-90% Hitrate avg.

    However, we're experiencing one strange behaviour with Turpentine and would like to kindly ask you for any suggestions on how to resolve this. By default, cancelling an order in magento returns a customer to Magento page saying 'no products in your cart/empty shopping cart'. After allowing Turpentine and applying VCL configuration to Varnish, these things changed. Cancelling an order redirects customer back to shopping cart, which includes previously cancelled products. The other things > these products cant be removed from cart by clicking on Remove button. And, browsing to any other sub-page/home page of magento shows that there isn't any product in the cart. Visiting a cart again shows that there is previously un-removable product. It seems to us like the shopping cart remains fully cached, and doesn't refresh by cancelling an order.

    We weren't able to find other solution to this strange behaviour, than stopping Varnish and return to default magento caching. But...everything is always back to normal, when other product is added to the cart. It replaces the one that can't be removed, and actually, this new one could be easily removed and everything is back to normal easily.

    Any ideas about this one? :)) Thank you for any info or help, we use Turpentine in our production live site, because it's really great.

    You can see and replicate the problem easily here, if you're interested: http://goo.gl/Dy2g6 We're using Magento 1.6.1.0, Varnish 3.0.1, Fooman Speedster for minifying CSS & JS. Average load-time: 1.4s

    Thank you. Kind regards, Tomas

    opened by Krajcikt 48
  • Possible to use with Multiple Magento Sites?

    Possible to use with Multiple Magento Sites?

    Hi, I am anxiously wanting to get your extension working on our server. My question before I got too deep is. On our VPC we have several magento stores that we would like to take advantage of using varnish. Is there something special we need to do to allow all of the magento installs to work properly? Or is there a special setup? Please advise.

    question unresolved 
    opened by danielc1234 39
  • Ugly issue - Online Customers section in Admin is compromised

    Ugly issue - Online Customers section in Admin is compromised

    Go to Backend and from [Customers] menu choose [Online Customers]. Watch URL column, it is compromised as information. 24 records all with turpentine in url for the same ip. After a while and some refreshes it will remain only one URL, also with turpentine text in URL. Here is an example from my test localhost:

    http://192.168.159.131/turpentine/esi/getBlock/method/esi/access/public/ttl/3600/hmac/c2b8547cb6feec581e62213af326e05c9ad9c057716ea153892b5ce5664a84d2/data/ahlJpOZh6So05ByE.Xp2gC98.HR.9i7FudWMsOQbmfqEGZscaOmtlZuMhmY17YS9fpF7qcIyd9NiK6XFfp587nqAwVnJXt

    As this URL is you cannot understand anything a visitor is doing inside the website.

    unconfirmed-bug 
    opened by ADDISON74 35
  • turpentine not caching?

    turpentine not caching?

    Is varnish-turpentine not caching product pages in Magento?

    We tested a product page for varnish-turpentine in gtmetrix and this is the result: http://gtmetrix.com/reports/www.trendsndeals.com/70jkcCPY

    Please see under Timeline, the time to first byte is 5.37s (long time).

    We checked by running varnishlog that it is configured correctly and that website is going through varnish.

    comparatively, and curiously, all other pages in magento website loads fast (low time to first byte), such as the main page: http://gtmetrix.com/reports/www.trendsndeals.com/HvyBs0pq

    it seems the issue is only in the product pages. is varnish-turpentine not caching product pages?

    please advice. thanks!

    support 
    opened by nomadph 34
  • Using Magento CE 1.7  There has been an error processing your request

    Using Magento CE 1.7 There has been an error processing your request

    Got this error after installing Magento-Turpentine. I can't find anyway to debug it, any help please? Error report thrown:

    There has been an error processing your request
    
    Mage registry key "_singleton/turpentine/observer_esi" already exists
    
    Trace:
    #0 /home/magentoman/www/pondicherie.net/app/Mage.php(222): Mage::throwException('Mage registry k...')
    #1 /home/magentoman/www/pondicherie.net/app/Mage.php(476): Mage::register('_singleton/turp...', false)
    #2 /home/magentoman/www/pondicherie.net/includes/src/__default.php(20995): Mage::getSingleton('turpentine/obse...')
    #3 /home/magentoman/www/pondicherie.net/app/Mage.php(447): Mage_Core_Model_App->dispatchEvent('controller_fron...', Array)
    #4 /home/magentoman/www/pondicherie.net/includes/src/__default.php(17408): Mage::dispatchEvent('controller_fron...', Array)
    #5 /home/magentoman/www/pondicherie.net/includes/src/__default.php(20428): Mage_Core_Controller_Varien_Front->init()
    #6 /home/magentoman/www/pondicherie.net/includes/src/__default.php(20773): Mage_Core_Model_App->_initFrontController()
    #7 /home/magentoman/www/pondicherie.net/includes/src/__default.php(20033): Mage_Core_Model_App->getFrontController()
    #8 /home/magentoman/www/pondicherie.net/app/Mage.php(683): Mage_Core_Model_App->run(Array)
    #9 /home/magentoman/www/pondicherie.net/index.php(87): Mage::run('', 'store')
    #10 {main}
    
    support 
    opened by maurisource 33
  • The famous <ul id=MESSAGE HERE
">

The famous
    MESSAGE HERE

I have Magento 1.9.1 and Turpentine 0.6.5, with Ultimo Theme.

And I have the same issue as some people had #112 #153. But that issues are from 2013, I don't believe they are not fixed yet.

When I post a review I get

<ul id="admin_messages">MESSAGE HERE</ul>

Is there any way to fix this? I don't have that error if I disable Turpentine.

My turpentine_esi.xml looks like

 <reference name="global_messages">
            <action method="setEsiOptions">
                <params>
                <method>esi</method>
                    <access>private</access>
                    <flush_events>
                        <core_session_abstract_add_message/>
                    </flush_events>
                </params>
            </action>
        </reference>
    <reference name="messages">
            <action method="setEsiOptions">
                <params>
                <method>esi</method>
                <access>private</access>
                    <flush_events>
                        <core_session_abstract_add_message/>
                    </flush_events>
                </params>
            </action>
        </reference>

Any help will be really appretiated, I'm getting crazy with this.

unconfirmed-bug support 
opened by elfeffe 32
  • some users can't login, but some can

    some users can't login, but some can

    Hi,

    When I enable varnish-turpentine, some users complain that they suddenly can't login to their existing account on our magento store, while others have no problem logging in at all.

    I've tried flushing magento cache, and flush cache storage, but same problem persist.

    The users that can't login say that when they enter their login email and password and clicks the submit button, the login page just reloads itself (no error or anything).

    When we turn off varnish-turpentine, all is well and no customers complain about not being able to login. Please advice on where to look or if we're missing something.

    unconfirmed-bug 
    opened by nomadph 32
  • Errors in admin area

    Errors in admin area

    I have some bugs in admin area. In System > Varnish Management don't work functions. No one.

    After click on any button, I'm redirecting to Magento error page:

    "There has been an error processing your request Exception printing is disabled by default for security reasons.

    Error log record number: 837656914520"

    Inf file:

    a:5:{i:0;s:106:"Got unexpected response code from Varnish: 107
    <removed>
    
    Authentication required.
    ";i:1;s:2565:"#0 /magento/app/code/community/Nexcessnet/Turpentine/Model/Varnish/Admin/Socket.php(406): Mage::throwException('Got unexpected ...')
    #1 PATHTOMAGENTO/magento/app/code/community/Nexcessnet/Turpentine/Model/Varnish/Admin/Socket.php(299): Nexcessnet_Turpentine_Model_Varnish_Admin_Socket->_command('auth', 200, '9629ca4046e3c5c...')
    #2 PATHTOMAGENTO/magento/app/code/community/Nexcessnet/Turpentine/Model/Varnish/Admin/Socket.php(329): Nexcessnet_Turpentine_Model_Varnish_Admin_Socket->_connect()
    #3 PATHTOMAGENTO/magento/app/code/community/Nexcessnet/Turpentine/Model/Varnish/Admin/Socket.php(440): Nexcessnet_Turpentine_Model_Varnish_Admin_Socket->_write('help')
    #4 PATHTOMAGENTO/magento/app/code/community/Nexcessnet/Turpentine/Model/Varnish/Admin/Socket.php(226): Nexcessnet_Turpentine_Model_Varnish_Admin_Socket->_determineVersion()
    #5 PATHTOMAGENTO/magento/app/code/community/Nexcessnet/Turpentine/Model/Varnish/Admin.php(135): Nexcessnet_Turpentine_Model_Varnish_Admin_Socket->getVersion()
    #6 PATHTOMAGENTO/magento/app/code/community/Nexcessnet/Turpentine/Model/Varnish/Admin.php(44): Nexcessnet_Turpentine_Model_Varnish_Admin->getConfigurator()
    #7 PATHTOMAGENTO/magento/app/code/community/Nexcessnet/Turpentine/Model/Varnish/Admin.php(33): Nexcessnet_Turpentine_Model_Varnish_Admin->flushUrl('.*')
    #8 PATHTOMAGENTO/magento/app/code/community/Nexcessnet/Turpentine/controllers/Varnish/ManagementController.php(48): Nexcessnet_Turpentine_Model_Varnish_Admin->flushAll()
    #9 PATHTOMAGENTO/magento/app/code/core/Mage/Core/Controller/Varien/Action.php(419): Nexcessnet_Turpentine_Varnish_ManagementController->flushAllAction()
    #10 PATHTOMAGENTO/magento/app/code/core/Mage/Core/Controller/Varien/Router/Standard.php(250): Mage_Core_Controller_Varien_Action->dispatch('flushAll')
    #11 PATHTOMAGENTO/magento/app/code/core/Mage/Core/Controller/Varien/Front.php(176): Mage_Core_Controller_Varien_Router_Standard->match(Object(Mage_Core_Controller_Request_Http))
    #12 PATHTOMAGENTO/magento/app/code/core/Mage/Core/Model/App.php(354): Mage_Core_Controller_Varien_Front->dispatch()
    #13 PATHTOMAGENTO/magento/app/Mage.php(683): Mage_Core_Model_App->run(Array)
    #14 PATHTOMAGENTO/magento/index.php(87): Mage::run('', 'store')
    #15 {main}";s:3:"url";s:90:"/magento/index.php/admin/varnish_management/flushAll/key/<removed>/";s:11:"script_name";s:18:"/magento/index.php";s:4:"skin";s:5:"admin";}
    
    question 
    opened by Springerton 31
  • Varnish Turpentine: Slow cart, AJAX, Add to cart (nginx/ssl)

    Varnish Turpentine: Slow cart, AJAX, Add to cart (nginx/ssl)

    I've seen a high number of issues on Github, however unresolved... Or after a while just closed due to lack of feedback: #345

    I'm trying to implement a varnish / turpentine configuration. Problem: New session user tries to add item to cart. Adding the item to the cart however takes very long.

    add-to-cart

    This is the HTTP response for a add to cart:

    Request URL:https://testing.two-store.be/ajaxcart/index/add/uenc/aHR0cHM6Ly90ZXN0aW5nLnR3by1zdG9yZS5iZS9wYW50cy1hbmQtdHJvdXNlcnMtZGlhcmEuaHRtbD9fX19TSUQ9VQ,,/product/4021/form_key/4Z3KMfgvpJFprFtN/
    Request Method:POST
    Status Code:200 
    Remote Address:77.243.239.145:443
    Referrer Policy:no-referrer-when-downgrade
    Response Headers
    cache-control:no-store, no-cache, must-revalidate, post-check=0, pre-check=0
    content-encoding:gzip
    content-length:13302
    content-type:text/html; charset=UTF-8
    date:Wed, 24 May 2017 11:42:37 GMT
    expires:Thu, 19 Nov 1981 08:52:00 GMT
    pragma:no-cache
    server:Apache
    set-cookie:frontend=bsu31mrtajqdu3lr4q9ocjdaf3; expires=Wed, 24-May-2017 12:42:36 GMT; Max-Age=3600; path=/; domain=testing.two-store.be; httponly
    status:200
    strict-transport-security:max-age=15768000
    vary:Accept-Encoding
    x-frame-options:SAMEORIGIN
    x
    -powered-by:PHP/5.5.38-4+deb.sury.org~xenial+1
    Request Headers
    :authority:testing.two-store.be
    :method:POST
    :path:/ajaxcart/index/add/uenc/aHR0cHM6Ly90ZXN0aW5nLnR3by1zdG9yZS5iZS9wYW50cy1hbmQtdHJvdXNlcnMtZGlhcmEuaHRtbD9fX19TSUQ9VQ,,/product/4021/form_key/4Z3KMfgvpJFprFtN/
    :scheme:https
    accept:application/json, text/javascript, */*; q=0.01
    accept-encoding:gzip, deflate, br
    accept-language:nl,en-US;q=0.8,en;q=0.6,fr;q=0.4
    content-length:73
    content-type:application/x-www-form-urlencoded; charset=UTF-8
    cookie:email=none; external_no_cache=1; frontend=bsu31mrtajqdu3lr4q9ocjdaf3; frontend_cid=tKytwVtDVUpb26Eo
    dnt:1
    origin:https://testing.two-store.be
    referer:https://testing.two-store.be/pants-and-trousers-diara.html
    user-agent:Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.96 Safari/537.36
    x-requested-with:XMLHttpRequest
    Form Data
    view source
    view URL encoded
    product:4021
    related_product:
    super_attribute[172]:114
    qty:1
    isAjax:1
    

    This is the HTTP response for a normal product page:

    Request URL:https://testing.two-store.be/pants-and-trousers-diara.html
    Request Method:GET
    Status Code:200 
    Remote Address:77.243.239.145:443
    Referrer Policy:no-referrer-when-downgrade
    Response Headers
    accept-ranges:bytes
    age:15
    content-encoding:gzip
    content-type:text/html; charset=UTF-8
    date:Wed, 24 May 2017 11:04:44 GMT
    server:Apache
    status:200
    strict-transport-security:max-age=15768000
    vary:Accept-Encoding
    via:1.1 varnish-v4
    x-frame-options:SAMEORIGIN
    x-powered-by:PHP/5.5.38-4+deb.sury.org~xenial+1
    x-turpentine-cache:1
    x-turpentine-esi:1
    x-varnish:360706 327856
    x-varnish-currency:
    x-varnish-esi-access:
    x-varnish-esi-method:
    x-varnish-hits:2
    x-varnish-host:testing.two-store.be
    x-varnish-set-cookie:frontend=pg1mrqdphdhf0kek2v8o966a84; expires=Wed, 24-May-2017 12:04:28 GMT; Max-Age=3600; path=/; domain=testing.two-store.be; httponly
    x-varnish-store:
    x-varnish-url:/pants-and-trousers-diara.html
    Request Headers
    :authority:testing.two-store.be
    :method:GET
    :path:/pants-and-trousers-diara.html
    :scheme:https
    accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
    accept-encoding:gzip, deflate, sdch, br
    accept-language:nl,en-US;q=0.8,en;q=0.6,fr;q=0.4
    cache-control:max-age=0
    cookie:frontend_cid=skjrpXgfQD1XrNjS; email=none; external_no_cache=1; frontend=pg1mrqdphdhf0kek2v8o966a84
    dnt:1
    referer:https://testing.two-store.be/ladies-8.html?___SID=U
    upgrade-insecure-requests:1
    user-agent:Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.96 Safari/537.36
    

    This is the setup: testing.two-store.be

    Magento version 1.9.1.1 Theme: BEWEAR One Theme

    Configuration file:

    /etc/varnish/default.vcl
    
    backend othello {
        .host = "127.0.0.1";
        .port = "80";
    }
    backend othellotesting {
        .host = "127.0.0.1";
        .port = "81";
    }
    backend pakjes {
        .host = "127.0.0.1";
        .port = "82";
    }
    backend othellotesting2 {
        .host = "127.0.0.1";
        .port = "83";
    }
    backend twostoretesting {
        .host = "127.0.0.1";
        .port = "84";
    }
    backend lookbook {
        .host = "127.0.0.1";
        .port = "85";
    }
    backend twostore {
        .host = "127.0.0.1";
        .port = "86";
    }
    sub vcl_recv { if (std.port(server.ip) == 7080) {
            set req.backend_hint = othello;
    }
    elsif (std.port(server.ip) == 7081) {
            set req.backend_hint = othellotesting;
    }
    elsif (std.port(server.ip) == 7082) {
            set req.backend_hint = pakjes;
    }
    elsif (std.port(server.ip) == 7083) {
            set req.backend_hint = othellotesting2;
    }
    elsif (std.port(server.ip) == 7084) {
            set req.backend_hint = twostoretesting;
    }
    elsif (std.port(server.ip) == 7085) {
            set req.backend_hint = lookbook;
    }
    elsif (std.port(server.ip) == 7086) {
            set req.backend_hint = twostore;
    }
    }
    sub vcl_backend_response {
        
    }
    sub vcl_deliver {
     
    }
    
    

    Daemon opts:

    /etc/default/varnish
    
    START=yes
    
    NFILES=131072
    
    MEMLOCK=82000
    
    DAEMON_OPTS="-a :7080,:7081,:7082,:7083,:7084,:7085,:7086 \
                 -T localhost:6082 \
                 -f /etc/varnish/default.vcl \
                 -S /etc/varnish/secret \
                 -s malloc,256m \
                 -p cli_buffer=16384 \
                 -p feature=+esi_ignore_other_elements \
                 -p vcc_allow_inline_c=on" \
                 -p http_resp_hdr_len=42000 \
                 -p esi_syntax=0x2 \
                 -p vcc_allow_inline_c=on \
    
    
    

    Then after applying the config, this is the running config I get when I press the button: "Download Varnish Config"

    vcl 4.0;
    C{
    #include <stdlib.h>
    #include <stdio.h>
    #include <time.h>
    #include <pthread.h>
    static pthread_mutex_t lrand_mutex = PTHREAD_MUTEX_INITIALIZER;
    void generate_uuid(char* buf) {
    pthread_mutex_lock(&lrand_mutex);
    long a = lrand48();
    long b = lrand48();
    long c = lrand48();
    long d = lrand48();
    pthread_mutex_unlock(&lrand_mutex);
    sprintf(buf, "frontend=%08lx%04lx%04lx%04lx%04lx%08lx",
    a,
    b & 0xffff,
    (b & ((long)0x0fff0000) >> 16) | 0x4000,
    (c & 0x0fff) | 0x8000,
    (c & (long)0xffff0000) >> 16,
    d
    );
    return;
    }
    }C
    import std;
    import directors;
    backend othello {
    .host = "127.0.0.1";
    .port = "80";
    }
    backend othellotesting {
    .host = "127.0.0.1";
    .port = "81";
    }
    backend pakjes {
    .host = "127.0.0.1";
    .port = "82";
    }
    backend othellotesting2 {
    .host = "127.0.0.1";
    .port = "83";
    }
    backend twostoretesting {
    .host = "127.0.0.1";
    .port = "84";
    }
    backend lookbook {
    .host = "127.0.0.1";
    .port = "85";
    }
    backend twostore {
    .host = "127.0.0.1";
    .port = "86";
    }
    sub vcl_recv { if (std.port(server.ip) == 7080) {
    set req.backend_hint = othello;
    }
    elsif (std.port(server.ip) == 7081) {
    set req.backend_hint = othellotesting;
    }
    elsif (std.port(server.ip) == 7082) {
    set req.backend_hint = pakjes;
    }
    elsif (std.port(server.ip) == 7083) {
    set req.backend_hint = othellotesting2;
    }
    elsif (std.port(server.ip) == 7084) {
    set req.backend_hint = twostoretesting;
    }
    elsif (std.port(server.ip) == 7085) {
    set req.backend_hint = lookbook;
    }
    elsif (std.port(server.ip) == 7086) {
    set req.backend_hint = twostore;
    }
    }
    sub vcl_backend_response {
    }
    sub vcl_deliver {
    }
    backend default {
    .host = "127.0.0.1";
    .port = "84";
    .first_byte_timeout = 300s;
    .between_bytes_timeout = 300s;
    }
    backend admin {
    .host = "127.0.0.1";
    .port = "84";
    .first_byte_timeout = 21600s;
    .between_bytes_timeout = 21600s;
    }
    acl crawler_acl {
    "127.0.0.1";
    }
    acl debug_acl {
    }
    sub generate_session {
    if (req.url ~ ".*[&?]SID=([^&]+).*") {
    set req.http.X-Varnish-Faked-Session = regsub(
    req.url, ".*[&?]SID=([^&]+).*", "frontend=\1");
    } else {
    C{
    char uuid_buf [50];
    generate_uuid(uuid_buf);
    static const struct gethdr_s VGC_HDR_REQ_VARNISH_FAKED_SESSION =
    { HDR_REQ, "\030X-Varnish-Faked-Session:"};
    VRT_SetHdr(ctx,
    &VGC_HDR_REQ_VARNISH_FAKED_SESSION,
    uuid_buf,
    vrt_magic_string_end
    );
    }C
    }
    if (req.http.Cookie) {
    std.collect(req.http.Cookie);
    set req.http.Cookie = req.http.X-Varnish-Faked-Session +
    "; " + req.http.Cookie;
    } else {
    set req.http.Cookie = req.http.X-Varnish-Faked-Session;
    }
    }
    sub generate_session_expires {
    C{
    time_t now = time(NULL);
    struct tm now_tm = *gmtime(&now);
    now_tm.tm_sec += 3600;
    mktime(&now_tm);
    char date_buf [50];
    strftime(date_buf, sizeof(date_buf)-1, "%a, %d-%b-%Y %H:%M:%S %Z", &now_tm);
    static const struct gethdr_s VGC_HDR_RESP_COOKIE_EXPIRES =
    { HDR_RESP, "\031X-Varnish-Cookie-Expires:"};
    VRT_SetHdr(ctx,
    &VGC_HDR_RESP_COOKIE_EXPIRES,
    date_buf,
    vrt_magic_string_end
    );
    }C
    }
    sub vcl_init {
    }
    sub vcl_recv {
    if ( (req.http.host ~ "^(?i)www.testing.two-store.be" || req.http.host ~ "^(?i)testing.two-store.be") && req.http.X-Forwarded-Proto !~ "(?i)https") {
    return (synth(750, ""));
    }
    if (req.restarts == 0) {
    if (req.http.X-Forwarded-For) {
    set req.http.X-Forwarded-For =
    req.http.X-Forwarded-For + ", " + client.ip;
    } else {
    set req.http.X-Forwarded-For = client.ip;
    }
    }
    if (!true || req.http.Authorization ||
    req.method !~ "^(GET|HEAD|OPTIONS)$" ||
    req.http.Cookie ~ "varnish_bypass=1") {
    return (pipe);
    }
    if(false) {
    set req.http.X-Varnish-Origin-Url = req.url;
    }
    set req.url = regsuball(req.url, "(.*)//+(.*)", "\1/\2");
    if (req.http.Accept-Encoding) {
    if (req.http.Accept-Encoding ~ "\*|gzip") {
    set req.http.Accept-Encoding = "gzip";
    } else if (req.http.Accept-Encoding ~ "deflate") {
    set req.http.Accept-Encoding = "deflate";
    } else {
    unset req.http.Accept-Encoding;
    }
    }
    if (req.http.User-Agent ~ "iP(?:hone|ad|od)|BlackBerry|Palm|Googlebot-Mobile|Mobile|mobile|mobi|Windows Mobile|Safari Mobile|Android|Opera (?:Mini|Mobi)") {
    set req.http.X-Normalized-User-Agent = "mobile";
    } else {
    set req.http.X-Normalized-User-Agent = "other";
    }
    if (req.url ~ "^(/media/|/skin/|/js/|/)(?:(?:index|litespeed)\.php/)?") {
    set req.http.X-Turpentine-Secret-Handshake = "1";
    if (req.url ~ "^(/media/|/skin/|/js/|/)(?:(?:index|litespeed)\.php/)?admin") {
    set req.backend_hint = admin;
    return (pipe);
    } else {
    }
    if (req.http.Cookie ~ "\bcurrency=") {
    set req.http.X-Varnish-Currency = regsub(
    req.http.Cookie, ".*\bcurrency=([^;]*).*", "\1");
    }
    if (req.http.Cookie ~ "\bstore=") {
    set req.http.X-Varnish-Store = regsub(
    req.http.Cookie, ".*\bstore=([^;]*).*", "\1");
    }
    if (req.url ~ "/turpentine/esi/get(?:Block|FormKey)/") {
    set req.http.X-Varnish-Esi-Method = regsub(
    req.url, ".*/method/(\w+)/.*", "\1");
    set req.http.X-Varnish-Esi-Access = regsub(
    req.url, ".*/access/(\w+)/.*", "\1");
    if (req.http.X-Varnish-Esi-Method == "esi" && req.esi_level == 0 &&
    !(true || client.ip ~ debug_acl)) {
    return (synth(403, "External ESI requests are not allowed"));
    }
    }
    if (req.http.Cookie !~ "frontend=" && !req.http.X-Varnish-Esi-Method) {
    if (client.ip ~ crawler_acl ||
    req.http.User-Agent ~ "^(?:ApacheBench/.*|.*Googlebot.*|JoeDog/.*|.*Siege/.*|magespeedtest\.com|Nexcessnet_Turpentine/.*|.*PTST.*)$") {
    set req.http.Cookie = "frontend=crawler-session";
    } else {
    call generate_session;
    }
    }
    if (true &&
    req.url ~ ".*\.(?:css|js|jpe?g|png|gif|ico|swf)(?=\?|&|$)") {
    unset req.http.Cookie;
    unset req.http.X-Varnish-Faked-Session;
    set req.http.X-Varnish-Static = 1;
    return (hash);
    }
    if (req.url ~ "^(/media/|/skin/|/js/|/)(?:(?:index|litespeed)\.php/)?(?:admin|api|cron\.php|customer|account|login|register|index\.php|admin|onepage|onestepcheckout|checkout|cart|review|sales|wishlist|monkey|ebizautoresponder|oauth|tag|review|ajaxcart)" ||
    req.url ~ "\?.*__from_store=") {
    return (pipe);
    }
    if (true &&
    req.url ~ "(?:[?&](?:__SID|XDEBUG_PROFILE|product|related_product|qty|isAjax)(?=[&=]|$))") {
    return (pass);
    }
    if (req.url ~ "[?&](utm_source|utm_medium|utm_campaign|gclid|cx|ie|cof|siteurl)=") {
    set req.url = regsuball(req.url, "(?:(\?)?|&)(?:utm_source|utm_medium|utm_campaign|gclid|cx|ie|cof|siteurl)=[^&]+", "\1");
    set req.url = regsuball(req.url, "(?:(\?)&|\?$)", "\1");
    }
    if (true && req.url ~ "[?&](utm_source|utm_medium|utm_campaign|utm_content|utm_term|gclid|cx|ie|cof|siteurl)=") {
    set req.url = regsuball(req.url, "(?:(\?)?|&)(?:utm_source|utm_medium|utm_campaign|utm_content|utm_term|gclid|cx|ie|cof|siteurl)=[^&]+", "\1");
    set req.url = regsuball(req.url, "(?:(\?)&|\?$)", "\1");
    }
    if(false) {
    set req.http.X-Varnish-Cache-Url = req.url;
    set req.url = req.http.X-Varnish-Origin-Url;
    unset req.http.X-Varnish-Origin-Url;
    }
    return (hash);
    }
    }
    sub vcl_pipe {
    unset bereq.http.X-Turpentine-Secret-Handshake;
    set bereq.http.Connection = "close";
    }
    sub vcl_hash {
    std.log("vcl_hash start");
    if (true && req.http.X-Varnish-Static) {
    std.log("hash_data static file - req.url: " + req.url);
    hash_data(req.url);
    if (req.http.Accept-Encoding) {
    std.log("hash_data static file - Accept-Encoding: " + req.http.Accept-Encoding);
    hash_data(req.http.Accept-Encoding);
    }
    std.log("vcl_hash end return lookup");
    return (lookup);
    }
    if(false && req.http.X-Varnish-Cache-Url) {
    hash_data(req.http.X-Varnish-Cache-Url);
    std.log("hash_data - X-Varnish-Cache-Url: " + req.http.X-Varnish-Cache-Url);
    } else {
    hash_data(req.url);
    std.log("hash_data - req.url: " + req.url );
    }
    if (req.http.Host) {
    hash_data(req.http.Host);
    std.log("hash_data - req.http.Host: " + req.http.Host);
    } else {
    hash_data(server.ip);
    }
    std.log("hash_data - req.http.Ssl-Offloaded: " + req.http.Ssl-Offloaded);
    hash_data(req.http.Ssl-Offloaded);
    if (req.http.X-Normalized-User-Agent) {
    hash_data(req.http.X-Normalized-User-Agent);
    std.log("hash_data - req.http.X-Normalized-User-Agent: " + req.http.X-Normalized-User-Agent);
    }
    if (req.http.Accept-Encoding) {
    hash_data(req.http.Accept-Encoding);
    std.log("hash_data - req.http.Accept-Encoding: " + req.http.Accept-Encoding);
    }
    if (req.http.X-Varnish-Store || req.http.X-Varnish-Currency) {
    hash_data("s=" + req.http.X-Varnish-Store + "&c=" + req.http.X-Varnish-Currency);
    std.log("hash_data - Store and Currency: " + "s=" + req.http.X-Varnish-Store + "&c=" + req.http.X-Varnish-Currency);
    }
    if (req.http.X-Varnish-Esi-Access == "private" &&
    req.http.Cookie ~ "frontend=") {
    std.log("hash_data - frontned cookie: " + regsub(req.http.Cookie, "^.*?frontend=([^;]*);*.*$", "\1"));
    hash_data(regsub(req.http.Cookie, "^.*?frontend=([^;]*);*.*$", "\1"));
    }
    if (req.http.X-Varnish-Esi-Access == "customer_group" &&
    req.http.Cookie ~ "customer_group=") {
    hash_data(regsub(req.http.Cookie, "^.*?customer_group=([^;]*);*.*$", "\1"));
    }
    std.log("vcl_hash end return lookup");
    return (lookup);
    }
    sub vcl_hit {
    }
    sub vcl_backend_response {
    set beresp.grace = 15s;
    set beresp.http.X-Varnish-Host = bereq.http.host;
    set beresp.http.X-Varnish-URL = bereq.url;
    if (bereq.url ~ "^(/media/|/skin/|/js/|/)(?:(?:index|litespeed)\.php/)?") {
    unset beresp.http.Vary;
    set beresp.do_gzip = true;
    if (beresp.status != 200 && beresp.status != 404) {
    set beresp.ttl = 15s;
    set beresp.uncacheable = true;
    return (deliver);
    } else {
    if (beresp.http.Set-Cookie) {
    set beresp.http.X-Varnish-Set-Cookie = beresp.http.Set-Cookie;
    unset beresp.http.Set-Cookie;
    }
    unset beresp.http.Cache-Control;
    unset beresp.http.Expires;
    unset beresp.http.Pragma;
    unset beresp.http.Cache;
    unset beresp.http.Age;
    if (beresp.http.X-Turpentine-Esi == "1") {
    set beresp.do_esi = true;
    }
    if (beresp.http.X-Turpentine-Cache == "0") {
    set beresp.ttl = 15s;
    set beresp.uncacheable = true;
    return (deliver);
    } else {
    if (true &&
    bereq.url ~ ".*\.(?:css|js|jpe?g|png|gif|ico|swf)(?=\?|&|$)") {
    set beresp.ttl = 28800s;
    set beresp.http.Cache-Control = "max-age=28800";
    } elseif (bereq.http.X-Varnish-Esi-Method) {
    if (bereq.http.X-Varnish-Esi-Access == "private" &&
    bereq.http.Cookie ~ "frontend=") {
    set beresp.http.X-Varnish-Session = regsub(bereq.http.Cookie,
    "^.*?frontend=([^;]*);*.*$", "\1");
    }
    if (bereq.http.X-Varnish-Esi-Method == "ajax" &&
    bereq.http.X-Varnish-Esi-Access == "public") {
    set beresp.http.Cache-Control = "max-age=" + regsub(
    bereq.url, ".*/ttl/(\d+)/.*", "\1");
    }
    set beresp.ttl = std.duration(
    regsub(
    bereq.url, ".*/ttl/(\d+)/.*", "\1s"),
    300s);
    if (beresp.ttl == 0s) {
    set beresp.ttl = 15s;
    set beresp.uncacheable = true;
    return (deliver);
    }
    } else {
    set beresp.ttl = 3600s;
    }
    }
    }
    return (deliver);
    }
    }
    sub vcl_synth {
    if (resp.status == 750) {
    set resp.status = 301;
    set resp.http.Location = "https://" + req.http.host + req.url;
    return(deliver);
    }
    }
    sub vcl_deliver {
    if (req.http.X-Varnish-Faked-Session) {
    call generate_session_expires;
    set resp.http.Set-Cookie = req.http.X-Varnish-Faked-Session +
    "; expires=" + resp.http.X-Varnish-Cookie-Expires + "; path=/";
    if (req.http.Host) {
    if (req.http.User-Agent ~ "^(?:ApacheBench/.*|.*Googlebot.*|JoeDog/.*|.*Siege/.*|magespeedtest\.com|Nexcessnet_Turpentine/.*|.*PTST.*)$") {
    set resp.http.Set-Cookie = resp.http.Set-Cookie +
    "; domain=" + regsub(req.http.Host, ":\d+$", "");
    } else {
    if (req.http.Host ~ "" && "" ~ "..") {
    set resp.http.Set-Cookie = resp.http.Set-Cookie +
    "; domain=";
    } else {
    set resp.http.Set-Cookie = resp.http.Set-Cookie +
    "; domain=" + regsub(req.http.Host, ":\d+$", "");
    }
    }
    }
    set resp.http.Set-Cookie = resp.http.Set-Cookie + "; httponly";
    unset resp.http.X-Varnish-Cookie-Expires;
    }
    if (req.http.X-Varnish-Esi-Method == "ajax" && req.http.X-Varnish-Esi-Access == "private") {
    set resp.http.Cache-Control = "no-cache";
    }
    if (true || client.ip ~ debug_acl) {
    set resp.http.X-Varnish-Hits = obj.hits;
    set resp.http.X-Varnish-Esi-Method = req.http.X-Varnish-Esi-Method;
    set resp.http.X-Varnish-Esi-Access = req.http.X-Varnish-Esi-Access;
    set resp.http.X-Varnish-Currency = req.http.X-Varnish-Currency;
    set resp.http.X-Varnish-Store = req.http.X-Varnish-Store;
    } else {
    unset resp.http.X-Varnish;
    unset resp.http.Via;
    unset resp.http.X-Powered-By;
    unset resp.http.Server;
    unset resp.http.X-Turpentine-Cache;
    unset resp.http.X-Turpentine-Esi;
    unset resp.http.X-Turpentine-Flush-Events;
    unset resp.http.X-Turpentine-Block;
    unset resp.http.X-Varnish-Session;
    unset resp.http.X-Varnish-Host;
    unset resp.http.X-Varnish-URL;
    unset resp.http.X-Varnish-Set-Cookie;
    }
    }
    
    

    Take a look at the magento backend configuration: turpentine varnish

    Kind regards, Pieter-Jan

    opened by pieterjanliekens 30
  • OpenMage+php7.4 -

    OpenMage+php7.4 - "Serve cached pages to crawlers on initial visit" not working

    After upgrading from Magento 1.9.4.5 > OpenMage LTS 19.4.15, Turpentine started serving Googlebot HTTP 302.

    When clearing the setting Caching Options > Crawler User Agents Googlebot again is served HTTP 200 as expected.

    opened by m-overlund 0
  • Somebody Help me to fix this magneto issue

    Somebody Help me to fix this magneto issue

    When i edit local.xml.sample to local.xml. and i have also created tmp folder on magento main folder but i am getting this issue. I am new. Somebody please help out.

    My error:

    There has been an error processing your request Cannot send headers; headers already sent in /home/yagyaoli/public_html/aab/app/code/core/Mage/Core/functions.php, line 60

    Trace: #0 /home/yagyaoli/public_html/aab/lib/Zend/Controller/Response/Abstract.php(115): Zend_Controller_Response_Abstract->canSendHeaders(true) #1 /home/yagyaoli/public_html/aab/app/code/core/Mage/Core/Model/App.php(1265): Zend_Controller_Response_Abstract->setHeader('Content-Type', 'text/html; char...') #2 /home/yagyaoli/public_html/aab/app/code/core/Mage/Core/Controller/Varien/Front.php(80): Mage_Core_Model_App->getResponse() #3 /home/yagyaoli/public_html/aab/app/code/core/Mage/Core/Controller/Varien/Router/Standard.php(202): Mage_Core_Controller_Varien_Front->getResponse() #4 /home/yagyaoli/public_html/aab/app/code/core/Mage/Core/Controller/Varien/Front.php(172): Mage_Core_Controller_Varien_Router_Standard->match(Object(Mage_Core_Controller_Request_Http)) #5 /home/yagyaoli/public_html/aab/app/code/core/Mage/Core/Model/App.php(365): Mage_Core_Controller_Varien_Front->dispatch() #6 /home/yagyaoli/public_html/aab/app/Mage.php(683): Mage_Core_Model_App->run(Array) #7 /home/yagyaoli/public_html/aab/index.php(83): Mage::run('', 'store') #8 {main}

    opened by ybo19091 0
  • Cache mobile sms preview

    Cache mobile sms preview

    Hi We sent an sms compagn today and we noticed a large number of not cached request after investigation we realized that the sms application on many devices (specially android) is showing a preview of the sent link, and this link is crawled via an integrated bot that does not accept cookie. So despite having put an internal redirect link in magento to land on a cached page, the bot is crawling uncached pages. We compare the ReqHeader of the bot with other requests, "accept-language" is missing and "Accept-Encoding" has the value "identity" Any idea how we can cache the viewed pages by this bot without cookie frontend

    varnish-cached.txt varnish-notcached.txt

    opened by choussamaster 0
  • generateUuid function in Data.php file not secure and maybe create duplicate uuid

    generateUuid function in Data.php file not secure and maybe create duplicate uuid

    In the "generateUuid()" function, that is in the "Data.php" file, mt_rand function does not good for generate uuid and maybe create duplicate uuid. It's better to use random_int(),random_bytes(), or openssl_random_pseudo_bytes() instead.

    https://www.php.net/manual/en/function.mt-rand.php

    opened by mortezasaki 0
  • pass changed to pipe

    pass changed to pipe

    We've been using an old version (0.7.1) and we had no performance issues. After decided to upgrade to 0.7.5 we've noticed a performance drop in our Magento 1 installation, after checking all code changes we determine that performance dropped due to change in varnish return from pass to pipe.

    Before (0.7.1):

    if (!true || req.method !~ "^(GET|HEAD|OPTIONS)$" ||
    req.http.Cookie ~ "varnish_bypass=1") {
    return (pass);
    }
    

    After (0.7.5)

    if (!true || req.http.Authorization ||
    req.method !~ "^(GET|HEAD|OPTIONS)$" ||
    req.http.Cookie ~ "varnish_bypass=1") {
    return (pipe);
    }
    

    Was that on purpose?

    opened by qsolutions-pl 3
  • Releases(release-0.7.5)
    Owner
    Nexcess.net
    Nexcess.net
    A Magento 1.x module which facilitates automatic purging of static assets from HTTP caches such as browser cache, CDN, Varnish, etc using best practices outlined within the HTML5 boilerplate community.

    Magento Cachebuster Cachebuster is a Magento module which facilitates automatic purging of static assets from HTTP caches such as browser cache, CDN,

    Gordon Knoppe 129 Apr 1, 2022
    Magento2 + Varnish + PHP7 + Redis + SSL (cluster ready)

    Docker Magento2: Varnish + PHP7 + Redis + SSL cluster ready docker-compose infrastructure Infrastructure overview Container 1: MariaDB Container 2: Re

    Fabrizio Balliano 332 Dec 30, 2022
    Magento 2 Blog Extension is a better blog extension for Magento 2 platform. These include all useful features of Wordpress CMS

    Magento 2 Blog extension FREE Magento 2 Better Blog by Mageplaza is integrated right into the Magento backend so you can manage your blog and your e-c

    Mageplaza 113 Dec 14, 2022
    Magento 2 Extension to cleanup admin menu and Store > Configuration area by arranging third party extension items.

    Clean Admin Menu - Magento 2 Extension It will merge all 3rd party extension's menu items in backend's primary menu to a common menu item named "Exten

    RedChamps 109 Jan 3, 2023
    This Magento 2 extension integrates EasyTranslate into Magento 2.

    EasyTranslate Magento 2 Connector This Magento 2 extension integrates EasyTranslate into Magento 2. Mind that you need to have an account with EasyTra

    Easytranslate ApS 0 Oct 7, 2022
    A tool that allows to quickly export data from Magento 1 and Magento 2 store and import it back into Magento 2

    Simple Import / Export tool A tool that allows to quickly export data from Magento 1 and Magento 2 store and import it back into Magento 2. Table data

    EcomDev B.V. 51 Dec 5, 2022
    Magento specific extension for phpstan

    bitexpert/phpstan-magento This package provides some additional features for PHPStan to make it work for Magento 2 projects. Installation The preferre

    bitExpert AG 92 Dec 7, 2022
    Magento extension which makes it impossible for a customer to log in until the account has been activated by the administrator.

    This Magento 1 extension is orphaned, unsupported and no longer maintained. If you use it, you are effectively adopting the code for your own project.

    Vinai Kopp 120 Oct 10, 2022
    Magento 2 Magetrend PdfTemplates extension override pdf tempate in order,invoice,credit-memo

    Magento 2 Magetrend PdfTemplates extension override pdf tempate in order,invoice,credit-memo

    Yodo1117 1 Jan 3, 2022
    Magento 2 Product Allocation extension allows the to admin manage all products in an order

    Magento 2 Product Allocation extension allows the to admin manage all products in an order, making sure that products can only be moved to cart if sufficient allocation is available.

    Yodo1117 1 Jan 1, 2022
    Official Kraken.io Magento Extension

    Kraken.io Magento Extension Advanced optimization for your Magento JPEG, PNG, GIF and SVG images Established in 2012, Kraken.io is an industry-leading

    Kraken.io Image Optimizer 21 Nov 30, 2022
    LiqPay integration extension for Magento 2

    LiqPay Extension for Magento 2 LiqPay payment integration extension for Magento 2. Check out the Wiki pages for the project details. Idea The idea of

    Max Pronko 21 Nov 2, 2021
    Wirecard Magento 2 Extension

    Wirecard Magento 2 Extension General Information Before you proceed, please read our General Information for more details on Wirecard Shop Extension f

    Wirecard 10 Sep 16, 2021
    PAYONE Payment Extension for Magento 2

    PAYMENT FOR YOUR MAGENTO 2-SHOP The PAYONE payment extension for Magento 2 is massively reworked since the first version. The Github-Community was imp

    PAYONE GmbH 27 Nov 10, 2022
    Magento 2 SEO extension will do perfectly for your better SEO.

    Magento 2 SEO extension will do perfectly for your better SEO. This is a bundle of outstanding features that are auto-active when you install it from Mageplaza without any code modifications. It is also friendly with your store if you need to insert meta keywords and meta descriptions for your product.

    Mageplaza 121 Oct 28, 2022
    Magento 2 Blog Extension - FREE, fully featured, powerful Blog solution for your online store!

    Blog MX | Magento 2 Blog Module by Mirasvit FREE, fully featured, powerful Blog solution for your online store! Magento 2 Blog MX allows you to open a

    Mirasvit 71 Dec 7, 2022
    Magento 2 Blog is an extension that allows you to manage your store and blog

    Magento 2 Blog Extension by Magefan Magento 2 Blog is an extension that allows you to manage your store and blog from one place without having to rely

    Magefan 243 Dec 21, 2022