3 #include <event2/buffer.h>
9 headers_add_key(struct header_list
*headers
, const char *key
, size_t n
)
13 h
= mem_calloc(1, sizeof(*h
) + n
+ 1);
15 memcpy(h
->key
, key
, n
);
16 TAILQ_INSERT_TAIL(headers
, h
, next
);
20 headers_add_val(struct header_list
*headers
, const char *val
, size_t n
)
23 struct val_line
*line
;
25 h
= TAILQ_LAST(headers
, header_list
);
28 line
= mem_calloc(1, sizeof(*line
) + n
+ 1);
29 memcpy(line
->str
, val
, n
);
31 TAILQ_INSERT_TAIL(&h
->val
, line
, next
);
36 headers_dump(struct header_list
*headers
, struct evbuffer
*buf
)
39 struct val_line
*line
;
41 TAILQ_FOREACH(h
, headers
, next
) {
42 evbuffer_add_printf(buf
, "%s:", h
->key
);
43 TAILQ_FOREACH(line
, &h
->val
, next
)
44 evbuffer_add_printf(buf
, "%s\r\n", line
->str
);
47 evbuffer_add(buf
, "\r\n", 2);
50 /* return: -1 error, 0 need more data, 1 finished. */
52 headers_parse(struct header_list
*headers
, struct evbuffer
*buf
)
56 while ((line
= evbuffer_readln(buf
, NULL
, EVBUFFER_EOL_CRLF
))) {
64 if (*line
!= ' ' && *line
!= '\t') {
65 p
= strchr(line
, ':');
70 headers_add_key(headers
, line
, p
- line
);
74 if (!TAILQ_LAST(headers
, header_list
)) {
79 headers_add_val(headers
, p
, strlen(p
));
86 /* caller must free result; returns NULL if key not found. */
88 headers_find(struct header_list
*headers
, const char *key
)
91 struct val_line
*line
;
95 TAILQ_FOREACH(h
, headers
, next
) {
96 if (evutil_ascii_strcasecmp(h
->key
, key
))
99 /* calculate total size */
100 TAILQ_FOREACH(line
, &h
->val
, next
)
103 /* XXX Some of this space is wasted if we trim any leading WS
105 ret
= mem_calloc(1, len
+ 1);
108 TAILQ_FOREACH(line
, &h
->val
, next
) {
109 len
= strspn(line
->str
, " \t");
110 /* after the first line, translate leading WS to
114 memcpy(p
, line
->str
+ len
, line
->len
- len
);
115 p
+= line
->len
- len
;
125 headers_clear(struct header_list
*headers
)
128 struct val_line
*line
;
130 while ((h
= TAILQ_FIRST(headers
))) {
131 TAILQ_REMOVE(headers
, h
, next
);
132 while ((line
= TAILQ_FIRST(&h
->val
))) {
133 TAILQ_REMOVE(&h
->val
, line
, next
);
142 int main(int argc
, char **argv
)
144 struct evbuffer
*buf
, *buf2
;
145 struct header_list headers
;
148 buf
= evbuffer_new();
149 buf2
= evbuffer_new();
150 TAILQ_INIT(&headers
);
152 while (fgets(line
, sizeof(line
), stdin
)) {
153 evbuffer_add(buf
, line
, strlen(line
));
156 headers_parse(&headers
, buf
);
157 headers_dump(&headers
, buf2
);
160 fwrite(evbuffer_pullup(buf
, evbuffer_get_length(buf
)), evbuffer_get_length(buf
), 1, stdout
);
161 printf("\nbuf2..\n");
162 fwrite(evbuffer_pullup(buf2
, evbuffer_get_length(buf2
)), evbuffer_get_length(buf2
), 1, stdout
);
166 printf("\nfinding stuffs...\n");
167 for (i
= 1; i
< argc
; ++i
) {
168 char *buf
= headers_find(&headers
, argv
[i
]);
169 printf("%s? %s\n", argv
[i
], buf
? buf
: "NOT FOUND");
170 if (buf
) mem_free(buf
);