Actually used the SEND_RESPONSE phase

This commit is contained in:
Nate Choe
2022-01-30 17:57:20 -06:00
parent f3694d3b43
commit 1888bb9518
6 changed files with 51 additions and 28 deletions

View File

@@ -198,7 +198,20 @@ static int processChar(Connection *conn, char c, Sitefile *site) {
} }
if (conn->progress == RECEIVE_BODY && if (conn->progress == RECEIVE_BODY &&
conn->receivedBody >= conn->bodylen) conn->receivedBody >= conn->bodylen)
sendResponse(conn, site); getResponse(conn, site);
if (conn->progress == SEND_RESPONSE) {
for (;;) {
char buffer[1024];
size_t readLen = read(conn->fd, buffer, sizeof(buffer));
if (readLen == 0)
break;
size_t writeLen = sendStream(conn->stream,
buffer, readLen);
if (writeLen < readLen)
return 1;
}
resetConnection(conn);
}
return 0; return 0;
} }

View File

@@ -54,6 +54,9 @@ typedef struct Connection {
size_t bodylen; size_t bodylen;
size_t receivedBody; size_t receivedBody;
int fd;
//the fd of the response
char *currLine; char *currLine;
//persistent //persistent
size_t currLineAlloc; size_t currLineAlloc;

View File

@@ -20,5 +20,6 @@
#include <sitefile.h> #include <sitefile.h>
#include <connections.h> #include <connections.h>
int sendResponse(Connection *conn, Sitefile *site); int getResponse(Connection *conn, Sitefile *site);
//returns 1 on error, sets conn->progress to SEND_RESPONSE and sets conn->fd
#endif #endif

View File

@@ -19,6 +19,7 @@
#define _HAVE_RESPONSE_UTIL #define _HAVE_RESPONSE_UTIL
#include <connections.h> #include <connections.h>
#define CODE_200 "200 OK"
#define ERROR_400 "400 Bad Request" #define ERROR_400 "400 Bad Request"
#define ERROR_403 "403 Forbidden" #define ERROR_403 "403 Forbidden"
#define ERROR_404 "404 Not Found" #define ERROR_404 "404 Not Found"
@@ -27,5 +28,6 @@
int sendStringResponse(Connection *conn, char *status, char *str); int sendStringResponse(Connection *conn, char *status, char *str);
int sendBinaryResponse(Connection *conn, char *status, void *data, size_t len); int sendBinaryResponse(Connection *conn, char *status, void *data, size_t len);
int sendErrorResponse(Connection *conn, char *error); int sendErrorResponse(Connection *conn, char *error);
//sendErrorResponse(conn, "404 Not found"); //sendErrorResponse(conn, ERROR_404);
int sendHeader(Connection *conn, char *status, size_t len);
#endif #endif

View File

@@ -28,12 +28,12 @@
#include <responses.h> #include <responses.h>
#include <responseutil.h> #include <responseutil.h>
static void readResponse(Connection *conn, char *path) { static int readResponse(Connection *conn, char *path) {
FILE *file; FILE *file;
struct stat statbuf; struct stat statbuf;
if (stat(path, &statbuf)) { if (stat(path, &statbuf)) {
sendErrorResponse(conn, ERROR_404); sendErrorResponse(conn, ERROR_404);
return; return -1;
} }
if (S_ISDIR(statbuf.st_mode)) { if (S_ISDIR(statbuf.st_mode)) {
long reqPathLen = strlen(conn->path); long reqPathLen = strlen(conn->path);
@@ -49,7 +49,7 @@ static void readResponse(Connection *conn, char *path) {
if (errno == ENOENT) { if (errno == ENOENT) {
free(assembledPath); free(assembledPath);
sendErrorResponse(conn, ERROR_404); sendErrorResponse(conn, ERROR_404);
return; return -1;
} }
free(assembledPath); free(assembledPath);
goto error; goto error;
@@ -74,12 +74,12 @@ static void readResponse(Connection *conn, char *path) {
if (stat(requestPath, &requestbuf)) { if (stat(requestPath, &requestbuf)) {
free(assembledPath); free(assembledPath);
sendErrorResponse(conn, ERROR_404); sendErrorResponse(conn, ERROR_404);
return; return -1;
} }
if (S_ISDIR(requestbuf.st_mode)) { if (S_ISDIR(requestbuf.st_mode)) {
free(assembledPath); free(assembledPath);
sendErrorResponse(conn, ERROR_400); sendErrorResponse(conn, ERROR_400);
return; return -1;
} }
file = fopen(requestPath, "r"); file = fopen(requestPath, "r");
@@ -91,25 +91,15 @@ static void readResponse(Connection *conn, char *path) {
goto forbidden; goto forbidden;
fseek(file, 0, SEEK_END); fseek(file, 0, SEEK_END);
long len = ftell(file); long len = ftell(file);
char *data = malloc(len);
if (data == NULL)
return;
fseek(file, 0, SEEK_SET); fseek(file, 0, SEEK_SET);
if (fread(data, 1, len, file) < len) { sendHeader(conn, CODE_200, len);
fclose(file); return fileno(file);
goto error;
}
fclose(file);
if (sendBinaryResponse(conn, "200 OK", data, len) < len)
goto error;
free(data);
return;
error: error:
sendErrorResponse(conn, ERROR_500); sendErrorResponse(conn, ERROR_500);
return; return -1;
forbidden: forbidden:
sendErrorResponse(conn, ERROR_403); sendErrorResponse(conn, ERROR_403);
return; return -1;
} }
static int fullmatch(regex_t *regex, char *str) { static int fullmatch(regex_t *regex, char *str) {
@@ -119,7 +109,7 @@ static int fullmatch(regex_t *regex, char *str) {
return match.rm_so != 0 || match.rm_eo != strlen(str); return match.rm_so != 0 || match.rm_eo != strlen(str);
} }
int sendResponse(Connection *conn, Sitefile *site) { int getResponse(Connection *conn, Sitefile *site) {
char *host = NULL; char *host = NULL;
for (int i = 0; i < conn->fieldCount; i++) { for (int i = 0; i < conn->fieldCount; i++) {
if (strcmp(conn->fields[i].field, "Host") == 0) { if (strcmp(conn->fields[i].field, "Host") == 0) {
@@ -137,18 +127,23 @@ int sendResponse(Connection *conn, Sitefile *site) {
if (fullmatch(&site->content[i].host, host)) if (fullmatch(&site->content[i].host, host))
continue; continue;
if (fullmatch(&site->content[i].path, conn->path) == 0) { if (fullmatch(&site->content[i].path, conn->path) == 0) {
int fd = -1;
switch (site->content[i].command) { switch (site->content[i].command) {
case READ: case READ:
readResponse(conn, site->content[i].arg); return
goto end; fd = readResponse(conn,
site->content[i].arg);
default: default:
sendErrorResponse(conn, ERROR_500); sendErrorResponse(conn, ERROR_500);
return 1; return 1;
} }
if (fd == -1)
return 1;
conn->fd = fd;
conn->progress = SEND_RESPONSE;
return 0;
} }
} }
sendErrorResponse(conn, ERROR_404); sendErrorResponse(conn, ERROR_404);
end: return -1;
resetConnection(conn);
return 0;
} }

View File

@@ -85,3 +85,12 @@ int sendBinaryResponse(Connection *conn, char *status,
return 1; return 1;
return sendStream(conn->stream, data, len) < len; return sendStream(conn->stream, data, len) < len;
} }
int sendHeader(Connection *conn, char *status, size_t len) {
return (sendConnection(conn,
"HTTP/1.1 %s\r\n"
CONST_FIELDS
"Content-Length: %lu\r\n"
"\r\n"
, status, len));
}