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;%% ]] |