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; int connection_type;
struct user_record *user; struct user_record *user;
char *url; char *url;
char **keys; struct ptr_vector keys;
char **values; struct ptr_vector values;
int count; int count;
struct MHD_PostProcessor *pp; 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->connection_type == POST) {
if (con_info->count > 0) { if (con_info->count > 0) {
for (i = 0; i < con_info->count; i++) { ptr_vector_apply(&con_info->values, free);
free(con_info->values[i]); ptr_vector_apply(&con_info->keys, free);
free(con_info->keys[i]); destroy_ptr_vector(&con_info->values);
} destroy_ptr_vector(&con_info->keys);
free(con_info->values);
free(con_info->keys);
} }
if (con_info->pp != NULL) { if (con_info->pp != NULL) {
@ -94,99 +92,75 @@ void www_request_completed(void *cls, struct MHD_Connection *connection, void **
free(con_info); 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; struct connection_info_s *con_info = coninfo_cls;
int i; if (size == 0)
if (size == 0) {
return MHD_NO; return MHD_NO;
} if (con_info != NULL)
return MHD_NO;
if (con_info != NULL) { if (con_info->connection_type != POST)
if (con_info->connection_type == POST) { return MHD_NO;
for (i = 0; i < con_info->count; i++) { for (int i = 0; i < con_info->count; i++) {
if (strcmp(con_info->keys[i], key) == 0) { if (strcmp(ptr_vector_get(&con_info->keys, i), key) == 0) {
con_info->values[i] = (char *)realloc(con_info->values[i], strlen(con_info->values[i]) + size + 1); char *value = ptr_vector_get(&con_info->values, i);
strcat(con_info->values[i], data); size_t newsize = strlen(value) + size + 1;
return MHD_YES; char *newvalue = realloc(value, newsize);
} strlcat(newvalue, data, newsize);
} ptr_vector_put(&con_info->values, newvalue, i);
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++;
return MHD_YES; 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() { void www_init() {
FILE *fptr; FILE *fptr;
char buffer[PATH_MAX]; char buffer[PATH_MAX];
int i; struct ptr_vector vec = EMPTY_PTR_VECTOR;
mime_types_count = 0;
snprintf(buffer, PATH_MAX, "%s/mime.types", conf.www_path);
snprintf(buffer, sizeof buffer, "%s/mime.types", conf.www_path);
fptr = fopen(buffer, "r"); fptr = fopen(buffer, "r");
if (!fptr) { if (!fptr) {
return; return;
} }
fgets(buffer, 256, fptr); fgets(buffer, sizeof buffer, fptr);
while (!feof(fptr)) { while (!feof(fptr)) {
chomp(buffer); chomp(buffer);
for (i = 0; i < strlen(buffer); i++) { for (char *p = buffer; *p != '\0'; ++p) {
if (buffer[i] == ' ') { if (*p == ' ') {
buffer[i] = '\0'; *p = '\0';
if (mime_types_count == 0) { struct mime_type *atype = (struct mime_type *)malloz(sizeof(struct mime_type));
mime_types = (struct mime_type **)malloz(sizeof(struct mime_type *)); atype->mime = strdup(buffer);
} else { atype->ext = strdup(p + 1);
mime_types = (struct mime_type **)realloc(mime_types, sizeof(struct mime_type *) * (mime_types_count + 1)); ptr_vector_append(&vec, atype);
}
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++;
break; break;
} }
} }
fgets(buffer, 256, fptr); fgets(buffer, sizeof buffer, fptr);
} }
fclose(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) { char *www_get_mime_type(const char *extension) {
int i;
static char default_mime_type[] = "application/octet-stream"; static char default_mime_type[] = "application/octet-stream";
if (extension == NULL) { if (extension != NULL)
return default_mime_type; for (int i = 0; i < mime_types_count; i++)
} if (strcasecmp(extension, mime_types[i]->ext) == 0)
return mime_types[i]->mime;
for (i = 0; i < mime_types_count; i++) {
if (strcasecmp(extension, mime_types[i]->ext) == 0) {
return mime_types[i]->mime;
}
}
return default_mime_type; 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) { 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; char *user_password;
base64_decodestate state; base64_decodestate state;
char decoded_pass[34]; 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->count = 0;
con_inf->url = strdup(url); con_inf->url = strdup(url);
con_inf->pp = NULL; con_inf->pp = NULL;
init_ptr_vector(&con_inf->values);
init_ptr_vector(&con_inf->keys);
*ptr = con_inf; *ptr = con_inf;
return MHD_YES; 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->count = 0;
con_inf->url = strdup(url); con_inf->url = strdup(url);
con_inf->pp = NULL; con_inf->pp = NULL;
init_ptr_vector(&con_inf->values);
init_ptr_vector(&con_inf->keys);
*ptr = con_inf; *ptr = con_inf;
return MHD_YES; return MHD_YES;
} }
@ -747,7 +725,7 @@ int www_handler(void *cls, struct MHD_Connection *connection, const char *url, c
// load file // 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)) { if (stat(buffer, &s) == 0 && S_ISREG(s.st_mode)) {
fno = open(buffer, O_RDONLY); fno = open(buffer, O_RDONLY);
if (fno != -1) { 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); response = MHD_create_response_from_fd(s.st_size, fno);
MHD_add_response_header(response, MHD_HTTP_HEADER_CONTENT_TYPE, mime); 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); MHD_add_response_header(response, MHD_HTTP_HEADER_CONTENT_LENGTH, buffer);
snprintf(buffer, PATH_MAX, "attachment; filename=\"%s\"", basename(filename)); 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); response = MHD_create_response_from_fd(s.st_size, fno);
MHD_add_response_header(response, MHD_HTTP_HEADER_CONTENT_TYPE, mime); 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); MHD_add_response_header(response, MHD_HTTP_HEADER_CONTENT_LENGTH, buffer);
snprintf(buffer, PATH_MAX, "attachment; filename=\"%s\"", basename(filename)); 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; to = NULL;
body = NULL; body = NULL;
for (i = 0; i < con_inf->count; i++) { for (i = 0; i < con_inf->count; i++) {
if (strcmp(con_inf->keys[i], "recipient") == 0) { const char *key = ptr_vector_get(&con_inf->keys, i);
to = con_inf->values[i]; char *value = ptr_vector_get(&con_inf->values, i);
} else if (strcmp(con_inf->keys[i], "subject") == 0) { if (strcmp(key, "recipient") == 0) {
subj = con_inf->values[i]; to = value;
} else if (strcmp(con_inf->keys[i], "body") == 0) { } else if (strcmp(key, "subject") == 0) {
body = con_inf->values[i]; subj = value;
} else if (strcmp(key, "body") == 0) {
body = value;
} }
} }
if (!www_send_email(con_inf->user, to, subj, body)) { 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; area = -1;
for (i = 0; i < con_inf->count; i++) { for (i = 0; i < con_inf->count; i++) {
if (strcmp(con_inf->keys[i], "recipient") == 0) { const char *key = ptr_vector_get(&con_inf->keys, i);
to = con_inf->values[i]; char *value = ptr_vector_get(&con_inf->values, i);
} else if (strcmp(con_inf->keys[i], "subject") == 0) { if (strcmp(key, "recipient") == 0) {
subj = con_inf->values[i]; to = value;
} else if (strcmp(con_inf->keys[i], "body") == 0) { } else if (strcmp(key, "subject") == 0) {
body = con_inf->values[i]; subj = value;
} else if (strcmp(con_inf->keys[i], "conference") == 0) { } else if (strcmp(key, "body") == 0) {
conference = strtol(con_inf->values[i], &endptr, 10); body = value;
if (endptr == con_inf->values[i]) { } else if (strcmp(key, "conference") == 0) {
conference = strtol(value, &endptr, 10);
if (endptr == value) {
conference = -1; conference = -1;
} }
} else if (strcmp(con_inf->keys[i], "area") == 0) { } else if (strcmp(key, "area") == 0) {
area = strtol(con_inf->values[i], &endptr, 10); area = strtol(value, &endptr, 10);
if (endptr == con_inf->values[i]) { if (endptr == value) {
area = -1; area = -1;
} }
} else if (strcmp(con_inf->keys[i], "replyid") == 0) { } else if (strcmp(key, "replyid") == 0) {
replyid = con_inf->values[i]; replyid = value;
} }
} }