Fossil SCM

Move the /builtin webpage from style.c over to builtin.c. Add the new "m=" query parameter enabling it to return multiple JS files in a single request.

drh 2020-07-31 16:06 trunk
Commit 956d2f8db9534902a49eb3f29ea6e2e413f01d529f9ac5efbda1614adedb6e1f
3 files changed +111 -10 +1 -1 -36
+111 -10
--- src/builtin.c
+++ src/builtin.c
@@ -28,13 +28,15 @@
2828
** builtin_data.h file. Include that information here:
2929
*/
3030
#include "builtin_data.h"
3131
3232
/*
33
-** Return a pointer to built-in content
33
+** Return the index in the aBuiltinFiles[] array for the file
34
+** whose name is zFilename. Or return -1 if the file is not
35
+** found.
3436
*/
35
-const unsigned char *builtin_file(const char *zFilename, int *piSize){
37
+static int builtin_file_index(const char *zFilename){
3638
int lwr, upr, i, c;
3739
lwr = 0;
3840
upr = count(aBuiltinFiles) - 1;
3941
while( upr>=lwr ){
4042
i = (upr+lwr)/2;
@@ -42,16 +44,28 @@
4244
if( c<0 ){
4345
lwr = i+1;
4446
}else if( c>0 ){
4547
upr = i-1;
4648
}else{
47
- if( piSize ) *piSize = aBuiltinFiles[i].nByte;
48
- return aBuiltinFiles[i].pData;
49
+ return i;
4950
}
5051
}
51
- if( piSize ) *piSize = 0;
52
- return 0;
52
+ return -1;
53
+}
54
+
55
+/*
56
+** Return a pointer to built-in content
57
+*/
58
+const unsigned char *builtin_file(const char *zFilename, int *piSize){
59
+ int i = builtin_file_index(zFilename);
60
+ if( i>=0 ){
61
+ if( piSize ) *piSize = aBuiltinFiles[i].nByte;
62
+ return aBuiltinFiles[i].pData;
63
+ }else{
64
+ if( piSize ) *piSize = 0;
65
+ return 0;
66
+ }
5367
}
5468
const char *builtin_text(const char *zFilename){
5569
return (char*)builtin_file(zFilename, 0);
5670
}
5771
@@ -65,11 +79,11 @@
6579
*/
6680
void test_builtin_list(void){
6781
int i, size = 0;;
6882
for(i=0; i<count(aBuiltinFiles); i++){
6983
const int n = aBuiltinFiles[i].nByte;
70
- fossil_print("%-30s %6d\n", aBuiltinFiles[i].zName,n);
84
+ fossil_print("%3d. %-45s %6d\n", i+1, aBuiltinFiles[i].zName,n);
7185
size += n;
7286
}
7387
if(find_option("verbose","v",0)!=0){
7488
fossil_print("%d entries totaling %d bytes\n", i, size);
7589
}
@@ -81,16 +95,18 @@
8195
** Show all built-in text files.
8296
*/
8397
void test_builtin_list_page(void){
8498
int i;
8599
style_header("Built-in Text Files");
86
- @ <ul>
100
+ @ <ol>
87101
for(i=0; i<count(aBuiltinFiles); i++){
88102
const char *z = aBuiltinFiles[i].zName;
89
- @ <li>%z(href("%R/builtin?name=%T&id=%S",z,MANIFEST_UUID))%h(z)</a>
103
+ char *zUrl = href("%R/builtin?name=%T&id=%.8s&mimetype=text/plain",
104
+ z,fossil_exe_id());
105
+ @ <li>%z(zUrl)%h(z)</a>
90106
}
91
- @ </ul>
107
+ @ </ol>
92108
style_footer();
93109
}
94110
95111
/*
96112
** COMMAND: test-builtin-get
@@ -110,5 +126,90 @@
110126
}
111127
blob_init(&x, (const char*)pData, nByte);
112128
blob_write_to_file(&x, g.argc==4 ? g.argv[3] : "-");
113129
blob_reset(&x);
114130
}
131
+
132
+/*
133
+** Input zList is a list of numeric identifiers for files in
134
+** aBuiltinFiles[]. Return the concatenation of all of those
135
+** files using mimetype zType, or as application/javascript if
136
+** zType is 0.
137
+*/
138
+static void builtin_deliver_multiple_js_files(
139
+ const char *zList, /* List of numeric identifiers */
140
+ const char *zType /* Override mimetype */
141
+){
142
+ Blob *pOut;
143
+ if( zType==0 ) zType = "application/javascript";
144
+ cgi_set_content_type(zType);
145
+ pOut = cgi_output_blob();
146
+ while( zList[0] ){
147
+ int i = atoi(zList);
148
+ if( i>0 && i<=count(aBuiltinFiles) ){
149
+ blob_append(pOut, (const char*)aBuiltinFiles[i-1].pData,
150
+ aBuiltinFiles[i-1].nByte);
151
+ }
152
+ while( fossil_isdigit(zList[0]) ) zList++;
153
+ if( zList[0]==',' ) zList++;
154
+ }
155
+ return;
156
+}
157
+
158
+/*
159
+** WEBPAGE: builtin
160
+**
161
+** Return one of many built-in content files. Query parameters:
162
+**
163
+** name=FILENAME Return the single file whose name is FILENAME.
164
+** mimetype=TYPE Override the mimetype in the returned file to
165
+** be TYPE. If this query parameter is omitted
166
+** (the usual case) then the mimetype is inferred
167
+** from the suffix on FILENAME
168
+** m=IDLIST IDLIST is a comma-separated list of integers
169
+** that specify multiple javascript files to be
170
+** concatenated and returned all at once.
171
+** id=UNIQUEID Version number of the "builtin" files. Used
172
+** for cache control only.
173
+**
174
+** At least one of the name= or m= query parameters must be present.
175
+**
176
+** If the id= query parameter is present, then Fossil assumes that the
177
+** result is immutable and sets a very large cache retention time (1 year).
178
+*/
179
+void builtin_webpage(void){
180
+ Blob out;
181
+ const char *zName = P("name");
182
+ const char *zTxt = 0;
183
+ const char *zId = P("id");
184
+ const char *zType = P("mimetype");
185
+ int nId;
186
+ if( zName ) zTxt = builtin_text(zName);
187
+ if( zTxt==0 ){
188
+ const char *zM = P("m");
189
+ if( zM ){
190
+ builtin_deliver_multiple_js_files(zM, zType);
191
+ return;
192
+ }
193
+ cgi_set_status(404, "Not Found");
194
+ @ File "%h(zName)" not found
195
+ return;
196
+ }
197
+ if( zType==0 ){
198
+ if( sqlite3_strglob("*.js", zName)==0 ){
199
+ zType = "application/javascript";
200
+ }else{
201
+ zType = mimetype_from_name(zName);
202
+ }
203
+ }
204
+ cgi_set_content_type(zType);
205
+ if( zId
206
+ && (nId = (int)strlen(zId))>=8
207
+ && strncmp(zId,fossil_exe_id(),nId)==0
208
+ ){
209
+ g.isConst = 1;
210
+ }else{
211
+ etag_check(0,0);
212
+ }
213
+ blob_init(&out, zTxt, -1);
214
+ cgi_set_content(&out);
215
+}
115216
--- src/builtin.c
+++ src/builtin.c
@@ -28,13 +28,15 @@
28 ** builtin_data.h file. Include that information here:
29 */
30 #include "builtin_data.h"
31
32 /*
33 ** Return a pointer to built-in content
 
 
34 */
35 const unsigned char *builtin_file(const char *zFilename, int *piSize){
36 int lwr, upr, i, c;
37 lwr = 0;
38 upr = count(aBuiltinFiles) - 1;
39 while( upr>=lwr ){
40 i = (upr+lwr)/2;
@@ -42,16 +44,28 @@
42 if( c<0 ){
43 lwr = i+1;
44 }else if( c>0 ){
45 upr = i-1;
46 }else{
47 if( piSize ) *piSize = aBuiltinFiles[i].nByte;
48 return aBuiltinFiles[i].pData;
49 }
50 }
51 if( piSize ) *piSize = 0;
52 return 0;
 
 
 
 
 
 
 
 
 
 
 
 
 
53 }
54 const char *builtin_text(const char *zFilename){
55 return (char*)builtin_file(zFilename, 0);
56 }
57
@@ -65,11 +79,11 @@
65 */
66 void test_builtin_list(void){
67 int i, size = 0;;
68 for(i=0; i<count(aBuiltinFiles); i++){
69 const int n = aBuiltinFiles[i].nByte;
70 fossil_print("%-30s %6d\n", aBuiltinFiles[i].zName,n);
71 size += n;
72 }
73 if(find_option("verbose","v",0)!=0){
74 fossil_print("%d entries totaling %d bytes\n", i, size);
75 }
@@ -81,16 +95,18 @@
81 ** Show all built-in text files.
82 */
83 void test_builtin_list_page(void){
84 int i;
85 style_header("Built-in Text Files");
86 @ <ul>
87 for(i=0; i<count(aBuiltinFiles); i++){
88 const char *z = aBuiltinFiles[i].zName;
89 @ <li>%z(href("%R/builtin?name=%T&id=%S",z,MANIFEST_UUID))%h(z)</a>
 
 
90 }
91 @ </ul>
92 style_footer();
93 }
94
95 /*
96 ** COMMAND: test-builtin-get
@@ -110,5 +126,90 @@
110 }
111 blob_init(&x, (const char*)pData, nByte);
112 blob_write_to_file(&x, g.argc==4 ? g.argv[3] : "-");
113 blob_reset(&x);
114 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
115
--- src/builtin.c
+++ src/builtin.c
@@ -28,13 +28,15 @@
28 ** builtin_data.h file. Include that information here:
29 */
30 #include "builtin_data.h"
31
32 /*
33 ** Return the index in the aBuiltinFiles[] array for the file
34 ** whose name is zFilename. Or return -1 if the file is not
35 ** found.
36 */
37 static int builtin_file_index(const char *zFilename){
38 int lwr, upr, i, c;
39 lwr = 0;
40 upr = count(aBuiltinFiles) - 1;
41 while( upr>=lwr ){
42 i = (upr+lwr)/2;
@@ -42,16 +44,28 @@
44 if( c<0 ){
45 lwr = i+1;
46 }else if( c>0 ){
47 upr = i-1;
48 }else{
49 return i;
 
50 }
51 }
52 return -1;
53 }
54
55 /*
56 ** Return a pointer to built-in content
57 */
58 const unsigned char *builtin_file(const char *zFilename, int *piSize){
59 int i = builtin_file_index(zFilename);
60 if( i>=0 ){
61 if( piSize ) *piSize = aBuiltinFiles[i].nByte;
62 return aBuiltinFiles[i].pData;
63 }else{
64 if( piSize ) *piSize = 0;
65 return 0;
66 }
67 }
68 const char *builtin_text(const char *zFilename){
69 return (char*)builtin_file(zFilename, 0);
70 }
71
@@ -65,11 +79,11 @@
79 */
80 void test_builtin_list(void){
81 int i, size = 0;;
82 for(i=0; i<count(aBuiltinFiles); i++){
83 const int n = aBuiltinFiles[i].nByte;
84 fossil_print("%3d. %-45s %6d\n", i+1, aBuiltinFiles[i].zName,n);
85 size += n;
86 }
87 if(find_option("verbose","v",0)!=0){
88 fossil_print("%d entries totaling %d bytes\n", i, size);
89 }
@@ -81,16 +95,18 @@
95 ** Show all built-in text files.
96 */
97 void test_builtin_list_page(void){
98 int i;
99 style_header("Built-in Text Files");
100 @ <ol>
101 for(i=0; i<count(aBuiltinFiles); i++){
102 const char *z = aBuiltinFiles[i].zName;
103 char *zUrl = href("%R/builtin?name=%T&id=%.8s&mimetype=text/plain",
104 z,fossil_exe_id());
105 @ <li>%z(zUrl)%h(z)</a>
106 }
107 @ </ol>
108 style_footer();
109 }
110
111 /*
112 ** COMMAND: test-builtin-get
@@ -110,5 +126,90 @@
126 }
127 blob_init(&x, (const char*)pData, nByte);
128 blob_write_to_file(&x, g.argc==4 ? g.argv[3] : "-");
129 blob_reset(&x);
130 }
131
132 /*
133 ** Input zList is a list of numeric identifiers for files in
134 ** aBuiltinFiles[]. Return the concatenation of all of those
135 ** files using mimetype zType, or as application/javascript if
136 ** zType is 0.
137 */
138 static void builtin_deliver_multiple_js_files(
139 const char *zList, /* List of numeric identifiers */
140 const char *zType /* Override mimetype */
141 ){
142 Blob *pOut;
143 if( zType==0 ) zType = "application/javascript";
144 cgi_set_content_type(zType);
145 pOut = cgi_output_blob();
146 while( zList[0] ){
147 int i = atoi(zList);
148 if( i>0 && i<=count(aBuiltinFiles) ){
149 blob_append(pOut, (const char*)aBuiltinFiles[i-1].pData,
150 aBuiltinFiles[i-1].nByte);
151 }
152 while( fossil_isdigit(zList[0]) ) zList++;
153 if( zList[0]==',' ) zList++;
154 }
155 return;
156 }
157
158 /*
159 ** WEBPAGE: builtin
160 **
161 ** Return one of many built-in content files. Query parameters:
162 **
163 ** name=FILENAME Return the single file whose name is FILENAME.
164 ** mimetype=TYPE Override the mimetype in the returned file to
165 ** be TYPE. If this query parameter is omitted
166 ** (the usual case) then the mimetype is inferred
167 ** from the suffix on FILENAME
168 ** m=IDLIST IDLIST is a comma-separated list of integers
169 ** that specify multiple javascript files to be
170 ** concatenated and returned all at once.
171 ** id=UNIQUEID Version number of the "builtin" files. Used
172 ** for cache control only.
173 **
174 ** At least one of the name= or m= query parameters must be present.
175 **
176 ** If the id= query parameter is present, then Fossil assumes that the
177 ** result is immutable and sets a very large cache retention time (1 year).
178 */
179 void builtin_webpage(void){
180 Blob out;
181 const char *zName = P("name");
182 const char *zTxt = 0;
183 const char *zId = P("id");
184 const char *zType = P("mimetype");
185 int nId;
186 if( zName ) zTxt = builtin_text(zName);
187 if( zTxt==0 ){
188 const char *zM = P("m");
189 if( zM ){
190 builtin_deliver_multiple_js_files(zM, zType);
191 return;
192 }
193 cgi_set_status(404, "Not Found");
194 @ File "%h(zName)" not found
195 return;
196 }
197 if( zType==0 ){
198 if( sqlite3_strglob("*.js", zName)==0 ){
199 zType = "application/javascript";
200 }else{
201 zType = mimetype_from_name(zName);
202 }
203 }
204 cgi_set_content_type(zType);
205 if( zId
206 && (nId = (int)strlen(zId))>=8
207 && strncmp(zId,fossil_exe_id(),nId)==0
208 ){
209 g.isConst = 1;
210 }else{
211 etag_check(0,0);
212 }
213 blob_init(&out, zTxt, -1);
214 cgi_set_content(&out);
215 }
216
+1 -1
--- src/doc.c
+++ src/doc.c
@@ -147,11 +147,11 @@
147147
{ "jad", 3, "text/vnd.sun.j2me.app-descriptor" },
148148
{ "jar", 3, "application/java-archive" },
149149
{ "jpe", 3, "image/jpeg" },
150150
{ "jpeg", 4, "image/jpeg" },
151151
{ "jpg", 3, "image/jpeg" },
152
- { "js", 2, "application/x-javascript" },
152
+ { "js", 2, "application/javascript" },
153153
{ "kar", 3, "audio/midi" },
154154
{ "latex", 5, "application/x-latex" },
155155
{ "lha", 3, "application/octet-stream" },
156156
{ "lsp", 3, "application/x-lisp" },
157157
{ "lzh", 3, "application/octet-stream" },
158158
--- src/doc.c
+++ src/doc.c
@@ -147,11 +147,11 @@
147 { "jad", 3, "text/vnd.sun.j2me.app-descriptor" },
148 { "jar", 3, "application/java-archive" },
149 { "jpe", 3, "image/jpeg" },
150 { "jpeg", 4, "image/jpeg" },
151 { "jpg", 3, "image/jpeg" },
152 { "js", 2, "application/x-javascript" },
153 { "kar", 3, "audio/midi" },
154 { "latex", 5, "application/x-latex" },
155 { "lha", 3, "application/octet-stream" },
156 { "lsp", 3, "application/x-lisp" },
157 { "lzh", 3, "application/octet-stream" },
158
--- src/doc.c
+++ src/doc.c
@@ -147,11 +147,11 @@
147 { "jad", 3, "text/vnd.sun.j2me.app-descriptor" },
148 { "jar", 3, "application/java-archive" },
149 { "jpe", 3, "image/jpeg" },
150 { "jpeg", 4, "image/jpeg" },
151 { "jpg", 3, "image/jpeg" },
152 { "js", 2, "application/javascript" },
153 { "kar", 3, "audio/midi" },
154 { "latex", 5, "application/x-latex" },
155 { "lha", 3, "application/octet-stream" },
156 { "lsp", 3, "application/x-lisp" },
157 { "lzh", 3, "application/octet-stream" },
158
-36
--- src/style.c
+++ src/style.c
@@ -1127,46 +1127,10 @@
11271127
11281128
/* Tell CGI that the content returned by this page is considered cacheable */
11291129
g.isConst = 1;
11301130
}
11311131
1132
-/*
1133
-** WEBPAGE: builtin
1134
-** URL: builtin/FILENAME
1135
-**
1136
-** Return the built-in text given by FILENAME. This is used internally
1137
-** by many Fossil web pages to load built-in javascript files.
1138
-**
1139
-** If the id= query parameter is present, then Fossil assumes that the
1140
-** result is immutable and sets a very large cache retention time (1 year).
1141
-*/
1142
-void page_builtin_text(void){
1143
- Blob out;
1144
- const char *zName = P("name");
1145
- const char *zTxt = 0;
1146
- const char *zId = P("id");
1147
- int nId;
1148
- if( zName ) zTxt = builtin_text(zName);
1149
- if( zTxt==0 ){
1150
- cgi_set_status(404, "Not Found");
1151
- @ File "%h(zName)" not found
1152
- return;
1153
- }
1154
- if( sqlite3_strglob("*.js", zName)==0 ){
1155
- cgi_set_content_type("application/javascript");
1156
- }else{
1157
- cgi_set_content_type("text/plain");
1158
- }
1159
- if( zId && (nId = (int)strlen(zId))>=8 && strncmp(zId,MANIFEST_UUID,nId)==0 ){
1160
- g.isConst = 1;
1161
- }else{
1162
- etag_check(0,0);
1163
- }
1164
- blob_init(&out, zTxt, -1);
1165
- cgi_set_content(&out);
1166
-}
1167
-
11681132
/*
11691133
** All possible capabilities
11701134
*/
11711135
static const char allCap[] =
11721136
"abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKL";
11731137
--- src/style.c
+++ src/style.c
@@ -1127,46 +1127,10 @@
1127
1128 /* Tell CGI that the content returned by this page is considered cacheable */
1129 g.isConst = 1;
1130 }
1131
1132 /*
1133 ** WEBPAGE: builtin
1134 ** URL: builtin/FILENAME
1135 **
1136 ** Return the built-in text given by FILENAME. This is used internally
1137 ** by many Fossil web pages to load built-in javascript files.
1138 **
1139 ** If the id= query parameter is present, then Fossil assumes that the
1140 ** result is immutable and sets a very large cache retention time (1 year).
1141 */
1142 void page_builtin_text(void){
1143 Blob out;
1144 const char *zName = P("name");
1145 const char *zTxt = 0;
1146 const char *zId = P("id");
1147 int nId;
1148 if( zName ) zTxt = builtin_text(zName);
1149 if( zTxt==0 ){
1150 cgi_set_status(404, "Not Found");
1151 @ File "%h(zName)" not found
1152 return;
1153 }
1154 if( sqlite3_strglob("*.js", zName)==0 ){
1155 cgi_set_content_type("application/javascript");
1156 }else{
1157 cgi_set_content_type("text/plain");
1158 }
1159 if( zId && (nId = (int)strlen(zId))>=8 && strncmp(zId,MANIFEST_UUID,nId)==0 ){
1160 g.isConst = 1;
1161 }else{
1162 etag_check(0,0);
1163 }
1164 blob_init(&out, zTxt, -1);
1165 cgi_set_content(&out);
1166 }
1167
1168 /*
1169 ** All possible capabilities
1170 */
1171 static const char allCap[] =
1172 "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKL";
1173
--- src/style.c
+++ src/style.c
@@ -1127,46 +1127,10 @@
1127
1128 /* Tell CGI that the content returned by this page is considered cacheable */
1129 g.isConst = 1;
1130 }
1131
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1132 /*
1133 ** All possible capabilities
1134 */
1135 static const char allCap[] =
1136 "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKL";
1137

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button