6 #if defined HAVE_STDINT_H
8 #elif defined HAVE_INTTYPES_H
14 int etag_is_equal(buffer
*etag
, const char *line
, int weak_ok
) {
25 const char *tok_start
;
26 const char *tok
= NULL
;
29 if ('*' == line
[0] && '\0' == line
[1]) {
33 if (!etag
|| buffer_string_is_empty(etag
)) return 0;
34 tok_start
= etag
->ptr
;
36 if ('W' == tok_start
[0]) {
37 if (!weak_ok
|| '/' != tok_start
[1]) return 0; /* bad etag */
38 tok_start
= tok_start
+ 2;
41 if ('"' != tok_start
[0]) return 0; /* bad etag */
42 /* we start comparing after the first '"' */
45 for (current
= line
; *current
; ++current
) {
48 /* wait for etag to start; ignore whitespace and ',' */
51 /* weak etag always starts with 'W/"' */
52 if ('/' != *++current
) return 0; /* bad etag list */
53 if ('"' != *++current
) return 0; /* bad etag list */
62 /* strong etag starts with '"' */
73 return 0; /* bad etag list */
77 /* compare etags (after the beginning '"')
78 * quoted-pairs must match too (i.e. quoted in both strings):
79 * > (RFC 2616:) both validators MUST be identical in every way
81 matched
= *tok
&& *tok
== *current
;
85 state
= matched
? CHECK_QUOTED
: SKIP_QUOTED
;
89 /* bad etag - string should end after '"' */
93 /* matching etag: strings were equal */
101 /* strings not matching, skip remainder of etag */
108 if (!*tok
|| *tok
!= *current
) {
109 /* strings not matching, skip remainder of etag */
117 /* wait for final (not quoted) '"' */
131 /* search for ',', ignore white space */
142 return 0; /* bad etag list */
147 /* no matching etag found */
151 int etag_create(buffer
*etag
, struct stat
*st
,etag_flags_t flags
) {
152 if (0 == flags
) return 0;
156 if (flags
& ETAG_USE_INODE
) {
157 buffer_append_int(etag
, st
->st_ino
);
158 buffer_append_string_len(etag
, CONST_STR_LEN("-"));
161 if (flags
& ETAG_USE_SIZE
) {
162 buffer_append_int(etag
, st
->st_size
);
163 buffer_append_string_len(etag
, CONST_STR_LEN("-"));
166 if (flags
& ETAG_USE_MTIME
) {
167 buffer_append_int(etag
, st
->st_mtime
);
173 int etag_mutate(buffer
*mut
, buffer
*etag
) {
177 len
= buffer_string_length(etag
);
178 for (h
=0, i
=0; i
< len
; ++i
) h
= (h
<<5)^(h
>>27)^(etag
->ptr
[i
]);
181 buffer_copy_string_len(mut
, CONST_STR_LEN("\""));
182 buffer_append_int(mut
, h
);
183 buffer_append_string_len(mut
, CONST_STR_LEN("\""));