Git Product home page Git Product logo

lscache-laravel's Introduction

Laravel LSCache

This package allows you to use lscache together with Laravel.

It provides two middlewares and one facade:

  • LSCache Middleware to control the cache-control header for LiteSpeed LSCache
  • LSTags Middleware to control the tag header for LiteSpeed LSCache
  • LSCache facade to handle purging

Installation

Require this package using composer.

composer require litespeed/lscache-laravel

Laravel uses Auto-Discovery, so you won't have to make any changes to your application, the two middlewares and facade will be available right from the beginning.

Steps for Laravel >=5.1 and <=5.4

The package can be used for Laravel 5.1 to 5.4 as well, however due to lack of Auto-Discovery, a few additional steps have to be performed.

In config/app.php you have to add the following code in your aliases:

'aliases' => [
    ...
    'LSCache'   => Litespeed\LSCache\LSCache::class,
],

In app/Http/Kernel.php you have to add the two middlewares under middleware and routeMiddleware:

protected $middleware = [
    ...
    \Litespeed\LSCache\LSCacheMiddleware::class,
    \Litespeed\LSCache\LSTagsMiddleware::class,
];

protected $routeMiddleware = [
    ...
    'lscache' => \Litespeed\LSCache\LSCacheMiddleware::class,
    'lstags' => \Litespeed\LSCache\LSTagsMiddleware::class,
];

Copy lscache.php to config/:

Copy the package config/lscache.php file to your config/ directory.

important: Do not add the ServiceProvider under providers in config/app.php.

Steps for Laravel 5.5 and above

You should publish the package configuration, which allows you to set the defaults for the X-LiteSpeed-Cache-Control header:

php artisan vendor:publish --provider="Litespeed\LSCache\LSCacheServiceProvider"

Enable CacheLookup for LiteSpeed Cache

To enable CacheLookup for LiteSpeed Cache, you have to include the following code, either on server, vhost or .htaccess level:

<IfModule LiteSpeed>
   CacheLookup on
</IfModule>

Usage

The package comes with 3 functionalities: Setting the cache control headers for lscache, settings specific tags and purging.

cache-control

You'll be able to configure defaults in the config/lscache.php file, here you can set the max-age (default_ttl), the cacheability (default_cacheability) such as public, private or no-cache or enable esi (esi) in the X-LiteSpeed-Cache-Control response header.

If the default_ttl is set to 0, then we won't return the X-LiteSpeed-Cache-Control response header.

You can control the config settings in your .env file as such:

  • LSCACHE_ESI_ENABLED - accepts true or false to whether you want ESI enabled or not globally; Default false
  • LSCACHE_DEFAULT_TTL - accepts an integer, this value is in seconds; Default: 0
  • LSCACHE_DEFAULT_CACHEABILITY - accepts a string, you can use values such as private, no-cache, public or no-vary; Default: no-cache
  • LSCACHE_GUEST_ONLY - accepts true or false to decide if the cache should be enabled for guests only; Defaults to false

You set the cache-control header for lscache using a middleware, so we can in our routes do something like this:

Route::get('/', function() {
    return view('frontpage');
});

Route::get('/about-us', function() {
    return view('about-us');
})->middleware('lscache:max-age=300;public');

Route::get('/contact', function() {
    return view('contact');
})->middleware('lscache:max-age=10;private;esi=on');

Route::get('/admin', function() {
    return view('admin');
})->middleware('lscache:no-cache');

Below is 4 examples:

  • the / route will use the default X-LiteSpeed-Cache-Control header that you've configured in config/lscache.php.
  • the /about-us route sets a max-age of 300 seconds as well as setting the cacheability to public, keep in mind you'll use semi-colon (;) to separate these values.
  • the /contact route uses a max-age of 10 seconds, uses private cacheability and turns ESI on. Turning ESI on, allows you to use <esi:include> within your blade templates and these will be parsed by the ESI engine in LiteSpeed Web Server.
  • the /admin route will never be cached by setting a X-LiteSpeed-Cache-Control: no-cache -header.

Now, you'll also be able to apply the same middleware to route groups in Laravel, let's take an example:

Route::group(['prefix' => 'admin', 'middleware' => ['lscache:private;esi=on;max-age=120']], function() {
    Route::get('/dashboard', function() {
        return view('dashboard');
    });

    Route::get('/stats', function() {
        return view('stats');
    })->middleware('lscache:no-cache');
});

In the above case, we've set the whole admin group to be private with esi enabled and a max-age of 120 seconds, however in the /admin/stats route, we override the X-LiteSpeed-Cache-Control header to no-cache.

tags

You're also able to set tags for LSCache using the lstags middleware. If we use the previous example of our admin route group:

Route::group(['prefix' => 'admin', 'middleware' => ['lscache:private;esi=on;max-age=900', 'lstags:admin']], function() {
    Route::get('/dashboard', function() {
        return view('dashboard');
    });

    Route::get('/users', function() {
        return view('users');
    });
});

Here we've added the lstags:admin middleware, this means that the cache will get tagged with an admin tag, so when we later want to purge the cache, we can target all admin pages using the tag admin.

You can also do more complex tags as such:

Route::get('/view', function() {
    return view('view');
})->middleware(['lscache:private', 'lstags:public:pubtag1;public:pubtag2;public:pubtag3;privtag1;privtag2']);

purge

If we have an admin interface that controls for example a blog, when you publish a new article, you might want to purge the frontpage of the blog so the article appears in the overview.

You'd do this in your controller by doing

<?php

namespace App\Http\Controllers;

use LSCache;

class BlogController extends BaseController
{
    // Your article logic here

    LSCache::purge('/');
}

In the above example, we're simply telling it to add an additional header called X-LiteSpeed-Purge with the value stale,/, this will invalidate the frontpage of the site.

You can also purge everything by doing:

LSCache::purge('*');
// or
LSCache::purgeAll();

One or multiple URIs can be purged by using a comma-separated list:

LSCache::purge('/blog,/about-us,/');
// or
LSCache::purgeItems(['/blog', '/about-us', '/']);

You can purge individual or multiple tags:

LSCache::purge('tag=archive, tag=categories');
// or
LSCache::purgeTags(['archive', 'categories']);

Or if you want to purge private cache by tag:

LSCache::purge('private, tag=users');

You even have the possibility to purge a set of public tags and and purge all the private tags:

LSCache::purge('pubtag1, pubtag2, pubtag3; private, *');

LiteSpeed Cache for Laravel 1.1.0 comes with a stale option turned on by default for the LSCache::purge function, this can be turned off by using false as the second parameter in the purge function:

LSCache::purge('*', false);
// or
LSCache::purge('*', $stale=false);
// or
LSCache::purgeAll(false);

Why stale purge matters

By default the way Lscache works in LiteSpeed is by purging an element in the cache, and next request will generate the cached version.

This works great if you're running a fairly low traffic site, however if your application takes let's say 2 seconds to process a given request, all traffic received to this endpoint within those 2 seconds will end up hitting the backend, and all visitors will hit PHP.

By using the stale, keyword in front the "key" you're purging, you're telling Lscache to purge the item, but if multiple visitors hit the same endpoint right after each other, only the first visitor will be the one generating the cache item, all remaining vistors will get served the stale cached page until the new cached page is available.

Since a page generation should be rather fast, we're only serving this stale content for maybe a couple of seconds, thus also the reason it's being enabled by default.

If your application cannot work with stale content at all, then you can use false or $stale=false as the second parameter in the LSCache::purge() function to disable this functionality.

You can also purge specific public tags by adding ~s after the tag, such as:

LSCache::purge('pubtag1, pubtag2~s, pubtag3; private, privtag1, privtag2', $stale=false);

Only pubtag2 will be served stale.

Laravel Authentication

If you use authentication in Laravel for handling guests and logged-in users, you'll likely want to also separate the cache for people based on this.

This can be done in the .htaccess file simply by using the cache-vary on the Authorization cookie:

RewriteEngine On
RewriteRule .* - [E=Cache-Vary:Authorization]

Note: In the above example we use Authorization, this may have a different name depending on your setup, so it has to be changed accordingly.

lscache-laravel's People

Contributors

laravel-shift avatar lslisa avatar lucasrolff avatar niladam avatar piannelli avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

lscache-laravel's Issues

Support Lumen

Hi,

can you support Lumen (a micro-framework derivated from Laravel, by the same authors). Here is a discussion about the package incompatibilities: forum.openlitespeed.org/threads/lumen-composer-lscache-remove-illuminati-folder.4032

Thanks

cache half of screeen

hello
thanx for port this awsome plugin for Laravel users

i have a search page
i want to cache just filters in right of the page not total of the page
have you any way to do it for me ?

Purging multiple (or at least two) slugs

Hi,

We are trying to purge single articles + the homepage of a website upon updating a single article.

Having:

LSCache::purge('/an-article-slug'); // the article we update
LSCache::purge('/'); // the homepage 

does not work since headers are already send.

Is it possible to have purge extended in order to support multiple slugs (similar to multiple tags)

e.g.

LSCache::purge('/slug1', '/slug2', .... )

Thanks

Purging issues after last update on v1.1.0

LSCache::purge('*'); <--- WORKS

LSCache::purge('/'); <--- NOT purging homepage
LSCache::purge('/this-is-a-post-slug'); <--- NOT purging specific slug

As a result I have to purge all every time a new post is added.
Please advise.

Function to "Purge and Re-cache" immediately

Hi,

Is there a way to extent the Purge function and once the requested slug e.g. "/" or "contact-us" is purged from the cache, to be re-cached immediately (and not wait for the first front-end user to hit it).

This will allow to purge and re-cache content that's updated and we want to serve it cached even for the 1st request.

Thanks

isMethodCacheable not found error for laravel 5.2

The isMethodCacheable method exists in symfony/http-foundation/Request.php in the recent version of symfony but symfony version used by Laravel 5.2 doesn't have this method inside te Request class.

I think for backward compatibility the raw code from isMethodCacheable is be used directly :

\in_array($this->getMethod(), ['GET', 'HEAD']);

What do you think about it ?

As I have issue using this plugin inside my website.

Lscache Problem with middlewares

Hello
Thanks for the good package you have prepared for Laravel, I used this package in my project but there is a strange problem with it. First, read the following scenario:
I have written a custom middleware to track my site visits, please see the following snippet:

routes (web.php)

Route::group(['middleware' => 'tracker'], function (){
    
    Route::get('/', 'HomeController@home')->name('root');
    
    //Cache for 1 week
    Route::group(['middleware' => 'lscache:max-age=604800;public;esi=on', 'lstags:1wcache'], function (){
        Route::get('/experience','HomeController@showExperience');
        Route::get('/contact','ContactController@show')->name('contact');
        Route::get('/donate','PaymentController@show')->name('donate-page');
    });

    //Cache for 1 day
    Route::group(['middleware' => 'lscache:max-age=86400;public;esi=on', 'lstags:1dcache'], function (){
        Route::get('/portfolio','HomeController@showPortfolio');
    });

    //Cache for 12 hrs
    Route::group(['middleware' => 'lscache:max-age=3600;public;esi=on', 'lstags:12hcache'], function (){
        Route::get('/blog','HomeController@blog');
        Route::get('/blog/{post}','HomeController@showPost');
        Route::get('/p/{id}','HomeController@shortLink');
    });
});

my middleware:

<?php

namespace App\Http\Middleware;

use App\Jobs\ProcessUserTracker;
use Closure;
use Jenssegers\Agent\Agent;

use Illuminate\Support\Facades\Log;

class UserTracker
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next){
        
        //get user ip
        $ip = geoip()->getClientIP();
        $userTrack = geoip($ip);
        $agent = new Agent();

        //use jobs to make application faster
        ProcessUserTracker::dispatch($userTrack, $agent);
        
        return $next($request);
    }
}

And problem statement:

When the site is visited for the first time, nothing is cached and my custom middleware is executed, but for the next time, the same middleware will not be executed at all.

I have disabled the entire cache process and the problem is solved!!!

Can you help me solve this problem?

Only LSCache::purgeAll() is working!!

Hi,
Am using OpenLitespeed 1.6.21 (lsphp74) in the ols-docker-env image , LSCache::purgeAll() and LSCache::purge('*') seems to be the only working functions !
When using LSCache::purge('/') or LSCache::purge('/path1,/path2,/path3') or even LSCache::purgeItems(['/path1','/path2','/path3']) nothing happens !! the pages are still served from the cache

Laravel 8 publish provider

Hi,
For laravel 8 the command "php artisan vendor:publish --provider="Litespeed\LSCache\LSCacheServiceProvider"" produces config cache. I set group middleware
Route::group(['prefix' => 'admin', 'middleware' => ['lscache:no-cache', 'lstags:admin']], function () {
routes....

But i have proble with images update. The image is vissible after 3,4 times reload.
Also i have pagespeed apache.

Any comment?

Lscache tabs max-age not working (Cache-Control)

I installed lscache with these steps https://docs.litespeedtech.com/lscache/lsclaravel/installation/.
At .env i have
LSCACHE_ESI_ENABLED=true
LSCACHE_DEFAULT_TTL=108000
At laravel/public/.htacess
< IfModule LiteSpeed >
CacheLookup on
</ IfModule >
In web.php for homepage i set
Route::get('/', 'Controller@index')
->middleware(['lscache:max-age=108000;public;', 'lstags:home']);

but in f12 i am ok with
X-LiteSpeed-Cache: hit
X-LS-Pagespeed: 2.1-1.11.33.4
https://i.imgur.com/e9XiXQd.png
but how to set "Cache-Control: public,max-age=108000" instead "Cache-Control: no-cache, private,public" and see tag "home"?

Feature: Possibility to enable/disable caching for logged in users

It would be great if i could be able to disable cache on an per-auth setting.

I'm thinking this would involve some sort of config key (maybe guests_only) and probably a check if the user is logged in or not.

Also, maybe it could automatically build a private cache (per user setting?) automatically if the user is logged in..

LS cache causes loading unauthenticated page after login for the first time

The 'guest mode only' is on. After user log in I redirect it to the home page. For the first time the home page for unauthenticated users loads but after a refresh, the page changes and shows the logged-in user's name and information.
I tried to check the Auth::check() condition after a successful login and redirection in LSCacheMiddleware using the dd method but it seems it doesn't even get executed at the first redirection.
Handle method in LSCacheMiddleware:

    public function handle($request, Closure $next, string $lscache_control = null)
    {
        $response = $next($request);
        if (!strpos(URL::current(), 'login')) // added line
            dd(Auth::check()); // added line
        ...

I added !strpos(URL::current(), 'login') condition to be able to login. After successful login attempt and redirection to home page url ( '/') although !strpos(URL::current(), 'login') is true but it is still loading the page from cache (I expected to at least get false bool) but after another refresh I get the true bool.

I found a workaround but it results in dirty coding and dispensable concerns.
I purged the homepage cache before the redirection and it fixed it.
LSCache::purge('/');

lscache config:

return [
    /**
     * Enable ESI
     */
    'esi' => env('LSCACHE_ESI_ENABLED', false),

    /**
     * Default cache TTL in seconds
     */
    'default_ttl' => env('LSCACHE_DEFAULT_TTL', 15),

    /**
     * Default cache storage
     * private,no-cache,public,no-vary
     */
    'default_cacheability' => env('LSCACHE_DEFAULT_CACHEABILITY', 'no-cache'),

    /**
     * Guest only mode (Do not cache logged in users)
     */
     'guest_only' => env('LSCACHE_GUEST_ONLY', true),
];

Laravel version: 6.2
PHP version in composer: 7.2
PHP version: 7.3

Full example of esi in blade

Hi
Can you provide a full example of using esi in laravel blade template?

I want to prevent the cache from my topbar and I want to cache it privately. how can I do this?

LiteSpeed Cache and Browser Cache

LiteSpeed Cache and Browser Cache. are different thing.

LiteSpeed Cache Rules at web.php (laravel) ovverides Browser cache(defaults or rules from headers via php) or not?

Private caching without ESI

Hi guys,

Someone on Slack mentioned private caching won't work without ESI. I'm using OpenLiteSpeed so I won't be able to use ESI.

Is there any way to work around this? I'm moving from WordPress to Laravel and have been enjoying private caching on OLS via the WordPress LSCache plugin.

I'd prefer not to lose that if possible!

Cheers

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.