Coder Social home page Coder Social logo

static-cache's Introduction

Koa Static Cache

NPM version build status Test coverage David deps

Static server for koa.

Differences between this library and other libraries such as static:

  • There is no directory or index.html support.
  • You may optionally store the data in memory - it streams by default.
  • Caches the assets on initialization - you need to restart the process to update the assets.(can turn off with options.preload = false)
  • Uses MD5 hash sum as an ETag.
  • Uses .gz files if present on disk, like nginx gzip_static module

Installation

$ npm install koa-static-cache

API

staticCache(dir [, options] [, files])

var path = require('path')
var staticCache = require('koa-static-cache')

app.use(staticCache(path.join(__dirname, 'public'), {
  maxAge: 365 * 24 * 60 * 60
}))
  • dir (str) - the directory you wish to serve, priority than options.dir.
  • options.dir (str) - the directory you wish to serve, default to process.cwd.
  • options.maxAge (int) - cache control max age for the files, 0 by default.
  • options.cacheControl (str) - optional cache control header. Overrides options.maxAge.
  • options.buffer (bool) - store the files in memory instead of streaming from the filesystem on each request.
  • options.gzip (bool) - when request's accept-encoding include gzip, files will compressed by gzip.
  • options.usePrecompiledGzip (bool) - try use gzip files, loaded from disk, like nginx gzip_static
  • options.alias (obj) - object map of aliases. See below.
  • options.prefix (str) - the url prefix you wish to add, default to ''.
  • options.dynamic (bool) - dynamic load file which not cached on initialization.
  • options.filter (function | array) - filter files at init dir, for example - skip non build (source) files. If array set - allow only listed files
  • options.preload (bool) - caches the assets on initialization or not, default to true. always work together with options.dynamic.
  • options.files (obj) - optional files object. See below.
  • files (obj) - optional files object. See below.

Aliases

For example, if you have this alias object:

{
  '/favicon.png': '/favicon-32.png'
}

Then requests to /favicon.png will actually return /favicon-32.png without redirects or anything. This is particularly important when serving favicons as you don't want to store duplicate images.

Files

You can pass in an optional files object. This allows you to do two things:

Combining directories into a single middleware

Instead of doing:

app.use(staticCache('/public/js'))
app.use(staticCache('/public/css'))

You can do this:

var files = {}

// Mount the middleware
app.use(staticCache('/public/js', {}, files))

// Add additional files
staticCache('/public/css', {}, files)

The benefit is that you'll have one less function added to the stack as well as doing one hash lookup instead of two.

Editing the files object

For example, if you want to change the max age of /package.json, you can do the following:

var files = {}

app.use(staticCache('/public', {
  maxAge: 60 * 60 * 24 * 365
}, files))

files['/package.json'].maxAge = 60 * 60 * 24 * 30

Using a LRU cache to avoid OOM when dynamic mode enabled

You can pass in a lru cache instance which has tow methods: get(key) and set(key, value).

var LRU = require('lru-cache')
var files = new LRU({ max: 1000 })

app.use(staticCache({
  dir: '/public',
  dynamic: true,
  files: files
}))

License

The MIT License (MIT)

Copyright (c) 2013 Jonathan Ong [email protected]

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

static-cache's People

Contributors

alexeykhristov avatar atian25 avatar cap32 avatar codepiano avatar dead-horse avatar fengmk2 avatar fishrock123 avatar gl2748 avatar greenkeeperio-bot avatar jiazhonglin avatar jonathanong avatar madogai avatar mgol avatar mistadikay avatar ratson avatar tejasmanohar avatar teohhanhui avatar thomasdezeeuw avatar whwnow 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  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  avatar  avatar  avatar  avatar

static-cache's Issues

Render static page directly

It would be great to have a function one could use to render a file directly while still taking advantage of the caching mechanisms in static-cache...

E.g. something like

if (this.path == '/') {
  if (isAuthenticated)
    yield next;
  else
    staticCache.render('/landing.html');
}

ignore cache for some files which files name match RegExt

In a case like below:

  • directory structure:
./public
├── A
│   ├── index.html
│   └── index.js
├── B
│   ├── index.html
│   └── index.js
└── ...
    ├── index.html
    └── index.js
  • I want ignore cache for file index.html in each subdirectory in public. Because each index.html is generated by SSR in my case. But there too many subdirectories to add xxx/index.html into options.files, and some subdirectories name are generated dynamically after static-cache init.

research

question

can static-cache add an option called ignorefiles or another name, which type is one of RegExp/RegExpArray/filename/filenameArray, and ignore cache for files which match ignorefiles.

generally speaking, static-cache is use for directory/files which are static. So I am not sure this idea is worth and useful.

@dead-horse @fengmk2 @Gorden-Wang

after uploading pictures need to restart the service

Front

//profile settings
    var avatarData = '';
    upload.preview('avatar','preview-avatar',function(data){
        avatarData = data;//base64
    });

    new Vue({
        el:'#profile-form',
        data:{
            profile:{
                nickname:'',
                sex:profileSex,
                company:'',
                avatar:'',
                description:'',
                github:'',
                weibo:''
            }
        },
        methods:{
            submit:function(e){
                e.preventDefault();
                loadin.show('load');
                var profileData = this.$data.profile;
                if(avatarData){
                    avatarData = avatarData.replace(/^data:image\/\w+;base64,/,'');
                }
                profileData.avatar = avatarData;
                $.ajax({type:'POST',url:'/profile',data:profileData}).then(function(ret){
                    ret = JSON.parse(ret);
                    if(ret.status){
                        loadin.show('alert',ret.msg,'success');
                        setTimeout(function(){
                            location.reload();
                        },1000);
                    }
                },function(){});
            }
        }
    });

After

//profile
    user.profile = function* (){
        var body = this.request.body,
            nickname = body.nickname,
            sex = body.sex,
            company=body.company,
            avatar = body.avatar,
            description= body.description,
            github=body.github,
            weibo = body.weibo;

        if(avatar){
            var imgbuffer = new Buffer(avatar,'base64');
            var imgName = yield model.get({email:this.session.user.email},'avatar');
            if(/custom/.test(imgName.avatar)){
                imgName = 'assets'+imgName.avatar;
            }else{
                imgName = 'assets/customavatar/petitspois:'+(+new Date)+(Math.random()*1000|0)+'.png';
            }

            yield fs.writeFile(imgName,imgbuffer);

        }

        var profile = {
            nickname:nickname,
            sex: sex,
            company:company,
            description:description,
            github:github,
            weibo:weibo
        }

        avatar && (profile.avatar = imgName.slice(6));

        var update =  yield model.update({email:this.session.user.email},{$set:profile});

        if(update){
            this.body = {
                msg:'success',
                status:1
            }
        }


    }

static

app.use(sC(conf.static, {maxAge:0,dynamic:false}));

Path 404, need to restart

'dynamic' option is not working

Describe the bug

'dynamic' option is not working.

OS version:
Ubuntu 20.04 x64
Node v16

Description:
Even set 'dynamic' to true, new uploaded files cannot be get and got 404 instead.

Actual behavior

Even set 'dynamic' to true, new uploaded files cannot be get and got 404 instead.

Expected behavior

Get new uploaded files, not 404.

Code to reproduce

app.use(staticCache(path.join(__dirname, './uploads'), { prefix: '/uploads', maxAge: 30 * 24 * 60 * 60, dynamic: true }));
or
app.use(mount('uploads', staticCache(path.join(__dirname, './uploads'), { maxAge: 30 * 24 * 60 * 60, dynamic: true })));

Checklist

  • [Y] I have searched through GitHub issues for similar issues.
  • [Y] I have completely read through the README and documentation.
  • [Y] I have tested my code with the latest version of Node.js and this package and confirmed it is still not working.

[bug] RangeError [ERR_FS_FILE_TOO_LARGE] when buffer set false.

Describe the bug

Node.js version: v16.20.1

OS version: macOS 13.5.1

Description: the app crashes when attempting to read a file larger than 2GB.. setting config.buffer false.

Actual behavior

a file larger than 2GB located in the /public directory can cause the entire app to crash when attempting to read it.

Expected behavior

reading it normally.

Code to reproduce

const Koa = require("koa");
const path = require("path");
const staticCache = require("koa-static-cache");
const app = new Koa();

app.use(
  staticCache(path.join(__dirname, "public"), {
    buffer: false,
    dynamic: true,
    preload: false,
  })
);

app.use(async (ctx) => {
  ctx.body = "Hello World";
});

app.listen(3000);

Checklist

  • I have searched through GitHub issues for similar issues.
  • I have completely read through the README and documentation.
  • I have tested my code with the latest version of Node.js and this package and confirmed it is still not working.

Other

I suspect the issue may be related to the loadFile function:

image

Path separator not unified

After update from 1.2.0 I have realized that I can't serve static files anymore. Looking inside the module I have found that the path separator mismatch have made the file object never accessible.

The machine is Windows, and example files object (via console.log) shown below:

{
  '/res\jquery-2.1.1.min.js':
   { path: 'D:\\test\\public\\jquery-2.1.1.min.js',
     cacheControl: undefined,
     maxAge: 0,
     mime: 'application/javascript',
     type: 'application/javascript',
     mtime: 'Sat, 01 Nov 2014 13:52:08 GMT',
     length: 84245,
     md5: '5A7CFh/nmTGW8jyKBzRjBg=='
   }
}

And when the url was visited, is looking for \res\jquery-2.1.1.min.js inside the files object.

Code setup:

var __PUBLIC_ABS = __dirname  + '/public/';
var staticCache = require('koa-static-cache');
app.use (staticCache(__PUBLIC_ABS, {
    prefix: '/res/'
}));

Thanks.

redo files api

it's kind of weird. maybe i just need to document it better.

Cannot read property 'getTime' of undefined

使用 static-cache 作为静态文件托管,使用过程中,概率出现以下报错

2021-12-30 10:14:09,663 ERROR 247 [-/-/172.16.224.25/64407ebb16408304496621596d00f7/2ms GET /public/common/bi.jpeg] ### onerror handle { TypeError: Cannot read property 'getTime' of undefined
    at /xxxxl/node_modules/_koa-static-cache@5.1.4@koa-static-cache/index.js:86:48 status: 500 }
2021-12-30 10:15:17,903 ERROR 256 [-/-/172.16.224.25/64407ebb16408305179021481d0100/1ms GET /public/common/bi.jpeg] nodejs.TypeError: Cannot read property 'getTime' of undefined
    at /xxxx/node_modules/_koa-static-cache@5.1.4@koa-static-cache/index.js:86:48

not working with koa-etag, koa-conditional-get

This will not work with koa-etag and koa-conditional-get (static requests pending to timeout). I guess because etag tries to generate a hash on static-cache or vice versa.

What would a workaround look like? I think it is common to use a cache for static files with one for generated ones (views, json).

when new file added, static-cache just return 404 Not Found

I think, when a new file added, staticCache should load file.

But, now it just return 404 Not Found.

Test code like this:

 var fs = require('fs');
 it('add new file should work fine', function (done) {
    var app = koa()
    app.use(staticCache())
    var server = app.listen()
    fs.writeFileSync('a.js', 'hello world');

    request(server)
      .get('/a.js')
      .expect(200, done)
  })

length

HI,
I'm using koa-static-cache in my app. my app deploy in the server. when I rollback my app to an old version,my broswer page is broken.
I serarch the reason. then I find that when I rollback my app the mtime is ealier than latest one,it cause ctx.length not refresh.
Should file.length refresh whether the mtime old or new?
image

koa2 not found txt file

file path
views/.xxx/aaa/xxx.txt

app.use(staticCache(path.join(__dirname, '/views'), {
        maxAge: 365 * 24 * 60 * 60,
        gzip:true,
    }))

i request localhost/.xxx/aaa/xxx.txt but not found.

bad argument handling

In index.js, in the first line of the staticCAche function, there is:

if (typeof dir === 'object') {
  options = dir
  files = options
  dir = null
}

this is wrong because options is lost before being copied to files. this should be:

if (typeof dir === 'object') {
  files = options
  options = dir
  dir = null
}

add a option to make it do not send cache headers?

the etags are calculate at initialization, and from the second request, every request just get a 304, even buffer: false.
when In the development time, i just want to do not send the annoying headers, and return the fresh streams.

maybe i can use koa-static in development, but i do not want to require two modules do the same thing.

it is good to add a options like cacheHeader: false to stop set cache headers. or maybe just don't set cache headers when options.buffer === false, it makes people confused why the static files do not refresh? is it still cache in the buffer?

any suggestions? i can make a PR for this.

option.alias redirect not effective in windows

to redirect /swagger-ui.html to /index.html,
in linux it is effective,but windows not.

const swaggerH5 = path.join(__dirname, '../../app/public');
app.use(staticCache(swaggerH5, {
  alias: {
    '/swagger-ui.html': '/index.html',
  },
}, {}));

how to clear the cache?

[Need help] As usually, files will be update, so if I want to clear the one or hole static cache , how do I do? Reload the server, or reset the max-age time?

Why not support defining cacheControl for certain file

// static-cache/index.js
198 obj.cacheControl = options.cacheControl // why not: obj.cacheControl = obj.cacheControl ? obj.cacheControl : options.cacheControl ?
199 obj.maxAge = obj.maxAge ? obj.maxAge : options.maxAge || 0

not working in windows

using windows 7, [email protected].

server.use(mount('/build', serve(__dirname)));

If serve = require('koa-static'), then the static files is accessible.
If serve = require('koa-static-cache'), then the static files is not accessible at all.

Here's a piece of the debug message:

request: /build/server.js
  koa-router GET undefined +8s
  koa-router test "/" /^(?:\/(?=$))?$/i +2ms
  koa-mount mount /jspm_packages staticCache -> false +5s
  koa-mount mount /build staticCache -> /server.js +1ms
  koa-mount enter /build/server.js -> /server.js +1ms
  koa-mount leave /build/server.js -> /server.js +2ms

looks like the file was found.. but somehow was not sent out, the browser request ends up in 'not found'.

Path separator still not unified

On windows, when I use alias, have to write like this {'\\public\\' : '\\public\\index.html'}
and the console shows, aliasing \public\index.html as \public\

Hope can define like this {'/public/' : '/public/index.html'} on all platforms

possible npm version issue

hi, when I run npm outdated I get the following

Package               Current  Wanted      Latest  Location
koa-static-cache        5.1.0   5.1.0       4.1.0     myproject

Not sure why latest is showing 4.1.0 when I have 5.1.0 installed and working?

Possible to set headers when using this module?

I'm looking to do something like the following (using koa-router):

router.all('*', async (ctx, next) => {
 assets.forEach((a) => { ctx.append('Link', `<${a}>; rel=preload;`) })
 // call staticCache(publicDirectory, otherOptions)
}

(where assets is some JS and CSS) but don't see a clear way to do this. Is that a possibility currently? What I'm currently doing can be seen here. This just gets a shape like [ { headerName: 'headerValue' } ].

I'm trying to avoid adding a separate middleware before staticCache — I'm trying to control headers only for things that happened to also be served by this middleware.

Serve video (mp4) files?

i have video on my website:
<video controls>
<source src="/public/video/myvideo.mp4" type="video/mp4">
</video>

but it doesnt work, it is possible to serve videos like images?

the deeper path is not work

My directory is :

index.js
static/css/base.css

In index.js my code is:

var staticCache = require('koa-static-cache');
app.use(staticCache(__dirname));

then i request "http://localhost/static/css/base.css",it`s worked;

But when my code is:

var staticCache = require('koa-static-cache');
app.use(staticCache(__dirname + '/static'));

it`s not work, and I got a 404.

I get wrong file when I use koa-route and koa-static-cache together

My files like:

healthcheck.html
oniui/index.html
static/js/avalon.js

my app.js is:

app.use(route.get('/', function *() {
  this.redirect('/oniui/index.html');
}));

//healthcheck
app.use(route.get('/healthcheck.html', function *(next) {
    this.body = '';
}));

// static routes
app.use(staticCache(path.join(__dirname,'static'), {
  prefix: '/static'
}));
app.use(staticCache(path.join(__dirname,'oniui'), {
  prefix: '/oniui'
}));

I request http://localhost/static/js/avalon.js, and i got a file like:

2014-07-31 11 17 17

It`s incomplete.

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.