Fossil SCM

ETags now working for the /uv page.

drh 2018-02-24 03:38 UTC etags-cache-control
Commit 5b84cab0d6d0dd8ac6820d68e7c76e55e025747f9fed7211aaa01485cc7be4bd
+8 -5
--- src/doc.c
+++ src/doc.c
@@ -639,15 +639,18 @@
639639
}else{
640640
goto doc_not_found;
641641
}
642642
}
643643
if( isUV ){
644
- if( db_table_exists("repository","unversioned")
645
- && unversioned_content(zName, &filebody)==0
646
- ){
647
- rid = 1;
648
- zDfltTitle = zName;
644
+ if( db_table_exists("repository","unversioned") ){
645
+ char *zHash;
646
+ zHash = db_text(0, "SELECT hash FROM unversioned WHERE name=%Q",zName);
647
+ etag_require_hash(zHash);
648
+ if( unversioned_content(zName, &filebody)==0 ){
649
+ rid = 1;
650
+ zDfltTitle = zName;
651
+ }
649652
}
650653
}else if( fossil_strcmp(zCheckin,"ckout")==0 ){
651654
/* Read from the local checkout */
652655
char *zFullpath;
653656
db_must_be_within_tree();
654657
--- src/doc.c
+++ src/doc.c
@@ -639,15 +639,18 @@
639 }else{
640 goto doc_not_found;
641 }
642 }
643 if( isUV ){
644 if( db_table_exists("repository","unversioned")
645 && unversioned_content(zName, &filebody)==0
646 ){
647 rid = 1;
648 zDfltTitle = zName;
 
 
 
649 }
650 }else if( fossil_strcmp(zCheckin,"ckout")==0 ){
651 /* Read from the local checkout */
652 char *zFullpath;
653 db_must_be_within_tree();
654
--- src/doc.c
+++ src/doc.c
@@ -639,15 +639,18 @@
639 }else{
640 goto doc_not_found;
641 }
642 }
643 if( isUV ){
644 if( db_table_exists("repository","unversioned") ){
645 char *zHash;
646 zHash = db_text(0, "SELECT hash FROM unversioned WHERE name=%Q",zName);
647 etag_require_hash(zHash);
648 if( unversioned_content(zName, &filebody)==0 ){
649 rid = 1;
650 zDfltTitle = zName;
651 }
652 }
653 }else if( fossil_strcmp(zCheckin,"ckout")==0 ){
654 /* Read from the local checkout */
655 char *zFullpath;
656 db_must_be_within_tree();
657
+142 -30
--- src/etag.c
+++ src/etag.c
@@ -26,10 +26,35 @@
2626
** Output "304 Not Modified" message and abort;
2727
**
2828
** In other words, if all conditions specified by the ETag are met, then
2929
** Fossil will return a 304 and avoid doing all the work, and all of the
3030
** bandwidth, associating with regenerating the whole page.
31
+**
32
+** To make use of this feature, page generators can invoke the
33
+** etag_require() interface with mask of ETAG_CONST, ETAG_CONFIG,
34
+** ETAG_DATA, and/or ETAG_COOKIE. Or it can invoke etag_require_hash()
35
+** with some kind of text hash.
36
+**
37
+** Or, in the WEBPAGE: line for the page generator, extra arguments
38
+** can be added. "const", "config", "data", and/or "cookie"
39
+**
40
+** ETAG_CONST const The reply is always the same for the same
41
+** build of the fossil binary. The content
42
+** is independent of the repository.
43
+**
44
+** ETAG_CONFIG config The reply is the same as long as the repository
45
+** config is constant.
46
+**
47
+** ETAG_DATA data The reply is the same as long as no new artifacts
48
+** are added to the repository
49
+**
50
+** ETAG_COOKIE cookie The reply is the same as long as the display
51
+** cookie is unchanged.
52
+**
53
+** Page generator routines can also invoke etag_require_hash(HASH) where
54
+** HASH is some string. In that case, the reply is the same as long as
55
+** the hash is the same.
3156
*/
3257
#include "config.h"
3358
#include "etag.h"
3459
3560
#if INTERFACE
@@ -38,38 +63,133 @@
3863
*/
3964
#define ETAG_CONST 0x00 /* Output is independent of database or parameters */
4065
#define ETAG_CONFIG 0x01 /* Output depends on the configuration */
4166
#define ETAG_DATA 0x02 /* Output depends on 'event' table */
4267
#define ETAG_COOKIE 0x04 /* Output depends on a display cookie value */
43
-#define ETAG_DYNAMIC 0x08 /* Output is always different */
68
+#define ETAG_HASH 0x08 /* Output depends on a hash */
69
+#define ETAG_DYNAMIC 0x10 /* Output is always different */
4470
#endif
4571
4672
/* Set of all etag requirements */
47
-static int mEtag = 0;
73
+static int mEtag = 0; /* Mask of requirements */
74
+static const char *zEHash = 0; /* Hash value if ETAG_HASH is set */
75
+
76
+
77
+/* Check an ETag to see if all conditions are valid. If all conditions are
78
+** valid, then return true. If any condition is false, return false.
79
+*/
80
+static int etag_valid(const char *zTag){
81
+ int iKey;
82
+ char *zCk;
83
+ int rc;
84
+ int nTag;
85
+ if( zTag==0 || zTag[0]<=0 ) return 0;
86
+ nTag = (int)strlen(zTag);
87
+ if( zTag[0]=='"' && zTag[nTag-1]=='"' ){
88
+ zTag++;
89
+ nTag -= 2;
90
+ }
91
+ iKey = zTag[0] - '0';
92
+ zCk = etag_generate(iKey);
93
+ rc = nTag==(int)strlen(zCk) && strncmp(zCk, zTag, nTag)==0;
94
+ fossil_free(zCk);
95
+ if( rc ) mEtag = iKey;
96
+ return rc;
97
+}
98
+
99
+/*
100
+** Check to see if there is an If-None-Match: header that
101
+** matches the current etag settings. If there is, then
102
+** generate a 304 Not Modified reply.
103
+**
104
+** This routine exits and does not return if the 304 Not Modified
105
+** reply is generated.
106
+**
107
+** If the etag does not match, the routine returns normally.
108
+*/
109
+static void etag_check(void){
110
+ const char *zETag = P("HTTP_IF_NONE_MATCH");
111
+ if( zETag==0 ) return;
112
+ if( !etag_valid(zETag) ) return;
113
+
114
+ /* If we get this far, it means that the content has
115
+ ** not changed and we can do a 304 reply */
116
+ cgi_reset_content();
117
+ cgi_set_status(304, "Not Modified");
118
+ cgi_reply();
119
+ fossil_exit(0);
120
+}
121
+
48122
49
-/* Add one or more new etag requirements */
123
+/* Add one or more new etag requirements.
124
+**
125
+** Page generator logic invokes one or both of these methods to signal
126
+** under what conditions page generation can be skipped
127
+**
128
+** After each call to these routines, the HTTP_IF_NONE_MATCH cookie
129
+** is checked, and if it contains a compatible ETag, then a
130
+** 304 Not Modified return is generated and execution aborts. This
131
+** routine does not return if the 304 is generated.
132
+*/
50133
void etag_require(int code){
51134
mEtag |= code;
135
+ etag_check();
136
+}
137
+void etag_require_hash(const char *zHash){
138
+ if( zHash ){
139
+ zEHash = zHash;
140
+ mEtag = ETAG_HASH;
141
+ etag_check();
142
+ }
52143
}
53144
54
-/* Return an appropriate max-age */
145
+/* Return an appropriate max-age.
146
+*/
55147
int etag_maxage(void){
56148
if( mEtag ) return 1;
57149
return 3600*24;
58150
}
59151
60152
/* Generate an appropriate ETags value that captures all requirements.
61153
** Space is obtained from fossil_malloc().
154
+**
155
+** The argument is the mask of attributes to include in the ETag.
156
+** If the argument is -1 then whatever mask is found from prior
157
+** calls to etag_require() and etag_require_hash() is used.
158
+**
159
+** Format:
160
+**
161
+** <mask><exec-mtime>/<data-or-config-key>/<cookie>/<hash>
162
+**
163
+** The <mask> is a single-character decimal number that is the mask of
164
+** all required attributes:
165
+**
166
+** ETAG_CONFIG: 1
167
+** ETAG_DATA: 2
168
+** ETAG_COOKIE: 4
169
+** ETAG_HASH: 8
170
+**
171
+** If ETAG_HASH is present, the others are omitted, so the number is
172
+** never greater than 8.
173
+**
174
+** The <exec-mtime> is the mtime of the Fossil executable. Since this
175
+** is part of the ETag, it means that recompiling or just "touch"-ing the
176
+** fossil binary is sufficient to invalidate all prior caches.
177
+**
178
+** The other elements are only present if the appropriate mask bits
179
+** appear in the first character.
62180
*/
63181
char *etag_generate(int m){
64182
Blob x = BLOB_INITIALIZER;
65183
int mtime;
66184
if( m<0 ) m = mEtag;
67185
if( m & ETAG_DYNAMIC ) return 0;
68186
mtime = file_mtime(g.nameOfExe, ExtFILE);
69187
blob_appendf(&x,"%d%x", m, mtime);
70
- if( m & ETAG_DATA ){
188
+ if( m & ETAG_HASH ){
189
+ blob_appendf(&x, "/%s", zEHash);
190
+ }else if( m & ETAG_DATA ){
71191
int iKey = db_int(0, "SELECT max(rcvid) FROM rcvfrom");
72192
blob_appendf(&x, "/%x", iKey);
73193
}else if( m & ETAG_CONFIG ){
74194
int iKey = db_int(0, "SELECT value FROM config WHERE name='cfgcnt'");
75195
blob_appendf(&x, "/%x", iKey);
@@ -80,37 +200,29 @@
80200
return blob_str(&x);
81201
}
82202
83203
/*
84204
** COMMAND: test-etag
205
+**
206
+** Usage: fossil test-etag -key KEY-NUMBER -hash HASH
207
+**
208
+** Generate an etag given a KEY-NUMBER and/or a HASH.
209
+**
210
+** KEY-NUMBER is some combination of:
211
+**
212
+** 1 ETAG_CONFIG The config table version number
213
+** 2 ETAG_DATA The event table version number
214
+** 4 ETAG_COOKIE The display cookie
85215
*/
86216
void test_etag_cmd(void){
87
- int iKey;
88217
char *zTag;
218
+ const char *zHash;
219
+ const char *zKey;
89220
db_find_and_open_repository(0, 0);
90
- iKey = g.argc>2 ? atoi(g.argv[2]) : 0;
91
- zTag = etag_generate(iKey);
221
+ zKey = find_option("key",0,1);
222
+ zHash = find_option("hash",0,1);
223
+ if( zKey ) etag_require(atoi(zKey));
224
+ if( zHash ) etag_require_hash(zHash);
225
+ zTag = etag_generate(mEtag);
92226
fossil_print("%s\n", zTag);
93227
fossil_free(zTag);
94228
}
95
-
96
-/* Check an ETag to see if all conditions are valid. If all conditions are
97
-** valid, then return true.
98
-*/
99
-int etag_valid(const char *zTag){
100
- int iKey;
101
- char *zCk;
102
- int rc;
103
- int nTag;
104
- if( zTag==0 || zTag[0]<=0 || zTag[0]>=5 ) return 0;
105
- nTag = (int)strlen(zTag);
106
- if( zTag[0]=='"' && zTag[nTag-1]=='"' ){
107
- zTag++;
108
- nTag -= 2;
109
- }
110
- iKey = zTag[0] - '0';
111
- zCk = etag_generate(iKey);
112
- rc = nTag==(int)strlen(zCk) && strncmp(zCk, zTag, nTag)==0;
113
- fossil_free(zCk);
114
- if( rc ) mEtag = iKey;
115
- return rc;
116
-}
117229
--- src/etag.c
+++ src/etag.c
@@ -26,10 +26,35 @@
26 ** Output "304 Not Modified" message and abort;
27 **
28 ** In other words, if all conditions specified by the ETag are met, then
29 ** Fossil will return a 304 and avoid doing all the work, and all of the
30 ** bandwidth, associating with regenerating the whole page.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
31 */
32 #include "config.h"
33 #include "etag.h"
34
35 #if INTERFACE
@@ -38,38 +63,133 @@
38 */
39 #define ETAG_CONST 0x00 /* Output is independent of database or parameters */
40 #define ETAG_CONFIG 0x01 /* Output depends on the configuration */
41 #define ETAG_DATA 0x02 /* Output depends on 'event' table */
42 #define ETAG_COOKIE 0x04 /* Output depends on a display cookie value */
43 #define ETAG_DYNAMIC 0x08 /* Output is always different */
 
44 #endif
45
46 /* Set of all etag requirements */
47 static int mEtag = 0;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
48
49 /* Add one or more new etag requirements */
 
 
 
 
 
 
 
 
 
50 void etag_require(int code){
51 mEtag |= code;
 
 
 
 
 
 
 
 
52 }
53
54 /* Return an appropriate max-age */
 
55 int etag_maxage(void){
56 if( mEtag ) return 1;
57 return 3600*24;
58 }
59
60 /* Generate an appropriate ETags value that captures all requirements.
61 ** Space is obtained from fossil_malloc().
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
62 */
63 char *etag_generate(int m){
64 Blob x = BLOB_INITIALIZER;
65 int mtime;
66 if( m<0 ) m = mEtag;
67 if( m & ETAG_DYNAMIC ) return 0;
68 mtime = file_mtime(g.nameOfExe, ExtFILE);
69 blob_appendf(&x,"%d%x", m, mtime);
70 if( m & ETAG_DATA ){
 
 
71 int iKey = db_int(0, "SELECT max(rcvid) FROM rcvfrom");
72 blob_appendf(&x, "/%x", iKey);
73 }else if( m & ETAG_CONFIG ){
74 int iKey = db_int(0, "SELECT value FROM config WHERE name='cfgcnt'");
75 blob_appendf(&x, "/%x", iKey);
@@ -80,37 +200,29 @@
80 return blob_str(&x);
81 }
82
83 /*
84 ** COMMAND: test-etag
 
 
 
 
 
 
 
 
 
 
85 */
86 void test_etag_cmd(void){
87 int iKey;
88 char *zTag;
 
 
89 db_find_and_open_repository(0, 0);
90 iKey = g.argc>2 ? atoi(g.argv[2]) : 0;
91 zTag = etag_generate(iKey);
 
 
 
92 fossil_print("%s\n", zTag);
93 fossil_free(zTag);
94 }
95
96 /* Check an ETag to see if all conditions are valid. If all conditions are
97 ** valid, then return true.
98 */
99 int etag_valid(const char *zTag){
100 int iKey;
101 char *zCk;
102 int rc;
103 int nTag;
104 if( zTag==0 || zTag[0]<=0 || zTag[0]>=5 ) return 0;
105 nTag = (int)strlen(zTag);
106 if( zTag[0]=='"' && zTag[nTag-1]=='"' ){
107 zTag++;
108 nTag -= 2;
109 }
110 iKey = zTag[0] - '0';
111 zCk = etag_generate(iKey);
112 rc = nTag==(int)strlen(zCk) && strncmp(zCk, zTag, nTag)==0;
113 fossil_free(zCk);
114 if( rc ) mEtag = iKey;
115 return rc;
116 }
117
--- src/etag.c
+++ src/etag.c
@@ -26,10 +26,35 @@
26 ** Output "304 Not Modified" message and abort;
27 **
28 ** In other words, if all conditions specified by the ETag are met, then
29 ** Fossil will return a 304 and avoid doing all the work, and all of the
30 ** bandwidth, associating with regenerating the whole page.
31 **
32 ** To make use of this feature, page generators can invoke the
33 ** etag_require() interface with mask of ETAG_CONST, ETAG_CONFIG,
34 ** ETAG_DATA, and/or ETAG_COOKIE. Or it can invoke etag_require_hash()
35 ** with some kind of text hash.
36 **
37 ** Or, in the WEBPAGE: line for the page generator, extra arguments
38 ** can be added. "const", "config", "data", and/or "cookie"
39 **
40 ** ETAG_CONST const The reply is always the same for the same
41 ** build of the fossil binary. The content
42 ** is independent of the repository.
43 **
44 ** ETAG_CONFIG config The reply is the same as long as the repository
45 ** config is constant.
46 **
47 ** ETAG_DATA data The reply is the same as long as no new artifacts
48 ** are added to the repository
49 **
50 ** ETAG_COOKIE cookie The reply is the same as long as the display
51 ** cookie is unchanged.
52 **
53 ** Page generator routines can also invoke etag_require_hash(HASH) where
54 ** HASH is some string. In that case, the reply is the same as long as
55 ** the hash is the same.
56 */
57 #include "config.h"
58 #include "etag.h"
59
60 #if INTERFACE
@@ -38,38 +63,133 @@
63 */
64 #define ETAG_CONST 0x00 /* Output is independent of database or parameters */
65 #define ETAG_CONFIG 0x01 /* Output depends on the configuration */
66 #define ETAG_DATA 0x02 /* Output depends on 'event' table */
67 #define ETAG_COOKIE 0x04 /* Output depends on a display cookie value */
68 #define ETAG_HASH 0x08 /* Output depends on a hash */
69 #define ETAG_DYNAMIC 0x10 /* Output is always different */
70 #endif
71
72 /* Set of all etag requirements */
73 static int mEtag = 0; /* Mask of requirements */
74 static const char *zEHash = 0; /* Hash value if ETAG_HASH is set */
75
76
77 /* Check an ETag to see if all conditions are valid. If all conditions are
78 ** valid, then return true. If any condition is false, return false.
79 */
80 static int etag_valid(const char *zTag){
81 int iKey;
82 char *zCk;
83 int rc;
84 int nTag;
85 if( zTag==0 || zTag[0]<=0 ) return 0;
86 nTag = (int)strlen(zTag);
87 if( zTag[0]=='"' && zTag[nTag-1]=='"' ){
88 zTag++;
89 nTag -= 2;
90 }
91 iKey = zTag[0] - '0';
92 zCk = etag_generate(iKey);
93 rc = nTag==(int)strlen(zCk) && strncmp(zCk, zTag, nTag)==0;
94 fossil_free(zCk);
95 if( rc ) mEtag = iKey;
96 return rc;
97 }
98
99 /*
100 ** Check to see if there is an If-None-Match: header that
101 ** matches the current etag settings. If there is, then
102 ** generate a 304 Not Modified reply.
103 **
104 ** This routine exits and does not return if the 304 Not Modified
105 ** reply is generated.
106 **
107 ** If the etag does not match, the routine returns normally.
108 */
109 static void etag_check(void){
110 const char *zETag = P("HTTP_IF_NONE_MATCH");
111 if( zETag==0 ) return;
112 if( !etag_valid(zETag) ) return;
113
114 /* If we get this far, it means that the content has
115 ** not changed and we can do a 304 reply */
116 cgi_reset_content();
117 cgi_set_status(304, "Not Modified");
118 cgi_reply();
119 fossil_exit(0);
120 }
121
122
123 /* Add one or more new etag requirements.
124 **
125 ** Page generator logic invokes one or both of these methods to signal
126 ** under what conditions page generation can be skipped
127 **
128 ** After each call to these routines, the HTTP_IF_NONE_MATCH cookie
129 ** is checked, and if it contains a compatible ETag, then a
130 ** 304 Not Modified return is generated and execution aborts. This
131 ** routine does not return if the 304 is generated.
132 */
133 void etag_require(int code){
134 mEtag |= code;
135 etag_check();
136 }
137 void etag_require_hash(const char *zHash){
138 if( zHash ){
139 zEHash = zHash;
140 mEtag = ETAG_HASH;
141 etag_check();
142 }
143 }
144
145 /* Return an appropriate max-age.
146 */
147 int etag_maxage(void){
148 if( mEtag ) return 1;
149 return 3600*24;
150 }
151
152 /* Generate an appropriate ETags value that captures all requirements.
153 ** Space is obtained from fossil_malloc().
154 **
155 ** The argument is the mask of attributes to include in the ETag.
156 ** If the argument is -1 then whatever mask is found from prior
157 ** calls to etag_require() and etag_require_hash() is used.
158 **
159 ** Format:
160 **
161 ** <mask><exec-mtime>/<data-or-config-key>/<cookie>/<hash>
162 **
163 ** The <mask> is a single-character decimal number that is the mask of
164 ** all required attributes:
165 **
166 ** ETAG_CONFIG: 1
167 ** ETAG_DATA: 2
168 ** ETAG_COOKIE: 4
169 ** ETAG_HASH: 8
170 **
171 ** If ETAG_HASH is present, the others are omitted, so the number is
172 ** never greater than 8.
173 **
174 ** The <exec-mtime> is the mtime of the Fossil executable. Since this
175 ** is part of the ETag, it means that recompiling or just "touch"-ing the
176 ** fossil binary is sufficient to invalidate all prior caches.
177 **
178 ** The other elements are only present if the appropriate mask bits
179 ** appear in the first character.
180 */
181 char *etag_generate(int m){
182 Blob x = BLOB_INITIALIZER;
183 int mtime;
184 if( m<0 ) m = mEtag;
185 if( m & ETAG_DYNAMIC ) return 0;
186 mtime = file_mtime(g.nameOfExe, ExtFILE);
187 blob_appendf(&x,"%d%x", m, mtime);
188 if( m & ETAG_HASH ){
189 blob_appendf(&x, "/%s", zEHash);
190 }else if( m & ETAG_DATA ){
191 int iKey = db_int(0, "SELECT max(rcvid) FROM rcvfrom");
192 blob_appendf(&x, "/%x", iKey);
193 }else if( m & ETAG_CONFIG ){
194 int iKey = db_int(0, "SELECT value FROM config WHERE name='cfgcnt'");
195 blob_appendf(&x, "/%x", iKey);
@@ -80,37 +200,29 @@
200 return blob_str(&x);
201 }
202
203 /*
204 ** COMMAND: test-etag
205 **
206 ** Usage: fossil test-etag -key KEY-NUMBER -hash HASH
207 **
208 ** Generate an etag given a KEY-NUMBER and/or a HASH.
209 **
210 ** KEY-NUMBER is some combination of:
211 **
212 ** 1 ETAG_CONFIG The config table version number
213 ** 2 ETAG_DATA The event table version number
214 ** 4 ETAG_COOKIE The display cookie
215 */
216 void test_etag_cmd(void){
 
217 char *zTag;
218 const char *zHash;
219 const char *zKey;
220 db_find_and_open_repository(0, 0);
221 zKey = find_option("key",0,1);
222 zHash = find_option("hash",0,1);
223 if( zKey ) etag_require(atoi(zKey));
224 if( zHash ) etag_require_hash(zHash);
225 zTag = etag_generate(mEtag);
226 fossil_print("%s\n", zTag);
227 fossil_free(zTag);
228 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
229
-9
--- src/main.c
+++ src/main.c
@@ -1629,19 +1629,10 @@
16291629
** payload, then pretend that the PATH_INFO is /xfer so that we always
16301630
** invoke the sync page. */
16311631
zPathInfo = "/xfer";
16321632
}
16331633
1634
- /* Check for an ETAG line
1635
- */
1636
- zETag = P("HTTP_IF_NONE_MATCH");
1637
- if( etag_valid(zETag) ){
1638
- cgi_set_status(304, "Not Modified");
1639
- cgi_reply();
1640
- return;
1641
- }
1642
-
16431634
/* Use the first element of PATH_INFO as the page name
16441635
** and deliver the appropriate page back to the user.
16451636
*/
16461637
set_base_url(0);
16471638
if( zPathInfo==0 || zPathInfo[0]==0
16481639
--- src/main.c
+++ src/main.c
@@ -1629,19 +1629,10 @@
1629 ** payload, then pretend that the PATH_INFO is /xfer so that we always
1630 ** invoke the sync page. */
1631 zPathInfo = "/xfer";
1632 }
1633
1634 /* Check for an ETAG line
1635 */
1636 zETag = P("HTTP_IF_NONE_MATCH");
1637 if( etag_valid(zETag) ){
1638 cgi_set_status(304, "Not Modified");
1639 cgi_reply();
1640 return;
1641 }
1642
1643 /* Use the first element of PATH_INFO as the page name
1644 ** and deliver the appropriate page back to the user.
1645 */
1646 set_base_url(0);
1647 if( zPathInfo==0 || zPathInfo[0]==0
1648
--- src/main.c
+++ src/main.c
@@ -1629,19 +1629,10 @@
1629 ** payload, then pretend that the PATH_INFO is /xfer so that we always
1630 ** invoke the sync page. */
1631 zPathInfo = "/xfer";
1632 }
1633
 
 
 
 
 
 
 
 
 
1634 /* Use the first element of PATH_INFO as the page name
1635 ** and deliver the appropriate page back to the user.
1636 */
1637 set_base_url(0);
1638 if( zPathInfo==0 || zPathInfo[0]==0
1639
+18 -14
--- src/mkindex.c
+++ src/mkindex.c
@@ -80,24 +80,25 @@
8080
8181
/***************************************************************************
8282
** These macros must match similar macros in dispatch.c.
8383
**
8484
** Allowed values for CmdOrPage.eCmdFlags. */
85
-#define CMDFLAG_1ST_TIER 0x0001 /* Most important commands */
86
-#define CMDFLAG_2ND_TIER 0x0002 /* Obscure and seldom used commands */
87
-#define CMDFLAG_TEST 0x0004 /* Commands for testing only */
88
-#define CMDFLAG_WEBPAGE 0x0008 /* Web pages */
89
-#define CMDFLAG_COMMAND 0x0010 /* A command */
90
-#define CMDFLAG_SETTING 0x0020 /* A setting */
91
-#define CMDFLAG_VERSIONABLE 0x0040 /* A versionable setting */
92
-#define CMDFLAG_BLOCKTEXT 0x0080 /* Multi-line text setting */
93
-#define CMDFLAG_BOOLEAN 0x0100 /* A boolean setting */
94
-#define CMDFLAG_CONST 0x0000 /* ETAG_CONST */
95
-#define CMDFLAG_CONFIG 0x1000 /* ETAG_CONFIG */
96
-#define CMDFLAG_DATA 0x2000 /* ETAG_DATA */
97
-#define CMDFLAG_DYNAMIC 0x8000 /* ETAG_DYNAMIC - on by default */
98
-#define CMDFLAG_ETAG 0xf000 /* Mask of all ETAG entries */
85
+#define CMDFLAG_1ST_TIER 0x00001 /* Most important commands */
86
+#define CMDFLAG_2ND_TIER 0x00002 /* Obscure and seldom used commands */
87
+#define CMDFLAG_TEST 0x00004 /* Commands for testing only */
88
+#define CMDFLAG_WEBPAGE 0x00008 /* Web pages */
89
+#define CMDFLAG_COMMAND 0x00010 /* A command */
90
+#define CMDFLAG_SETTING 0x00020 /* A setting */
91
+#define CMDFLAG_VERSIONABLE 0x00040 /* A versionable setting */
92
+#define CMDFLAG_BLOCKTEXT 0x00080 /* Multi-line text setting */
93
+#define CMDFLAG_BOOLEAN 0x00100 /* A boolean setting */
94
+#define CMDFLAG_CONST 0x00000 /* ETAG_CONST */
95
+#define CMDFLAG_CONFIG 0x01000 /* ETAG_CONFIG */
96
+#define CMDFLAG_DATA 0x02000 /* ETAG_DATA */
97
+#define CMDFLAG_COOKIE 0x04000 /* ETAG_COOKIE */
98
+#define CMDFLAG_DYNAMIC 0x10000 /* ETAG_DYNAMIC - on by default */
99
+#define CMDFLAG_ETAG 0x1f000 /* Mask of all ETAG entries */
99100
#define CMDFLAG_TO_ETAG(X) ((X)>>12)
100101
/**************************************************************************/
101102
102103
/*
103104
** Each entry looks like this:
@@ -251,10 +252,13 @@
251252
aEntry[nUsed].eType &= ~CMDFLAG_ETAG;
252253
aEntry[nUsed].eType |= CMDFLAG_CONFIG;
253254
}else if( j==4 && strncmp(&zLine[i], "data", j)==0 ){
254255
aEntry[nUsed].eType &= ~CMDFLAG_ETAG;
255256
aEntry[nUsed].eType |= CMDFLAG_DATA;
257
+ }else if( j==4 && strncmp(&zLine[i], "cookie", j)==0 ){
258
+ aEntry[nUsed].eType &= ~CMDFLAG_ETAG;
259
+ aEntry[nUsed].eType |= CMDFLAG_COOKIE;
256260
}else if( j==7 && strncmp(&zLine[i], "boolean", j)==0 ){
257261
aEntry[nUsed].eType &= ~(CMDFLAG_BLOCKTEXT);
258262
aEntry[nUsed].iWidth = 0;
259263
aEntry[nUsed].eType |= CMDFLAG_BOOLEAN;
260264
}else if( j==10 && strncmp(&zLine[i], "block-text", j)==0 ){
261265
--- src/mkindex.c
+++ src/mkindex.c
@@ -80,24 +80,25 @@
80
81 /***************************************************************************
82 ** These macros must match similar macros in dispatch.c.
83 **
84 ** Allowed values for CmdOrPage.eCmdFlags. */
85 #define CMDFLAG_1ST_TIER 0x0001 /* Most important commands */
86 #define CMDFLAG_2ND_TIER 0x0002 /* Obscure and seldom used commands */
87 #define CMDFLAG_TEST 0x0004 /* Commands for testing only */
88 #define CMDFLAG_WEBPAGE 0x0008 /* Web pages */
89 #define CMDFLAG_COMMAND 0x0010 /* A command */
90 #define CMDFLAG_SETTING 0x0020 /* A setting */
91 #define CMDFLAG_VERSIONABLE 0x0040 /* A versionable setting */
92 #define CMDFLAG_BLOCKTEXT 0x0080 /* Multi-line text setting */
93 #define CMDFLAG_BOOLEAN 0x0100 /* A boolean setting */
94 #define CMDFLAG_CONST 0x0000 /* ETAG_CONST */
95 #define CMDFLAG_CONFIG 0x1000 /* ETAG_CONFIG */
96 #define CMDFLAG_DATA 0x2000 /* ETAG_DATA */
97 #define CMDFLAG_DYNAMIC 0x8000 /* ETAG_DYNAMIC - on by default */
98 #define CMDFLAG_ETAG 0xf000 /* Mask of all ETAG entries */
 
99 #define CMDFLAG_TO_ETAG(X) ((X)>>12)
100 /**************************************************************************/
101
102 /*
103 ** Each entry looks like this:
@@ -251,10 +252,13 @@
251 aEntry[nUsed].eType &= ~CMDFLAG_ETAG;
252 aEntry[nUsed].eType |= CMDFLAG_CONFIG;
253 }else if( j==4 && strncmp(&zLine[i], "data", j)==0 ){
254 aEntry[nUsed].eType &= ~CMDFLAG_ETAG;
255 aEntry[nUsed].eType |= CMDFLAG_DATA;
 
 
 
256 }else if( j==7 && strncmp(&zLine[i], "boolean", j)==0 ){
257 aEntry[nUsed].eType &= ~(CMDFLAG_BLOCKTEXT);
258 aEntry[nUsed].iWidth = 0;
259 aEntry[nUsed].eType |= CMDFLAG_BOOLEAN;
260 }else if( j==10 && strncmp(&zLine[i], "block-text", j)==0 ){
261
--- src/mkindex.c
+++ src/mkindex.c
@@ -80,24 +80,25 @@
80
81 /***************************************************************************
82 ** These macros must match similar macros in dispatch.c.
83 **
84 ** Allowed values for CmdOrPage.eCmdFlags. */
85 #define CMDFLAG_1ST_TIER 0x00001 /* Most important commands */
86 #define CMDFLAG_2ND_TIER 0x00002 /* Obscure and seldom used commands */
87 #define CMDFLAG_TEST 0x00004 /* Commands for testing only */
88 #define CMDFLAG_WEBPAGE 0x00008 /* Web pages */
89 #define CMDFLAG_COMMAND 0x00010 /* A command */
90 #define CMDFLAG_SETTING 0x00020 /* A setting */
91 #define CMDFLAG_VERSIONABLE 0x00040 /* A versionable setting */
92 #define CMDFLAG_BLOCKTEXT 0x00080 /* Multi-line text setting */
93 #define CMDFLAG_BOOLEAN 0x00100 /* A boolean setting */
94 #define CMDFLAG_CONST 0x00000 /* ETAG_CONST */
95 #define CMDFLAG_CONFIG 0x01000 /* ETAG_CONFIG */
96 #define CMDFLAG_DATA 0x02000 /* ETAG_DATA */
97 #define CMDFLAG_COOKIE 0x04000 /* ETAG_COOKIE */
98 #define CMDFLAG_DYNAMIC 0x10000 /* ETAG_DYNAMIC - on by default */
99 #define CMDFLAG_ETAG 0x1f000 /* Mask of all ETAG entries */
100 #define CMDFLAG_TO_ETAG(X) ((X)>>12)
101 /**************************************************************************/
102
103 /*
104 ** Each entry looks like this:
@@ -251,10 +252,13 @@
252 aEntry[nUsed].eType &= ~CMDFLAG_ETAG;
253 aEntry[nUsed].eType |= CMDFLAG_CONFIG;
254 }else if( j==4 && strncmp(&zLine[i], "data", j)==0 ){
255 aEntry[nUsed].eType &= ~CMDFLAG_ETAG;
256 aEntry[nUsed].eType |= CMDFLAG_DATA;
257 }else if( j==4 && strncmp(&zLine[i], "cookie", j)==0 ){
258 aEntry[nUsed].eType &= ~CMDFLAG_ETAG;
259 aEntry[nUsed].eType |= CMDFLAG_COOKIE;
260 }else if( j==7 && strncmp(&zLine[i], "boolean", j)==0 ){
261 aEntry[nUsed].eType &= ~(CMDFLAG_BLOCKTEXT);
262 aEntry[nUsed].iWidth = 0;
263 aEntry[nUsed].eType |= CMDFLAG_BOOLEAN;
264 }else if( j==10 && strncmp(&zLine[i], "block-text", j)==0 ){
265
--- src/unversioned.c
+++ src/unversioned.c
@@ -153,11 +153,15 @@
153153
** 2: zName exists and is the same as zHash but has a older mtime
154154
** 3: zName exists and is identical to mtime/zHash in all respects.
155155
** 4: zName exists and is the same as zHash but has a newer mtime.
156156
** 5: zName exists and should override the mtime/zHash remote.
157157
*/
158
-int unversioned_status(const char *zName, sqlite3_int64 mtime, const char *zHash){
158
+int unversioned_status(
159
+ const char *zName,
160
+ sqlite3_int64 mtime,
161
+ const char *zHash
162
+){
159163
int iStatus = 0;
160164
Stmt q;
161165
db_prepare(&q, "SELECT mtime, hash FROM unversioned WHERE name=%Q", zName);
162166
if( db_step(&q)==SQLITE_ROW ){
163167
const char *zLocalHash = db_column_text(&q, 1);
164168
--- src/unversioned.c
+++ src/unversioned.c
@@ -153,11 +153,15 @@
153 ** 2: zName exists and is the same as zHash but has a older mtime
154 ** 3: zName exists and is identical to mtime/zHash in all respects.
155 ** 4: zName exists and is the same as zHash but has a newer mtime.
156 ** 5: zName exists and should override the mtime/zHash remote.
157 */
158 int unversioned_status(const char *zName, sqlite3_int64 mtime, const char *zHash){
 
 
 
 
159 int iStatus = 0;
160 Stmt q;
161 db_prepare(&q, "SELECT mtime, hash FROM unversioned WHERE name=%Q", zName);
162 if( db_step(&q)==SQLITE_ROW ){
163 const char *zLocalHash = db_column_text(&q, 1);
164
--- src/unversioned.c
+++ src/unversioned.c
@@ -153,11 +153,15 @@
153 ** 2: zName exists and is the same as zHash but has a older mtime
154 ** 3: zName exists and is identical to mtime/zHash in all respects.
155 ** 4: zName exists and is the same as zHash but has a newer mtime.
156 ** 5: zName exists and should override the mtime/zHash remote.
157 */
158 int unversioned_status(
159 const char *zName,
160 sqlite3_int64 mtime,
161 const char *zHash
162 ){
163 int iStatus = 0;
164 Stmt q;
165 db_prepare(&q, "SELECT mtime, hash FROM unversioned WHERE name=%Q", zName);
166 if( db_step(&q)==SQLITE_ROW ){
167 const char *zLocalHash = db_column_text(&q, 1);
168

Keyboard Shortcuts

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