Impl. handling HTTP/1.1 requests
TODO: Handle errors other than 404 Not Found.
This commit is contained in:
parent
3f70c52551
commit
9be6ac32bf
6 changed files with 91 additions and 7 deletions
6
example_config/example.config
Normal file
6
example_config/example.config
Normal file
|
@ -0,0 +1,6 @@
|
|||
PATH=/
|
||||
HTML='''Test HTML
|
||||
{{{Var}}}
|
||||
'''
|
||||
|
||||
Var='''Test var value'''
|
|
@ -24,6 +24,7 @@
|
|||
void print_usage(void) {
|
||||
puts("Usage:");
|
||||
puts(" -p <port> | --port <port>");
|
||||
puts(" --config=<config_file>");
|
||||
}
|
||||
|
||||
Args parse_args(int argc, char **argv) {
|
||||
|
@ -42,6 +43,8 @@ Args parse_args(int argc, char **argv) {
|
|||
}
|
||||
--argc;
|
||||
++argv;
|
||||
} else if (strncmp(argv[0], "--config=", 9) == 0 && strlen(argv[0]) > 9) {
|
||||
args.config_file = argv[0] + 9;
|
||||
} else {
|
||||
puts("ERROR: Invalid args!\n");
|
||||
print_usage();
|
||||
|
|
|
@ -20,6 +20,8 @@
|
|||
typedef struct Args {
|
||||
unsigned short flags;
|
||||
unsigned short port;
|
||||
// Does not need to be free'd, this should point to a string in argv.
|
||||
const char *config_file;
|
||||
} Args;
|
||||
|
||||
void print_usage(void);
|
||||
|
|
32
src/http.c
32
src/http.c
|
@ -21,8 +21,12 @@
|
|||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
// Third party includes.
|
||||
#include <SimpleArchiver/src/helpers.h>
|
||||
|
||||
// Local includes
|
||||
#include "constants.h"
|
||||
#include "http_template.h"
|
||||
|
||||
#define REQUEST_TYPE_BUFFER_SIZE 16
|
||||
#define REQUEST_PATH_BUFFER_SIZE 256
|
||||
|
@ -31,7 +35,11 @@
|
|||
char *c_simple_http_request_response(
|
||||
const char *request,
|
||||
unsigned int size,
|
||||
const C_SIMPLE_HTTP_HTTPTemplates *templates) {
|
||||
const C_SIMPLE_HTTP_HTTPTemplates *templates,
|
||||
size_t *out_size) {
|
||||
if (out_size) {
|
||||
*out_size = 0;
|
||||
}
|
||||
// parse first line.
|
||||
unsigned int idx = 0;
|
||||
char request_type[REQUEST_TYPE_BUFFER_SIZE] = {0};
|
||||
|
@ -102,8 +110,26 @@ char *c_simple_http_request_response(
|
|||
fprintf(stderr, "Parsing request: got http protocol \"%s\"\n", request_proto);
|
||||
#endif
|
||||
|
||||
// TODO
|
||||
return NULL;
|
||||
if (strcmp(request_type, "GET") != 0) {
|
||||
fprintf(stderr, "ERROR Only GET requests are allowed!\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
size_t generated_size = 0;
|
||||
char *generated_buf = c_simple_http_path_to_generated(
|
||||
request_path,
|
||||
templates,
|
||||
&generated_size);
|
||||
if (!generated_buf || generated_size == 0) {
|
||||
fprintf(stderr, "ERROR Unable to generate response html for path \"%s\"!\n",
|
||||
request_path);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (out_size) {
|
||||
*out_size = generated_size;
|
||||
}
|
||||
return generated_buf;
|
||||
}
|
||||
|
||||
// vim: ts=2 sts=2 sw=2
|
||||
|
|
|
@ -17,6 +17,9 @@
|
|||
#ifndef SEODISPARATE_COM_C_SIMPLE_HTTP_HTTP_H_
|
||||
#define SEODISPARATE_COM_C_SIMPLE_HTTP_HTTP_H_
|
||||
|
||||
// Standard library includes.
|
||||
#include <stddef.h>
|
||||
|
||||
// Third party includes.
|
||||
#include <SimpleArchiver/src/data_structures/hash_map.h>
|
||||
|
||||
|
@ -30,7 +33,8 @@ typedef C_SIMPLE_HTTP_ParsedConfig C_SIMPLE_HTTP_HTTPTemplates;
|
|||
char *c_simple_http_request_response(
|
||||
const char *request,
|
||||
unsigned int size,
|
||||
const C_SIMPLE_HTTP_HTTPTemplates *templates
|
||||
const C_SIMPLE_HTTP_HTTPTemplates *templates,
|
||||
size_t *out_size
|
||||
);
|
||||
|
||||
#endif
|
||||
|
|
49
src/main.c
49
src/main.c
|
@ -27,6 +27,9 @@
|
|||
#include <time.h>
|
||||
#include <errno.h>
|
||||
|
||||
// Third party includes.
|
||||
#include <SimpleArchiver/src/helpers.h>
|
||||
|
||||
// Local includes.
|
||||
#include "arg_parse.h"
|
||||
#include "big_endian.h"
|
||||
|
@ -39,7 +42,21 @@
|
|||
int main(int argc, char **argv) {
|
||||
Args args = parse_args(argc, argv);
|
||||
|
||||
if (!args.config_file) {
|
||||
fprintf(stderr, "ERROR Config file not specified!\n");
|
||||
print_usage();
|
||||
return 2;
|
||||
}
|
||||
|
||||
printf("%u\n", args.port);
|
||||
printf("config file is: %s\n", args.config_file);
|
||||
|
||||
__attribute__((cleanup(c_simple_http_clean_up_parsed_config)))
|
||||
C_SIMPLE_HTTP_ParsedConfig parsed_config = c_simple_http_parse_config(
|
||||
args.config_file,
|
||||
"PATH",
|
||||
NULL
|
||||
);
|
||||
|
||||
__attribute__((cleanup(cleanup_tcp_socket))) int tcp_socket =
|
||||
create_tcp_socket(args.port);
|
||||
|
@ -95,12 +112,38 @@ int main(int argc, char **argv) {
|
|||
}
|
||||
}
|
||||
puts("");
|
||||
// TODO Validate request and send response.
|
||||
// TODO WIP
|
||||
|
||||
size_t response_size = 0;
|
||||
const char *response = c_simple_http_request_response(
|
||||
(const char*)recv_buf, read_ret, NULL);
|
||||
(const char*)recv_buf, read_ret, &parsed_config, &response_size);
|
||||
if (response) {
|
||||
write(connection_fd, "HTTP/1.1 200 OK\n", 16);
|
||||
write(connection_fd, "Allow: GET\n", 11);
|
||||
write(connection_fd, "Content-Type: text/html\n", 24);
|
||||
char content_length_buf[128];
|
||||
size_t content_length_buf_size = 0;
|
||||
memcpy(content_length_buf, "Content-Length: ", 16);
|
||||
content_length_buf_size = 16;
|
||||
int written = 0;
|
||||
snprintf(
|
||||
content_length_buf + content_length_buf_size,
|
||||
127 - content_length_buf_size,
|
||||
"%lu\n%n",
|
||||
response_size,
|
||||
&written);
|
||||
content_length_buf_size += written;
|
||||
write(connection_fd, content_length_buf, content_length_buf_size);
|
||||
write(connection_fd, "\n", 1);
|
||||
write(connection_fd, response, response_size);
|
||||
|
||||
free((void*)response);
|
||||
} else {
|
||||
// TODO handle internal errors also.
|
||||
write(connection_fd, "HTTP/1.1 404 Not Found\n", 23);
|
||||
write(connection_fd, "Allow: GET\n", 11);
|
||||
write(connection_fd, "Content-Type: text/html\n", 24);
|
||||
write(connection_fd, "Content-Length: 14\n", 19);
|
||||
write(connection_fd, "\n404 Not Found\n", 15);
|
||||
}
|
||||
close(connection_fd);
|
||||
} else {
|
||||
|
|
Loading…
Reference in a new issue