Implement read_line

This commit is contained in:
Nick Krichevsky 2018-09-01 16:22:08 -04:00
parent 20d04d8bd7
commit 9d5bc143a2
2 changed files with 74 additions and 18 deletions

View file

@ -1,3 +1,4 @@
#include "http_types.h"
#include "socket_helper.h"
#include <stdlib.h>
#include <string.h>
@ -27,25 +28,72 @@ static const char *get_line_terminator(const char *buffer, int buffer_size) {
return NULL;
}
char *get_all_remote_parts(int socket_fd) {
int current_size = BUFFER_SIZE;
char *result = NULL;
char *buffer = malloc(BUFFER_SIZE * sizeof(char));
while (read(socket_fd, buffer, BUFFER_SIZE) > 0) {
//Allocate a new result buffer if we need to, otherwise grow the existing one.
if (result == NULL) {
result = malloc(BUFFER_SIZE);
} else {
int old_size = current_size;
current_size += BUFFER_SIZE;
char *new_result = malloc(current_size * sizeof(char));
strncpy(new_result, result, old_size);
free(result);
result = new_result;
}
memcpy(result, buffer, BUFFER_SIZE);
static struct line_read_result read_line(const char *buffer, int buffer_size, struct http_message *message) {
const char *line_terminator = get_line_terminator(buffer, buffer_size);
if (line_terminator == NULL) {
struct line_read_result result = {RESULT_NO_LINE, NULL, 0};
return result;
}
free(buffer);
int line_length = 0;
const char *header_delim = NULL;
const char *prev_cursor = NULL;
for (const char *cursor = buffer; cursor != line_terminator; (cursor++, line_length++)) {
if (*cursor == ':') {
header_delim = cursor;
}
prev_cursor = cursor;
}
struct line_read_result result;
// If the last character was a \r, we must have a CRLF sequence.
if (prev_cursor != NULL && *prev_cursor == '\r') {
result.line_type = RESULT_BLANK_LINE;
} else if (header_delim != NULL) {
result.line_type = RESULT_HEADER_LINE;
int name_size = header_delim - buffer;
char *header_name = malloc((name_size + 1) * sizeof(char));
// Start of the buffer + the number of bytes read - 1 for the \r
int value_size = (line_terminator - buffer) + line_length - 1;
char *header_value = malloc((value_size + 1) * sizeof(char));
memcpy(header_name, buffer, name_size);
header_name[name_size] = '\0';
// Must start copying after the :
memcpy(header_value, (buffer + name_size + 1), value_size);
header_value[value_size] = '\0';
message->headers = insert_header(header_name, header_value, message->headers);
free(header_value);
free(header_name);
} else {
result.line_type = RESULT_START_LINE;
}
// Add the space for the \n
int line_size = line_length + 1;
result.line = malloc((line_size + 1) * sizeof(char));
memcpy(result.line, buffer, line_size);
result.line[line_size] = '\0';
return result;
}
int get_all_remote_parts(int socket_fd, struct http_message *message) {
ssize_t current_result_size = 0;
char *result = NULL;
char *buffer = malloc(BUFFER_SIZE * sizeof(char));
ssize_t bytes_read;
while ((bytes_read = read(socket_fd, buffer, BUFFER_SIZE)) > 0) {
int write_offset = 0;
//Allocate a new result buffer if we need to, otherwise grow the existing one.
if (result == NULL) {
result = malloc(bytes_read);
} else {
write_offset = current_result_size;
current_result_size += bytes_read;
result = realloc(result, current_result_size);
}
memcpy(result + write_offset, buffer, BUFFER_SIZE);
}
free(buffer);
message->contents = result;
return result;
}

View file

@ -2,6 +2,14 @@
#define SOCKET_HELPER_H
#define BUFFER_SIZE 1024
enum line_type {RESULT_START_LINE, RESULT_HEADER, RESULT_BLANK_LINE, RESULT_NO_LINE};
struct line_read_result {
enum line_type line_type;
char *line;
int bytes_read;
};
char *get_all_remote_parts(int socket_fd);
#endif