Move status code arrays into c files
parent
85254e21cb
commit
f780b69793
|
@ -8,6 +8,7 @@
|
||||||
#define BUFFER_SIZE 1024
|
#define BUFFER_SIZE 1024
|
||||||
#define HEADER_CONTENT_LENGTH "Content-Length"
|
#define HEADER_CONTENT_LENGTH "Content-Length"
|
||||||
#define HEADER_TRANSFER_ENCODING "Transfer-Encoding"
|
#define HEADER_TRANSFER_ENCODING "Transfer-Encoding"
|
||||||
|
#define HEADER_CONNECTION "Connection"
|
||||||
|
|
||||||
enum line_type {RESULT_START_LINE, RESULT_HEADER, RESULT_BLANK_LINE, RESULT_NO_LINE};
|
enum line_type {RESULT_START_LINE, RESULT_HEADER, RESULT_BLANK_LINE, RESULT_NO_LINE};
|
||||||
enum socket_result {RESULT_OK, RESULT_MALFORMED, RESULT_READ_ERROR, RESULT_PROCESSING_ERROR, RESULT_WRITE_ERROR};
|
enum socket_result {RESULT_OK, RESULT_MALFORMED, RESULT_READ_ERROR, RESULT_PROCESSING_ERROR, RESULT_WRITE_ERROR};
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
#include "socket_server.h"
|
#include "socket_server.h"
|
||||||
#include "../common/http_types.h"
|
#include "../common/http_types.h"
|
||||||
#include "../common/socket_helper.h"
|
#include "../common/socket_helper.h"
|
||||||
|
#include "../common/buffer_helper.h"
|
||||||
|
#include "status_codes.h"
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <netdb.h>
|
#include <netdb.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
@ -71,6 +73,71 @@ struct server_info setup(int port) {
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends the headers and status line of the response
|
||||||
|
*
|
||||||
|
* @param status_code The status code to send
|
||||||
|
* @param client_socket The socket to send the message on
|
||||||
|
* @param content_length The content length of the file-to-send
|
||||||
|
*
|
||||||
|
* @return -1 on error, 0 otherwise.
|
||||||
|
*/
|
||||||
|
static int send_headers(int status_code, int client_socket, int content_length) {
|
||||||
|
const char *status_code_message = get_message_from_status_code(status_code);
|
||||||
|
if (status_code_message == NULL) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
// All status codes are three digits, plus the space for the null term.
|
||||||
|
char *status_code_string = malloc(4 * sizeof(char));
|
||||||
|
snprintf(status_code_string, 4, "%d", status_code);
|
||||||
|
const char *status_line_components[] = {HTTP_VERSION, " ", status_code_string, " ", status_code_message, "\r\n"};
|
||||||
|
int status_line_buffer_size = get_buffer_size(status_line_components, 6) + 1;
|
||||||
|
char *status_line_buffer = malloc(status_line_buffer_size * sizeof(char));
|
||||||
|
sprintf(status_line_buffer, "%s %s %s\r\n", HTTP_VERSION, status_code_string, status_code_message);
|
||||||
|
free(status_code_string);
|
||||||
|
|
||||||
|
// RFC2616 states that if we don't intend to persist the connection, we must send "Connection: close"
|
||||||
|
const char *connection_header_components[] = {HEADER_CONNECTION, ": close\r\n"};
|
||||||
|
char *content_length_header_buffer = "";
|
||||||
|
int header_buffer_size = get_buffer_size(connection_header_components, 2);
|
||||||
|
if (content_length > 0) {
|
||||||
|
// Get the number of chars in the port
|
||||||
|
int content_length_length = floor(log10(content_length)) + 1;
|
||||||
|
char *content_length_string = malloc((content_length_length + 1) * sizeof(char));
|
||||||
|
sprintf(content_length_string, "%d", content_length);
|
||||||
|
const char *content_length_header_components[] = {HEADER_CONTENT_LENGTH, ": ", content_length_string, "\r\n"};
|
||||||
|
int content_length_header_length = get_buffer_size(content_length_header_components, 4);
|
||||||
|
header_buffer_size += content_length_header_length;
|
||||||
|
content_length_header_buffer = malloc(content_length_header_length * sizeof(char));
|
||||||
|
sprintf(content_length_header_buffer, "%s: %s\r\n", HEADER_CONTENT_LENGTH, content_length_string);
|
||||||
|
free(content_length_string);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Include space for the null term and the CRLF
|
||||||
|
char *header_buffer = malloc((header_buffer_size + 3) * sizeof(char));
|
||||||
|
sprintf(header_buffer, "%s: close\r\n%s\r\n", HEADER_CONNECTION, content_length_header_buffer);
|
||||||
|
if (content_length > 0) {
|
||||||
|
free(content_length_header_buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
int send_result = send(client_socket, status_line_buffer, status_line_buffer_size - 1, 0);
|
||||||
|
if (send_result == -1) {
|
||||||
|
free(status_line_buffer);
|
||||||
|
free(header_buffer);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
send_result = send(client_socket, header_buffer, header_buffer_size - 1, 0);
|
||||||
|
if (send_result == -1) {
|
||||||
|
free(status_line_buffer);
|
||||||
|
free(header_buffer);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
free(status_line_buffer);
|
||||||
|
free(header_buffer);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
enum socket_result serve_one_request(int sock_fd) {
|
enum socket_result serve_one_request(int sock_fd) {
|
||||||
int client_fd = accept(sock_fd, NULL, NULL);
|
int client_fd = accept(sock_fd, NULL, NULL);
|
||||||
if (client_fd == -1) {
|
if (client_fd == -1) {
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#include "../common/socket_helper.h"
|
#include "../common/socket_helper.h"
|
||||||
|
|
||||||
#define BACKLOG_SIZE 8;
|
#define BACKLOG_SIZE 8;
|
||||||
|
#define HTTP_VERSION "HTTP/1.1"
|
||||||
|
|
||||||
enum server_status {STATUS_LISTENING, STATUS_CLOSED, STATUS_ERROR};
|
enum server_status {STATUS_LISTENING, STATUS_CLOSED, STATUS_ERROR};
|
||||||
struct server_info {
|
struct server_info {
|
||||||
|
|
|
@ -1,6 +1,58 @@
|
||||||
#include "status_codes.h"
|
#include "status_codes.h"
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
const char *STATUS_CODES_100[] = {
|
||||||
|
"Continue",
|
||||||
|
"Switching Protocols"
|
||||||
|
};
|
||||||
|
|
||||||
|
const char *STATUS_CODES_200[] = {
|
||||||
|
"OK",
|
||||||
|
"Created",
|
||||||
|
"Accepted",
|
||||||
|
"Non-Authoritative Information",
|
||||||
|
"No Content",
|
||||||
|
"Reset Content",
|
||||||
|
"Partial Content",
|
||||||
|
};
|
||||||
|
|
||||||
|
const char *STATUS_CODES_300[] = {
|
||||||
|
"Multiple Choices",
|
||||||
|
"Moved Permanently",
|
||||||
|
"Found",
|
||||||
|
"See Other",
|
||||||
|
"Not Modified",
|
||||||
|
"Use Proxy",
|
||||||
|
NULL, // There is no status code 306
|
||||||
|
"Temporary Redirect",
|
||||||
|
};
|
||||||
|
|
||||||
|
const char *STATUS_CODES_400[] = {
|
||||||
|
"Bad Request",
|
||||||
|
"Unauthorized",
|
||||||
|
"Payment Required",
|
||||||
|
"Forbidden",
|
||||||
|
"Not Found",
|
||||||
|
"Method Not Allowed",
|
||||||
|
"Not Acceptable",
|
||||||
|
"Proxy Authentication Required",
|
||||||
|
"Request Time-out",
|
||||||
|
"Conflict",
|
||||||
|
"Gone",
|
||||||
|
"Length Required",
|
||||||
|
"Precondition Failed",
|
||||||
|
"Request Entity Too Large",
|
||||||
|
"Request-URI Too Large",
|
||||||
|
"Unsupported Media Type",
|
||||||
|
"Requested range not satisfiable",
|
||||||
|
"Expectation Failed",
|
||||||
|
};
|
||||||
|
|
||||||
|
const char *STATUS_CODES_500[] = {
|
||||||
|
"Internal Server Error",
|
||||||
|
"Not Implemented",
|
||||||
|
};
|
||||||
|
|
||||||
const char *get_message_from_status_code(int status_code) {
|
const char *get_message_from_status_code(int status_code) {
|
||||||
if (status_code > 100 && status_code < 100 + NUM_100_STATUS_CODES) {
|
if (status_code > 100 && status_code < 100 + NUM_100_STATUS_CODES) {
|
||||||
return STATUS_CODES_100[status_code - 100];
|
return STATUS_CODES_100[status_code - 100];
|
||||||
|
|
|
@ -9,61 +9,11 @@
|
||||||
#define NUM_400_STATUS_CODES 18
|
#define NUM_400_STATUS_CODES 18
|
||||||
#define NUM_500_STATUS_CODES 6
|
#define NUM_500_STATUS_CODES 6
|
||||||
|
|
||||||
const char *STATUS_CODES_100[] = {
|
extern const char *STATUS_CODES_100[];
|
||||||
"Continue",
|
extern const char *STATUS_CODES_200[];
|
||||||
"Switching Protocols"
|
extern const char *STATUS_CODES_300[];
|
||||||
};
|
extern const char *STATUS_CODES_400[];
|
||||||
|
extern const char *STATUS_CODES_500[];
|
||||||
const char *STATUS_CODES_200[] = {
|
|
||||||
"OK",
|
|
||||||
"Created",
|
|
||||||
"Accepted",
|
|
||||||
"Non-Authoritative Information",
|
|
||||||
"No Content",
|
|
||||||
"Reset Content",
|
|
||||||
"Partial Content",
|
|
||||||
};
|
|
||||||
|
|
||||||
const char *STATUS_CODES_300[] = {
|
|
||||||
"Multiple Choices",
|
|
||||||
"Moved Permanently",
|
|
||||||
"Found",
|
|
||||||
"See Other",
|
|
||||||
"Not Modified",
|
|
||||||
"Use Proxy",
|
|
||||||
NULL, // There is no status code 306
|
|
||||||
"Temporary Redirect",
|
|
||||||
};
|
|
||||||
|
|
||||||
const char *STATUS_CODES_400[] = {
|
|
||||||
"Bad Request",
|
|
||||||
"Unauthorized",
|
|
||||||
"Payment Required",
|
|
||||||
"Forbidden",
|
|
||||||
"Not Found",
|
|
||||||
"Method Not Allowed",
|
|
||||||
"Not Acceptable",
|
|
||||||
"Proxy Authentication Required",
|
|
||||||
"Request Time-out",
|
|
||||||
"Conflict",
|
|
||||||
"Gone",
|
|
||||||
"Length Required",
|
|
||||||
"Precondition Failed",
|
|
||||||
"Request Entity Too Large",
|
|
||||||
"Request-URI Too Large",
|
|
||||||
"Unsupported Media Type",
|
|
||||||
"Requested range not satisfiable",
|
|
||||||
"Expectation Failed",
|
|
||||||
};
|
|
||||||
|
|
||||||
const char *STATUS_CODES_500[] = {
|
|
||||||
"Internal Server Error",
|
|
||||||
"Not Implemented",
|
|
||||||
"Bad Gateway",
|
|
||||||
"Service Unavailable",
|
|
||||||
"Gateway Time-out",
|
|
||||||
"HTTP Version not supported"
|
|
||||||
};
|
|
||||||
|
|
||||||
const char *get_message_from_status_code(int status_code);
|
const char *get_message_from_status_code(int status_code);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue