Implement read_line
This commit is contained in:
parent
20d04d8bd7
commit
9d5bc143a2
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue