www cleanups.

Use ptr_vectors in the WWW code to parse mime types,
headers in POST requests, etc.

Signed-off-by: Dan Cross <patchdev@fat-dragon.org>
This commit is contained in:
Dan Cross 2018-10-14 13:10:52 +00:00 committed by Andrew Pamment
parent e32addbe59
commit 40570f0fd0

170
src/www.c
View File

@ -34,8 +34,8 @@ struct connection_info_s {
int connection_type;
struct user_record *user;
char *url;
char **keys;
char **values;
struct ptr_vector keys;
struct ptr_vector values;
int count;
struct MHD_PostProcessor *pp;
};
@ -66,12 +66,10 @@ void www_request_completed(void *cls, struct MHD_Connection *connection, void **
if (con_info->connection_type == POST) {
if (con_info->count > 0) {
for (i = 0; i < con_info->count; i++) {
free(con_info->values[i]);
free(con_info->keys[i]);
}
free(con_info->values);
free(con_info->keys);
ptr_vector_apply(&con_info->values, free);
ptr_vector_apply(&con_info->keys, free);
destroy_ptr_vector(&con_info->values);
destroy_ptr_vector(&con_info->keys);
}
if (con_info->pp != NULL) {
@ -94,99 +92,75 @@ void www_request_completed(void *cls, struct MHD_Connection *connection, void **
free(con_info);
}
static int iterate_post(void *coninfo_cls, enum MHD_ValueKind kind, const char *key, const char *filename, const char *content_type, const char *transfer_encoding, const char *data, uint64_t off, size_t size) {
static int iterate_post(void *coninfo_cls, enum MHD_ValueKind kind,
const char *key, const char *filename,
const char *content_type, const char *transfer_encoding,
const char *data, uint64_t off, size_t size) {
struct connection_info_s *con_info = coninfo_cls;
int i;
if (size == 0) {
if (size == 0)
return MHD_NO;
}
if (con_info != NULL) {
if (con_info->connection_type == POST) {
for (i = 0; i < con_info->count; i++) {
if (strcmp(con_info->keys[i], key) == 0) {
con_info->values[i] = (char *)realloc(con_info->values[i], strlen(con_info->values[i]) + size + 1);
strcat(con_info->values[i], data);
return MHD_YES;
}
}
if (con_info->count == 0) {
con_info->keys = (char **)malloz(sizeof(char *));
con_info->values = (char **)malloz(sizeof(char *));
} else {
con_info->keys = (char **)realloc(con_info->keys, sizeof(char *) * (con_info->count + 1));
con_info->values = (char **)realloc(con_info->values, sizeof(char *) * (con_info->count + 1));
}
con_info->keys[con_info->count] = strdup(key);
con_info->values[con_info->count] = strdup(data);
con_info->count++;
if (con_info != NULL)
return MHD_NO;
if (con_info->connection_type != POST)
return MHD_NO;
for (int i = 0; i < con_info->count; i++) {
if (strcmp(ptr_vector_get(&con_info->keys, i), key) == 0) {
char *value = ptr_vector_get(&con_info->values, i);
size_t newsize = strlen(value) + size + 1;
char *newvalue = realloc(value, newsize);
strlcat(newvalue, data, newsize);
ptr_vector_put(&con_info->values, newvalue, i);
return MHD_YES;
} else {
return MHD_NO;
}
}
return MHD_NO;
ptr_vector_append(&con_info->keys, strdup(key));
ptr_vector_append(&con_info->values, strdup(data));
con_info->count++;
return MHD_YES;
}
void www_init() {
FILE *fptr;
char buffer[PATH_MAX];
int i;
mime_types_count = 0;
snprintf(buffer, PATH_MAX, "%s/mime.types", conf.www_path);
struct ptr_vector vec = EMPTY_PTR_VECTOR;
snprintf(buffer, sizeof buffer, "%s/mime.types", conf.www_path);
fptr = fopen(buffer, "r");
if (!fptr) {
return;
}
fgets(buffer, 256, fptr);
fgets(buffer, sizeof buffer, fptr);
while (!feof(fptr)) {
chomp(buffer);
for (i = 0; i < strlen(buffer); i++) {
if (buffer[i] == ' ') {
buffer[i] = '\0';
if (mime_types_count == 0) {
mime_types = (struct mime_type **)malloz(sizeof(struct mime_type *));
} else {
mime_types = (struct mime_type **)realloc(mime_types, sizeof(struct mime_type *) * (mime_types_count + 1));
}
mime_types[mime_types_count] = (struct mime_type *)malloz(sizeof(struct mime_type));
mime_types[mime_types_count]->mime = strdup(buffer);
mime_types[mime_types_count]->ext = strdup(&buffer[i + 1]);
mime_types_count++;
for (char *p = buffer; *p != '\0'; ++p) {
if (*p == ' ') {
*p = '\0';
struct mime_type *atype = (struct mime_type *)malloz(sizeof(struct mime_type));
atype->mime = strdup(buffer);
atype->ext = strdup(p + 1);
ptr_vector_append(&vec, atype);
break;
}
}
fgets(buffer, 256, fptr);
fgets(buffer, sizeof buffer, fptr);
}
fclose(fptr);
mime_types_count = ptr_vector_len(&vec);
mime_types = (struct mime_type **)consume_ptr_vector(&vec);
}
char *www_get_mime_type(const char *extension) {
int i;
static char default_mime_type[] = "application/octet-stream";
if (extension == NULL) {
return default_mime_type;
}
for (i = 0; i < mime_types_count; i++) {
if (strcasecmp(extension, mime_types[i]->ext) == 0) {
return mime_types[i]->mime;
}
}
if (extension != NULL)
for (int i = 0; i < mime_types_count; i++)
if (strcasecmp(extension, mime_types[i]->ext) == 0)
return mime_types[i]->mime;
return default_mime_type;
}
@ -295,7 +269,7 @@ int www_403(char *header, char *footer, struct MHD_Connection *connection) {
}
struct user_record *www_auth_ok(struct MHD_Connection *connection, const char *url) {
char *ptr = MHD_lookup_connection_value(connection, MHD_HEADER_KIND, "Authorization");
const char *ptr = MHD_lookup_connection_value(connection, MHD_HEADER_KIND, "Authorization");
char *user_password;
base64_decodestate state;
char decoded_pass[34];
@ -379,6 +353,8 @@ int www_handler(void *cls, struct MHD_Connection *connection, const char *url, c
con_inf->count = 0;
con_inf->url = strdup(url);
con_inf->pp = NULL;
init_ptr_vector(&con_inf->values);
init_ptr_vector(&con_inf->keys);
*ptr = con_inf;
return MHD_YES;
}
@ -393,6 +369,8 @@ int www_handler(void *cls, struct MHD_Connection *connection, const char *url, c
con_inf->count = 0;
con_inf->url = strdup(url);
con_inf->pp = NULL;
init_ptr_vector(&con_inf->values);
init_ptr_vector(&con_inf->keys);
*ptr = con_inf;
return MHD_YES;
}
@ -747,7 +725,7 @@ int www_handler(void *cls, struct MHD_Connection *connection, const char *url, c
// load file
sprintf(buffer, "%s%s", conf.www_path, url);
snprintf(buffer, sizeof buffer, "%s%s", conf.www_path, url);
if (stat(buffer, &s) == 0 && S_ISREG(s.st_mode)) {
fno = open(buffer, O_RDONLY);
if (fno != -1) {
@ -845,7 +823,7 @@ int www_handler(void *cls, struct MHD_Connection *connection, const char *url, c
response = MHD_create_response_from_fd(s.st_size, fno);
MHD_add_response_header(response, MHD_HTTP_HEADER_CONTENT_TYPE, mime);
sprintf(buffer, "%ld", s.st_size);
snprintf(buffer, sizeof buffer, "%ld", s.st_size);
MHD_add_response_header(response, MHD_HTTP_HEADER_CONTENT_LENGTH, buffer);
snprintf(buffer, PATH_MAX, "attachment; filename=\"%s\"", basename(filename));
@ -912,7 +890,7 @@ int www_handler(void *cls, struct MHD_Connection *connection, const char *url, c
response = MHD_create_response_from_fd(s.st_size, fno);
MHD_add_response_header(response, MHD_HTTP_HEADER_CONTENT_TYPE, mime);
sprintf(buffer, "%ld", s.st_size);
snprintf(buffer, sizeof buffer, "%ld", s.st_size);
MHD_add_response_header(response, MHD_HTTP_HEADER_CONTENT_LENGTH, buffer);
snprintf(buffer, PATH_MAX, "attachment; filename=\"%s\"", basename(filename));
@ -969,12 +947,14 @@ int www_handler(void *cls, struct MHD_Connection *connection, const char *url, c
to = NULL;
body = NULL;
for (i = 0; i < con_inf->count; i++) {
if (strcmp(con_inf->keys[i], "recipient") == 0) {
to = con_inf->values[i];
} else if (strcmp(con_inf->keys[i], "subject") == 0) {
subj = con_inf->values[i];
} else if (strcmp(con_inf->keys[i], "body") == 0) {
body = con_inf->values[i];
const char *key = ptr_vector_get(&con_inf->keys, i);
char *value = ptr_vector_get(&con_inf->values, i);
if (strcmp(key, "recipient") == 0) {
to = value;
} else if (strcmp(key, "subject") == 0) {
subj = value;
} else if (strcmp(key, "body") == 0) {
body = value;
}
}
if (!www_send_email(con_inf->user, to, subj, body)) {
@ -1020,24 +1000,26 @@ int www_handler(void *cls, struct MHD_Connection *connection, const char *url, c
area = -1;
for (i = 0; i < con_inf->count; i++) {
if (strcmp(con_inf->keys[i], "recipient") == 0) {
to = con_inf->values[i];
} else if (strcmp(con_inf->keys[i], "subject") == 0) {
subj = con_inf->values[i];
} else if (strcmp(con_inf->keys[i], "body") == 0) {
body = con_inf->values[i];
} else if (strcmp(con_inf->keys[i], "conference") == 0) {
conference = strtol(con_inf->values[i], &endptr, 10);
if (endptr == con_inf->values[i]) {
const char *key = ptr_vector_get(&con_inf->keys, i);
char *value = ptr_vector_get(&con_inf->values, i);
if (strcmp(key, "recipient") == 0) {
to = value;
} else if (strcmp(key, "subject") == 0) {
subj = value;
} else if (strcmp(key, "body") == 0) {
body = value;
} else if (strcmp(key, "conference") == 0) {
conference = strtol(value, &endptr, 10);
if (endptr == value) {
conference = -1;
}
} else if (strcmp(con_inf->keys[i], "area") == 0) {
area = strtol(con_inf->values[i], &endptr, 10);
if (endptr == con_inf->values[i]) {
} else if (strcmp(key, "area") == 0) {
area = strtol(value, &endptr, 10);
if (endptr == value) {
area = -1;
}
} else if (strcmp(con_inf->keys[i], "replyid") == 0) {
replyid = con_inf->values[i];
} else if (strcmp(key, "replyid") == 0) {
replyid = value;
}
}