Static.patch
| upp-production/uppsrc/Skylark/Http.h (working copy) | ||
|---|---|---|
| 1 | 1 |
void MakeLink(StringBuffer& out, const Vector<String>& part, const Vector<Value>& arg); |
| 2 |
void ServeStaticPage(Http& http); |
|
| 2 | 3 | |
| 3 | 4 |
struct HandlerId {
|
| 4 | 5 |
void (*handler)(Http& http); |
| upp-production/uppsrc/Skylark/Static.icpp (working copy) | ||
|---|---|---|
| 1 | 1 |
#include "Skylark.h" |
| 2 | 2 | |
| 3 | 3 |
namespace Upp {
|
| 4 |
namespace Ini {
|
|
| 5 |
INI_INT(caching, 1, "Agressivity of caching on static/** " |
|
| 6 |
"(0=no caching, 1=use ETag header, 2=use versioned path)"); |
|
| 7 |
} |
|
| 4 | 8 | |
| 9 |
Value CachedStatic(const Vector<Value>& arg, const Renderer *) |
|
| 10 |
{
|
|
| 11 |
String file = arg[0]; |
|
| 12 |
if(Ini::caching != 2) |
|
| 13 |
return "/"+SkylarkApp::Config().static_dir+"/"+file; |
|
| 14 |
|
|
| 15 |
String path = GetFileOnPath(file, SkylarkApp::Config().path, false); |
|
| 16 |
if(path.GetCount()){
|
|
| 17 |
return SkylarkApp::Config().static_dir+"/ver"+IntStr64(GetFileTime(path).ft)+"/"+file; |
|
| 18 |
} |
|
| 19 |
} |
|
| 20 |
|
|
| 21 |
INITBLOCK {
|
|
| 22 |
Compiler::Register("CachedStatic", CachedStatic);
|
|
| 23 |
}; |
|
| 24 |
|
|
| 5 | 25 |
SKYLARK(ServeStaticPage, "static/**") |
| 6 | 26 |
{
|
| 7 | 27 |
String file; |
| ... | ... | |
| 10 | 30 |
file << '/'; |
| 11 | 31 |
file << http[i]; |
| 12 | 32 |
} |
| 33 |
|
|
| 34 |
if(Ini::caching == 2 && file.StartsWith("ver"))
|
|
| 35 |
file = file.Mid(sizeof("ver1348339260"));
|
|
| 36 |
|
|
| 13 | 37 |
String path = GetFileOnPath(file, SkylarkApp::Config().path, false); |
| 14 |
if(path.GetCount()) {
|
|
| 15 |
String ext = ToLower(GetFileExt(file)); |
|
| 16 |
String type = "text"; |
|
| 17 |
if(ext == ".css") |
|
| 18 |
type = "text/css"; |
|
| 19 |
else |
|
| 20 |
if(ext == ".js") |
|
| 21 |
type = "text/javascript"; |
|
| 22 |
else |
|
| 23 |
if(ext == ".png" || ext == ".jpg" || ext == ".gif") |
|
| 24 |
type = "image/" + ext.Mid(1); |
|
| 25 |
http.Content(type, LoadFile(path)); |
|
| 38 |
if(!path.GetCount()) {
|
|
| 39 |
http.Response(404, "Not found"); |
|
| 40 |
return; |
|
| 26 | 41 |
} |
| 42 |
|
|
| 43 |
String ext = ToLower(GetFileExt(file)); |
|
| 44 |
String type = "text"; |
|
| 45 |
if(ext == ".css") |
|
| 46 |
type = "text/css"; |
|
| 47 |
else |
|
| 48 |
if(ext == ".js") |
|
| 49 |
type = "text/javascript"; |
|
| 50 |
else |
|
| 51 |
if(ext == ".png" || ext == ".jpg" || ext == ".gif") |
|
| 52 |
type = "image/" + ext.Mid(1); |
|
| 53 |
|
|
| 54 |
if(Ini::caching > 0) {
|
|
| 55 |
String tag = IntStr64(GetFileTime(path).ft); |
|
| 56 |
http.SetHeader("Cache-Control", "public, max-age=2592000");
|
|
| 57 |
http.SetHeader("ETag", tag);
|
|
| 58 |
if(http.GetHeader("if-none-match") == tag){
|
|
| 59 |
http.Response(304, "Not Modified"); |
|
| 60 |
return; |
|
| 61 |
} |
|
| 62 |
} |
|
| 63 |
|
|
| 64 |
http.Content(type, LoadFile(path)); |
|
| 27 | 65 |
} |
| 28 | 66 | |
| 29 | 67 |
}; |
| upp-production/uppsrc/Skylark/src.tpp/Static$en-us.tpp (working copy) | ||
|---|---|---|
| 1 |
topic ""; |
|
| 2 |
[2 $$0,0#00000000000000000000000000000000:Default] |
|
| 3 |
[i448;a25;kKO9;2 $$1,0#37138531426314131252341829483380:class] |
|
| 4 |
[l288;2 $$2,2#27521748481378242620020725143825:desc] |
|
| 5 |
[0 $$3,0#96390100711032703541132217272105:end] |
|
| 6 |
[H6;0 $$4,0#05600065144404261032431302351956:begin] |
|
| 7 |
[i448;a25;kKO9;2 $$5,0#37138531426314131252341829483370:item] |
|
| 8 |
[l288;a4;*@5;1 $$6,6#70004532496200323422659154056402:requirement] |
|
| 9 |
[l288;i1121;b17;O9;~~~.1408;2 $$7,0#10431211400427159095818037425705:param] |
|
| 10 |
[i448;b42;O9;2 $$8,8#61672508125594000341940100500538:tparam] |
|
| 11 |
[b42;2 $$9,9#13035079074754324216151401829390:normal] |
|
| 12 |
[{_}
|
|
| 13 |
[ {{10000@(113.42.0) [s0;%% [*@7;4 Serving static files]]}}&]
|
|
| 14 |
[s0;i448;a25;kKO9;@(0.0.255) &] |
|
| 15 |
[ {{10000F(128)G(128)@1 [s0;%% [* Function List]]}}&]
|
|
| 16 |
[s4; &] |
|
| 17 |
[s5;:ServeStaticPage`(Http`&`): [@(0.0.255) void]_[* ServeStaticPage]([_^Http^ Http][@(0.0.255) `& |
|
| 18 |
]_[*@3 http])&] |
|
| 19 |
[s2;%% Skylark handler for serving static files placed on [^topic`:`/`/Skylark`/src`/Config`$en`-us`#SkylarkConfig`:`:path^ p |
|
| 20 |
ath] given in configuration. Files will be served with mime`-type |
|
| 21 |
based on the extension. Recognized extensions are jpg, png, gif, |
|
| 22 |
js and css. Files with unknown extensions are served as text. |
|
| 23 |
The Ini variable [*@3 caching] can be used to set behavior of the |
|
| 24 |
caching. Currently supported values are 0`=no caching, 1`=use |
|
| 25 |
ETag header (allows browser to check if the content was modified, |
|
| 26 |
without downloading the file), 2`=use versioned path like [/ /static/ver1345496224/ |
|
| 27 |
favicon.png] that allows to use very strong caching while ensuring |
|
| 28 |
that when the file is change it will be immediately updated on |
|
| 29 |
clients browser as well. Both ETag header value and the version |
|
| 30 |
string are the timestamp of the served file.&] |
|
| 31 |
[s3;%% &] |
|
| 32 |
[s4; &] |
|
| 33 |
[s5;:CachedStatic`(const Vector`<Value`>`&`,const Renderer`*`): [_^Value^ Value]_[* Cache |
|
| 34 |
dStatic](Value filename)&] |
|
| 35 |
[s2;%% A [^topic`:`/`/Skylark`/src`/Witz`$en`-us^ witz function] intended |
|
| 36 |
as a helper to allow advanced caching of static files through |
|
| 37 |
the ServeStaticPage handler. It takes only one argument, the |
|
| 38 |
file to be served.&] |
|
| 39 |
[s3;%% &] |
|
| 40 |
[s0;%% ]] |
|