-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathquery.c
94 lines (79 loc) · 2.42 KB
/
query.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
#include "util.h"
#include "query.h"
#include "list.h"
QueryEntry *chttp_get_query_entry(Header *header, char *key) {
List *entry = &header->query;
for(ListNode *i = list_begin(entry); i != list_end(entry); i = list_next(i)) {
QueryEntry *current = (QueryEntry*)i;
if(stricmp(key, current->key) == 0) {
return current;
}
}
return NULL;
}
void chttp_add_query(Header *header, char *key, char *format, ...) {
va_list args, argsc;
va_start(args, format);
va_copy(argsc, args);
int len = vsnprintf(NULL, 0, format, args) + 1;
char val[len + 1];
vsnprintf(val, len + 1, format, argsc);
va_end(args);
va_end(argsc);
QueryEntry *find_header = chttp_get_query_entry(header, key);
if(find_header) {
find_header->val = realloc(find_header->val, (strlen(val) + 1) * sizeof(char));
strcpy(find_header->val, val);
} else {
QueryEntry *entry = malloc(sizeof(QueryEntry));
entry->key = malloc((strlen(key) + 1) * sizeof(char));
entry->val = malloc((strlen(val) + 1) * sizeof(char));
strcpy(entry->key, key);
strcpy(entry->val, val);
list_insert(list_end(&header->query), entry);
}
}
char *chttp_build_query(Header *header) {
char *result = malloc(sizeof(char) + 1);
*result = '\0';
List *entry = &header->query;
for(ListNode *i = list_begin(entry); i != list_end(entry); i = list_next(i)) {
QueryEntry *current = (QueryEntry*)i;
char *append = malloc_fmt("%s=%s& ", current->key, current->val);
result = realloc(result, strlen(result) + strlen(append) + 1);
strcat(result, append);
free(append);
}
return result;
}
int chttp_parse_query(Header *header, char* buf) {
char *saveptr;
char *key = strtok_r(buf, "=", &saveptr);
char *val = strtok_r(NULL, "&", &saveptr);
while(key != NULL && val != NULL) {
char key_decoded[strlen(key) + 1];
uri_decode(key, strlen(key), key_decoded);
char val_decoded[strlen(val) + 1];
uri_decode(val, strlen(val), val_decoded);
chttp_add_query(header, key_decoded, "%s", val_decoded);
key = strtok_r(NULL, "=", &saveptr);
val = strtok_r(NULL, "&", &saveptr);
}
return 0;
}
void chttp_free_query_entry(QueryEntry *entry) {
free(entry->key);
free(entry->val);
free(entry);
}
void chttp_clean_query(Header *header) {
List *entry = &header->query;
while(!list_empty(entry)) {
QueryEntry *current = (QueryEntry*)list_remove(list_begin(entry));
chttp_free_query_entry(current);
}
}