Skip to content

Commit

Permalink
POST requests without a target return path.
Browse files Browse the repository at this point in the history
If a POST request comes in the server doesn't actually care to do
anything with it. So it just drops the information. Previously it
would just break the connection, but now it sends back the path
it received in the request.
  • Loading branch information
jmvsenterprise committed Jan 20, 2024
1 parent beb979e commit 4057f6a
Show file tree
Hide file tree
Showing 5 changed files with 92 additions and 37 deletions.
3 changes: 3 additions & 0 deletions README.txt
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ FUTURE ENHANCEMENTS
Save card data when a quiz is completed. For each card, save the users's score
for the front and back of the card and when it should next be reviewed.

Write automated tests so I don't have to do all this manual testing. Its
painful.

Split out the ASL specific stuff into its own project the server loads via .so.
The idea here is to have the .so be an "application" that the server can be
told to load with an attached URI. If that URI is specified in a request, the
Expand Down
6 changes: 3 additions & 3 deletions asl.c
Original file line number Diff line number Diff line change
Expand Up @@ -147,11 +147,11 @@ int asl_post(struct request *r, int client)
static const struct str good_btn = STR("good");
static const struct str great_btn = STR("great");

for (long i = 0; i < r->param_count; ++i) {
for (long i = 0; i < r->header_count; ++i) {
printf("param %li=", i);
str_print(stdout, &r->params[i].key);
str_print(stdout, &r->headers[i].key);
puts("=");
str_print(stdout, &r->params[i].value);
str_print(stdout, &r->headers[i].value);
puts("\n");
}

Expand Down
18 changes: 11 additions & 7 deletions crvr.c
Original file line number Diff line number Diff line change
Expand Up @@ -79,13 +79,13 @@ static int parse_into_param(struct str *line, struct http_param *param)
static int add_param_to_request(struct request *r, struct http_param *param)
{
if (!r || !param) return EINVAL;
assert(LEN(r->params) <= LONG_MAX);
if (r->param_count >= (long)LEN(r->params)) {
assert(LEN(r->headers) <= LONG_MAX);
if (r->header_count >= (long)LEN(r->headers)) {
DEBUG("invalid param count");
return ENOBUFS;
}
r->params[r->param_count] = *param;
r->param_count++;
r->headers[r->header_count] = *param;
r->header_count++;
return 0;
}

Expand All @@ -111,8 +111,8 @@ static int parse_header_options(struct str rest_of_header, struct request *r)
return EINVAL;
}

while ((rest_of_header.len > 0) && (r->param_count <
(long)LEN(r->params)))
while ((rest_of_header.len > 0) && (r->header_count <
(long)LEN(r->headers)))
{
long eol = str_find_substr(&rest_of_header, &newline);
struct str line;
Expand All @@ -137,7 +137,7 @@ static int parse_header_options(struct str rest_of_header, struct request *r)
error = add_param_to_request(r, &param);
}

printf("Found %lu headers.\n", r->param_count);
printf("Found %lu headers.\n", r->header_count);
return 0;
}

Expand Down Expand Up @@ -394,6 +394,10 @@ int handle_post_request(int client, struct request *r, struct pool *p,

if (str_cmp_cstr(&r->path, "asl.html") == 0) return asl_post(r, client);

printf("No post response\n");

send_path(&r->path, client, p);

printf("Don't know what to do with post to \"");
str_print(stdout, &r->path);
printf("\"\n");
Expand Down
85 changes: 60 additions & 25 deletions http.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

#include <assert.h>
#include <errno.h>
#include <linux/limits.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
Expand All @@ -21,10 +22,10 @@ int find_param(const struct request *r, const char *param_name,
if (!out || !r || !param_name) return EINVAL;

static_assert(SIZE_MAX > LONG_MAX);
assert((size_t)r->param_count < LEN(r->params));
for (long i = 0; i < r->param_count; ++i) {
if (str_cmp_cstr(&r->params[i].key, param_name) == 0) {
*out = r->params[i];
assert((size_t)r->header_count < LEN(r->headers));
for (long i = 0; i < r->header_count; ++i) {
if (str_cmp_cstr(&r->headers[i].key, param_name) == 0) {
*out = r->headers[i];
return 0;
}
}
Expand All @@ -35,9 +36,9 @@ int header_find_value(struct request *r, const char *key, struct str *value)
{
if (!r || !key || !value) return EINVAL;

for (long i = 0; i < r->param_count; ++i) {
if (str_cmp_cstr(&r->params[i].key, key) == 0) {
*value = r->params[i].value;
for (long i = 0; i < r->header_count; ++i) {
if (str_cmp_cstr(&r->headers[i].key, key) == 0) {
*value = r->headers[i].value;
return 0;
}
}
Expand All @@ -62,14 +63,14 @@ void print_request(struct request *r)
puts("\nFormat: ");
str_print(stdout, &r->format);
puts("\n");
if (r->param_count > 0) {
if (r->header_count > 0) {
printf("Parameters:\n"
"-----------\n");
for (long i = 0; i < r->param_count; ++i) {
for (long i = 0; i < r->header_count; ++i) {
printf("%li: ", i);
str_print(stdout, &r->params[i].key);
str_print(stdout, &r->headers[i].key);
puts(":");
str_print(stdout, &r->params[i].value);
str_print(stdout, &r->headers[i].value);
puts("\n");
}
printf("-----------\n");
Expand Down Expand Up @@ -120,6 +121,27 @@ int send_data(int client, const char *header, const char *contents,
return 0;
}

int send_path(struct str *file_path, int client, struct pool *p)
{
char path[PATH_MAX + 1] = {0};
int err = str_copy_to_cstr(file_path, path, PATH_MAX);
if (err) {
fprintf(stderr, "Failed to copy path to c-string: %i\n", err);
return err;
}
FILE *f = fopen(path, "r");
if (!f) {
fprintf(stderr, "Failed to open file \"%s\": %i\n", path,
errno);
return errno;
}
err = send_file(f, client, p);
fclose(f);
if (err)
fprintf(stderr, "send_file failed for \"%s\": %i\n", path, err);
return err;
}

int send_file(FILE *f, int client, struct pool *p)
{
char *contents;
Expand All @@ -143,28 +165,41 @@ int send_file(FILE *f, int client, struct pool *p)
return -1;
}
printf("File is %lu bytes.\n", file_size);
contents = calloc((size_t)file_size, sizeof(*contents));

long pool_cap = pool_get_remaining_capacity(p);
if (pool_cap < file_size) {
fprintf(stderr, "%s> No pool space. Needed %li have %li\n",
__func__, file_size, pool_cap);
return ENOBUFS;
}
long pool_pos = pool_get_position(p);
assert(pool_pos != -1);
contents = pool_alloc(p, file_size);
if (!contents) {
fprintf(stderr, "Failed to allocate buffer for file: %d.\n",
errno);
return errno;
} else {
chars_read = fread((void*)contents, sizeof(*contents),
(size_t)file_size, f);
if (chars_read != (size_t)file_size) {
printf("Failed to read in file: %lu of %ld\n",
chars_read, file_size);
result = errno;
}
}

// Note: don't return without resetting the pool now

chars_read = fread((void*)contents, sizeof(*contents),
(size_t)file_size, f);
if (chars_read == (size_t)file_size) {
result = send_data(client, ok_header, contents,
(size_t)file_size);
if (result < 0) {
fprintf(stderr, "Failed to send message.\n");
result = errno;
}
free(contents);
} else {
printf("Failed to read in file: %lu of %ld\n", chars_read,
file_size);
result = errno;
}

if (result != 0) {
fprintf(stderr, "Failed to send message.\n");
result = errno;
}
pool_reset(p, pool_pos);

return result;
}

Expand Down
17 changes: 15 additions & 2 deletions http.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,8 @@ struct request {
enum request_type type;
struct str path;
struct str format;
long param_count;
struct http_param params[MAX_HEADER_LINES];
long header_count;
struct http_param headers[MAX_HEADER_LINES];
struct str buffer;
struct str post_params_buffer;
};
Expand Down Expand Up @@ -103,6 +103,19 @@ void print_request(struct request *r);
int send_data(int client, const char *header, const char *contents,
size_t content_len);

/**
* @file Sends the file with the specified path to a client.
*
* @param[in] file_path - The path to the file to send.
* @param[in] client - The client to send the file to.
* @param[in] p - The pool to use to allocate space to send the file to the
* client.
*
* @return Returns 0 if the file is sent successfully. Otherwise returns an
* error code.
*/
int send_path(struct str *file_path, int client, struct pool *p);

/*
* DEPRECATED Sends a file to the client with the HTTP 200 OK header.
*
Expand Down

0 comments on commit 4057f6a

Please sign in to comment.