requests
This commit is contained in:
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
bin
|
||||||
|
obj
|
||||||
166
CWebLibrary.make
Normal file
166
CWebLibrary.make
Normal file
@@ -0,0 +1,166 @@
|
|||||||
|
# GNU Make project makefile autogenerated by Premake
|
||||||
|
|
||||||
|
ifndef config
|
||||||
|
config=debug
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifndef verbose
|
||||||
|
SILENT = @
|
||||||
|
endif
|
||||||
|
|
||||||
|
.PHONY: clean prebuild prelink
|
||||||
|
|
||||||
|
ifeq ($(config),debug)
|
||||||
|
ifeq ($(origin CC), default)
|
||||||
|
CC = clang
|
||||||
|
endif
|
||||||
|
ifeq ($(origin CXX), default)
|
||||||
|
CXX = clang++
|
||||||
|
endif
|
||||||
|
ifeq ($(origin AR), default)
|
||||||
|
AR = ar
|
||||||
|
endif
|
||||||
|
TARGETDIR = bin/Debug
|
||||||
|
TARGET = $(TARGETDIR)/libCWebLibrary.a
|
||||||
|
OBJDIR = obj/Debug/CWebLibrary
|
||||||
|
DEFINES +=
|
||||||
|
INCLUDES +=
|
||||||
|
FORCE_INCLUDE +=
|
||||||
|
ALL_CPPFLAGS += $(CPPFLAGS) -MD -MP $(DEFINES) $(INCLUDES)
|
||||||
|
ALL_CFLAGS += $(CFLAGS) $(ALL_CPPFLAGS)
|
||||||
|
ALL_CXXFLAGS += $(CXXFLAGS) $(ALL_CPPFLAGS)
|
||||||
|
ALL_RESFLAGS += $(RESFLAGS) $(DEFINES) $(INCLUDES)
|
||||||
|
LIBS +=
|
||||||
|
LDDEPS +=
|
||||||
|
ALL_LDFLAGS += $(LDFLAGS)
|
||||||
|
LINKCMD = $(AR) -rcs "$@" $(OBJECTS)
|
||||||
|
define PREBUILDCMDS
|
||||||
|
endef
|
||||||
|
define PRELINKCMDS
|
||||||
|
endef
|
||||||
|
define POSTBUILDCMDS
|
||||||
|
endef
|
||||||
|
all: prebuild prelink $(TARGET)
|
||||||
|
@:
|
||||||
|
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq ($(config),release)
|
||||||
|
ifeq ($(origin CC), default)
|
||||||
|
CC = clang
|
||||||
|
endif
|
||||||
|
ifeq ($(origin CXX), default)
|
||||||
|
CXX = clang++
|
||||||
|
endif
|
||||||
|
ifeq ($(origin AR), default)
|
||||||
|
AR = ar
|
||||||
|
endif
|
||||||
|
TARGETDIR = bin/Release
|
||||||
|
TARGET = $(TARGETDIR)/libCWebLibrary.a
|
||||||
|
OBJDIR = obj/Release/CWebLibrary
|
||||||
|
DEFINES +=
|
||||||
|
INCLUDES +=
|
||||||
|
FORCE_INCLUDE +=
|
||||||
|
ALL_CPPFLAGS += $(CPPFLAGS) -MD -MP $(DEFINES) $(INCLUDES)
|
||||||
|
ALL_CFLAGS += $(CFLAGS) $(ALL_CPPFLAGS)
|
||||||
|
ALL_CXXFLAGS += $(CXXFLAGS) $(ALL_CPPFLAGS)
|
||||||
|
ALL_RESFLAGS += $(RESFLAGS) $(DEFINES) $(INCLUDES)
|
||||||
|
LIBS +=
|
||||||
|
LDDEPS +=
|
||||||
|
ALL_LDFLAGS += $(LDFLAGS)
|
||||||
|
LINKCMD = $(AR) -rcs "$@" $(OBJECTS)
|
||||||
|
define PREBUILDCMDS
|
||||||
|
endef
|
||||||
|
define PRELINKCMDS
|
||||||
|
endef
|
||||||
|
define POSTBUILDCMDS
|
||||||
|
endef
|
||||||
|
all: prebuild prelink $(TARGET)
|
||||||
|
@:
|
||||||
|
|
||||||
|
endif
|
||||||
|
|
||||||
|
OBJECTS := \
|
||||||
|
$(OBJDIR)/http_content_type.o \
|
||||||
|
$(OBJDIR)/http_method.o \
|
||||||
|
$(OBJDIR)/http_request.o \
|
||||||
|
$(OBJDIR)/http_response.o \
|
||||||
|
$(OBJDIR)/http_status.o \
|
||||||
|
|
||||||
|
RESOURCES := \
|
||||||
|
|
||||||
|
CUSTOMFILES := \
|
||||||
|
|
||||||
|
SHELLTYPE := posix
|
||||||
|
ifeq (.exe,$(findstring .exe,$(ComSpec)))
|
||||||
|
SHELLTYPE := msdos
|
||||||
|
endif
|
||||||
|
|
||||||
|
$(TARGET): $(GCH) ${CUSTOMFILES} $(OBJECTS) $(LDDEPS) $(RESOURCES) | $(TARGETDIR)
|
||||||
|
@echo Linking CWebLibrary
|
||||||
|
$(SILENT) $(LINKCMD)
|
||||||
|
$(POSTBUILDCMDS)
|
||||||
|
|
||||||
|
$(CUSTOMFILES): | $(OBJDIR)
|
||||||
|
|
||||||
|
$(TARGETDIR):
|
||||||
|
@echo Creating $(TARGETDIR)
|
||||||
|
ifeq (posix,$(SHELLTYPE))
|
||||||
|
$(SILENT) mkdir -p $(TARGETDIR)
|
||||||
|
else
|
||||||
|
$(SILENT) mkdir $(subst /,\\,$(TARGETDIR))
|
||||||
|
endif
|
||||||
|
|
||||||
|
$(OBJDIR):
|
||||||
|
@echo Creating $(OBJDIR)
|
||||||
|
ifeq (posix,$(SHELLTYPE))
|
||||||
|
$(SILENT) mkdir -p $(OBJDIR)
|
||||||
|
else
|
||||||
|
$(SILENT) mkdir $(subst /,\\,$(OBJDIR))
|
||||||
|
endif
|
||||||
|
|
||||||
|
clean:
|
||||||
|
@echo Cleaning CWebLibrary
|
||||||
|
ifeq (posix,$(SHELLTYPE))
|
||||||
|
$(SILENT) rm -f $(TARGET)
|
||||||
|
$(SILENT) rm -rf $(OBJDIR)
|
||||||
|
else
|
||||||
|
$(SILENT) if exist $(subst /,\\,$(TARGET)) del $(subst /,\\,$(TARGET))
|
||||||
|
$(SILENT) if exist $(subst /,\\,$(OBJDIR)) rmdir /s /q $(subst /,\\,$(OBJDIR))
|
||||||
|
endif
|
||||||
|
|
||||||
|
prebuild:
|
||||||
|
$(PREBUILDCMDS)
|
||||||
|
|
||||||
|
prelink:
|
||||||
|
$(PRELINKCMDS)
|
||||||
|
|
||||||
|
ifneq (,$(PCH))
|
||||||
|
$(OBJECTS): $(GCH) $(PCH) | $(OBJDIR)
|
||||||
|
$(GCH): $(PCH) | $(OBJDIR)
|
||||||
|
@echo $(notdir $<)
|
||||||
|
$(SILENT) $(CC) -x c-header $(ALL_CFLAGS) -o "$@" -MF "$(@:%.gch=%.d)" -c "$<"
|
||||||
|
else
|
||||||
|
$(OBJECTS): | $(OBJDIR)
|
||||||
|
endif
|
||||||
|
|
||||||
|
$(OBJDIR)/http_content_type.o: http/http_content_type.c
|
||||||
|
@echo $(notdir $<)
|
||||||
|
$(SILENT) $(CC) $(ALL_CFLAGS) $(FORCE_INCLUDE) -o "$@" -MF "$(@:%.o=%.d)" -c "$<"
|
||||||
|
$(OBJDIR)/http_method.o: http/http_method.c
|
||||||
|
@echo $(notdir $<)
|
||||||
|
$(SILENT) $(CC) $(ALL_CFLAGS) $(FORCE_INCLUDE) -o "$@" -MF "$(@:%.o=%.d)" -c "$<"
|
||||||
|
$(OBJDIR)/http_request.o: http/http_request.c
|
||||||
|
@echo $(notdir $<)
|
||||||
|
$(SILENT) $(CC) $(ALL_CFLAGS) $(FORCE_INCLUDE) -o "$@" -MF "$(@:%.o=%.d)" -c "$<"
|
||||||
|
$(OBJDIR)/http_response.o: http/http_response.c
|
||||||
|
@echo $(notdir $<)
|
||||||
|
$(SILENT) $(CC) $(ALL_CFLAGS) $(FORCE_INCLUDE) -o "$@" -MF "$(@:%.o=%.d)" -c "$<"
|
||||||
|
$(OBJDIR)/http_status.o: http/http_status.c
|
||||||
|
@echo $(notdir $<)
|
||||||
|
$(SILENT) $(CC) $(ALL_CFLAGS) $(FORCE_INCLUDE) -o "$@" -MF "$(@:%.o=%.d)" -c "$<"
|
||||||
|
|
||||||
|
-include $(OBJECTS:%.o=%.d)
|
||||||
|
ifneq (,$(PCH))
|
||||||
|
-include $(OBJDIR)/$(notdir $(PCH)).d
|
||||||
|
endif
|
||||||
55
Makefile
Normal file
55
Makefile
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
# GNU Make workspace makefile autogenerated by Premake
|
||||||
|
|
||||||
|
ifndef config
|
||||||
|
config=debug
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifndef verbose
|
||||||
|
SILENT = @
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq ($(config),debug)
|
||||||
|
CWebLibrary_config = debug
|
||||||
|
cweb_config = debug
|
||||||
|
endif
|
||||||
|
ifeq ($(config),release)
|
||||||
|
CWebLibrary_config = release
|
||||||
|
cweb_config = release
|
||||||
|
endif
|
||||||
|
|
||||||
|
PROJECTS := CWebLibrary cweb
|
||||||
|
|
||||||
|
.PHONY: all clean help $(PROJECTS)
|
||||||
|
|
||||||
|
all: $(PROJECTS)
|
||||||
|
|
||||||
|
CWebLibrary:
|
||||||
|
ifneq (,$(CWebLibrary_config))
|
||||||
|
@echo "==== Building CWebLibrary ($(CWebLibrary_config)) ===="
|
||||||
|
@${MAKE} --no-print-directory -C . -f CWebLibrary.make config=$(CWebLibrary_config)
|
||||||
|
endif
|
||||||
|
|
||||||
|
cweb: CWebLibrary
|
||||||
|
ifneq (,$(cweb_config))
|
||||||
|
@echo "==== Building cweb ($(cweb_config)) ===="
|
||||||
|
@${MAKE} --no-print-directory -C . -f cweb.make config=$(cweb_config)
|
||||||
|
endif
|
||||||
|
|
||||||
|
clean:
|
||||||
|
@${MAKE} --no-print-directory -C . -f CWebLibrary.make clean
|
||||||
|
@${MAKE} --no-print-directory -C . -f cweb.make clean
|
||||||
|
|
||||||
|
help:
|
||||||
|
@echo "Usage: make [config=name] [target]"
|
||||||
|
@echo ""
|
||||||
|
@echo "CONFIGURATIONS:"
|
||||||
|
@echo " debug"
|
||||||
|
@echo " release"
|
||||||
|
@echo ""
|
||||||
|
@echo "TARGETS:"
|
||||||
|
@echo " all (default)"
|
||||||
|
@echo " clean"
|
||||||
|
@echo " CWebLibrary"
|
||||||
|
@echo " cweb"
|
||||||
|
@echo ""
|
||||||
|
@echo "For more information, see https://github.com/premake/premake-core/wiki"
|
||||||
150
cweb.make
Normal file
150
cweb.make
Normal file
@@ -0,0 +1,150 @@
|
|||||||
|
# GNU Make project makefile autogenerated by Premake
|
||||||
|
|
||||||
|
ifndef config
|
||||||
|
config=debug
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifndef verbose
|
||||||
|
SILENT = @
|
||||||
|
endif
|
||||||
|
|
||||||
|
.PHONY: clean prebuild prelink
|
||||||
|
|
||||||
|
ifeq ($(config),debug)
|
||||||
|
ifeq ($(origin CC), default)
|
||||||
|
CC = clang
|
||||||
|
endif
|
||||||
|
ifeq ($(origin CXX), default)
|
||||||
|
CXX = clang++
|
||||||
|
endif
|
||||||
|
ifeq ($(origin AR), default)
|
||||||
|
AR = ar
|
||||||
|
endif
|
||||||
|
TARGETDIR = bin/Debug
|
||||||
|
TARGET = $(TARGETDIR)/cweb
|
||||||
|
OBJDIR = obj/Debug/cweb
|
||||||
|
DEFINES +=
|
||||||
|
INCLUDES += -Ihttp
|
||||||
|
FORCE_INCLUDE +=
|
||||||
|
ALL_CPPFLAGS += $(CPPFLAGS) -MD -MP $(DEFINES) $(INCLUDES)
|
||||||
|
ALL_CFLAGS += $(CFLAGS) $(ALL_CPPFLAGS) -g
|
||||||
|
ALL_CXXFLAGS += $(CXXFLAGS) $(ALL_CPPFLAGS) -g
|
||||||
|
ALL_RESFLAGS += $(RESFLAGS) $(DEFINES) $(INCLUDES)
|
||||||
|
LIBS += bin/Debug/libCWebLibrary.a
|
||||||
|
LDDEPS += bin/Debug/libCWebLibrary.a
|
||||||
|
ALL_LDFLAGS += $(LDFLAGS)
|
||||||
|
LINKCMD = $(CC) -o "$@" $(OBJECTS) $(RESOURCES) $(ALL_LDFLAGS) $(LIBS)
|
||||||
|
define PREBUILDCMDS
|
||||||
|
endef
|
||||||
|
define PRELINKCMDS
|
||||||
|
endef
|
||||||
|
define POSTBUILDCMDS
|
||||||
|
endef
|
||||||
|
all: prebuild prelink $(TARGET)
|
||||||
|
@:
|
||||||
|
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq ($(config),release)
|
||||||
|
ifeq ($(origin CC), default)
|
||||||
|
CC = clang
|
||||||
|
endif
|
||||||
|
ifeq ($(origin CXX), default)
|
||||||
|
CXX = clang++
|
||||||
|
endif
|
||||||
|
ifeq ($(origin AR), default)
|
||||||
|
AR = ar
|
||||||
|
endif
|
||||||
|
TARGETDIR = bin/Release
|
||||||
|
TARGET = $(TARGETDIR)/cweb
|
||||||
|
OBJDIR = obj/Release/cweb
|
||||||
|
DEFINES +=
|
||||||
|
INCLUDES += -Ihttp
|
||||||
|
FORCE_INCLUDE +=
|
||||||
|
ALL_CPPFLAGS += $(CPPFLAGS) -MD -MP $(DEFINES) $(INCLUDES)
|
||||||
|
ALL_CFLAGS += $(CFLAGS) $(ALL_CPPFLAGS) -O2
|
||||||
|
ALL_CXXFLAGS += $(CXXFLAGS) $(ALL_CPPFLAGS) -O2
|
||||||
|
ALL_RESFLAGS += $(RESFLAGS) $(DEFINES) $(INCLUDES)
|
||||||
|
LIBS += bin/Release/libCWebLibrary.a
|
||||||
|
LDDEPS += bin/Release/libCWebLibrary.a
|
||||||
|
ALL_LDFLAGS += $(LDFLAGS)
|
||||||
|
LINKCMD = $(CC) -o "$@" $(OBJECTS) $(RESOURCES) $(ALL_LDFLAGS) $(LIBS)
|
||||||
|
define PREBUILDCMDS
|
||||||
|
endef
|
||||||
|
define PRELINKCMDS
|
||||||
|
endef
|
||||||
|
define POSTBUILDCMDS
|
||||||
|
endef
|
||||||
|
all: prebuild prelink $(TARGET)
|
||||||
|
@:
|
||||||
|
|
||||||
|
endif
|
||||||
|
|
||||||
|
OBJECTS := \
|
||||||
|
$(OBJDIR)/main.o \
|
||||||
|
|
||||||
|
RESOURCES := \
|
||||||
|
|
||||||
|
CUSTOMFILES := \
|
||||||
|
|
||||||
|
SHELLTYPE := posix
|
||||||
|
ifeq (.exe,$(findstring .exe,$(ComSpec)))
|
||||||
|
SHELLTYPE := msdos
|
||||||
|
endif
|
||||||
|
|
||||||
|
$(TARGET): $(GCH) ${CUSTOMFILES} $(OBJECTS) $(LDDEPS) $(RESOURCES) | $(TARGETDIR)
|
||||||
|
@echo Linking cweb
|
||||||
|
$(SILENT) $(LINKCMD)
|
||||||
|
$(POSTBUILDCMDS)
|
||||||
|
|
||||||
|
$(CUSTOMFILES): | $(OBJDIR)
|
||||||
|
|
||||||
|
$(TARGETDIR):
|
||||||
|
@echo Creating $(TARGETDIR)
|
||||||
|
ifeq (posix,$(SHELLTYPE))
|
||||||
|
$(SILENT) mkdir -p $(TARGETDIR)
|
||||||
|
else
|
||||||
|
$(SILENT) mkdir $(subst /,\\,$(TARGETDIR))
|
||||||
|
endif
|
||||||
|
|
||||||
|
$(OBJDIR):
|
||||||
|
@echo Creating $(OBJDIR)
|
||||||
|
ifeq (posix,$(SHELLTYPE))
|
||||||
|
$(SILENT) mkdir -p $(OBJDIR)
|
||||||
|
else
|
||||||
|
$(SILENT) mkdir $(subst /,\\,$(OBJDIR))
|
||||||
|
endif
|
||||||
|
|
||||||
|
clean:
|
||||||
|
@echo Cleaning cweb
|
||||||
|
ifeq (posix,$(SHELLTYPE))
|
||||||
|
$(SILENT) rm -f $(TARGET)
|
||||||
|
$(SILENT) rm -rf $(OBJDIR)
|
||||||
|
else
|
||||||
|
$(SILENT) if exist $(subst /,\\,$(TARGET)) del $(subst /,\\,$(TARGET))
|
||||||
|
$(SILENT) if exist $(subst /,\\,$(OBJDIR)) rmdir /s /q $(subst /,\\,$(OBJDIR))
|
||||||
|
endif
|
||||||
|
|
||||||
|
prebuild:
|
||||||
|
$(PREBUILDCMDS)
|
||||||
|
|
||||||
|
prelink:
|
||||||
|
$(PRELINKCMDS)
|
||||||
|
|
||||||
|
ifneq (,$(PCH))
|
||||||
|
$(OBJECTS): $(GCH) $(PCH) | $(OBJDIR)
|
||||||
|
$(GCH): $(PCH) | $(OBJDIR)
|
||||||
|
@echo $(notdir $<)
|
||||||
|
$(SILENT) $(CC) -x c-header $(ALL_CFLAGS) -o "$@" -MF "$(@:%.gch=%.d)" -c "$<"
|
||||||
|
else
|
||||||
|
$(OBJECTS): | $(OBJDIR)
|
||||||
|
endif
|
||||||
|
|
||||||
|
$(OBJDIR)/main.o: main.c
|
||||||
|
@echo $(notdir $<)
|
||||||
|
$(SILENT) $(CC) $(ALL_CFLAGS) $(FORCE_INCLUDE) -o "$@" -MF "$(@:%.o=%.d)" -c "$<"
|
||||||
|
|
||||||
|
-include $(OBJECTS:%.o=%.d)
|
||||||
|
ifneq (,$(PCH))
|
||||||
|
-include $(OBJDIR)/$(notdir $(PCH)).d
|
||||||
|
endif
|
||||||
@@ -41,3 +41,23 @@ void http_method(HttpMethod __method, char *__out, size_t __size) {
|
|||||||
} break;
|
} break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
HttpMethod get_http_method(char *__met) {
|
||||||
|
if (strcmp(__met, "GET"))
|
||||||
|
return HTTP_METHOD_GET;
|
||||||
|
if (strcmp(__met, "POST"))
|
||||||
|
return HTTP_METHOD_POST;
|
||||||
|
if (strcmp(__met, "PUT"))
|
||||||
|
return HTTP_METHOD_PUT;
|
||||||
|
if (strcmp(__met, "DELETE"))
|
||||||
|
return HTTP_METHOD_DELETE;
|
||||||
|
if (strcmp(__met, "PATCH"))
|
||||||
|
return HTTP_METHOD_PATCH;
|
||||||
|
if (strcmp(__met, "HEAD"))
|
||||||
|
return HTTP_METHOD_HEAD;
|
||||||
|
if (strcmp(__met, "OPTIONS"))
|
||||||
|
return HTTP_METHOD_OPTIONS;
|
||||||
|
if (strcmp(__met, "CONNECT"))
|
||||||
|
return HTTP_METHOD_CONNECT;
|
||||||
|
return HTTP_METHOD_TRACE;
|
||||||
|
}
|
||||||
|
|||||||
@@ -16,5 +16,6 @@ typedef enum {
|
|||||||
} HttpMethod;
|
} HttpMethod;
|
||||||
|
|
||||||
void http_method(HttpMethod __method, char *__out, size_t __size);
|
void http_method(HttpMethod __method, char *__out, size_t __size);
|
||||||
|
HttpMethod get_http_method(char *__met);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
92
http/http_request.c
Normal file
92
http/http_request.c
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
#include "http_method.h"
|
||||||
|
#include "http_request.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
// GET / HTTP/1.1
|
||||||
|
// Host: localhost:8080
|
||||||
|
// Sec-Fetch-Dest: document
|
||||||
|
// User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)
|
||||||
|
// AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.0 Safari/605.1.15
|
||||||
|
// Upgrade-Insecure-Requests: 1
|
||||||
|
// Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
|
||||||
|
// Sec-Fetch-Site: none
|
||||||
|
// Sec-Fetch-Mode: navigate
|
||||||
|
// Accept-Language: en-GB,en;q=0.9
|
||||||
|
// Priority: u=0, i
|
||||||
|
// Accept-Encoding: gzip, deflate
|
||||||
|
// Connection: keep-alive
|
||||||
|
|
||||||
|
void print_request(const HttpRequest *__req) {
|
||||||
|
char method[10];
|
||||||
|
http_method(__req->method, method, 10);
|
||||||
|
printf("%s %s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n", method,
|
||||||
|
__req->path, __req->host, __req->sec_fetch_dest, __req->user_agent,
|
||||||
|
__req->upgrade_insecure_requests, "OK", __req->sec_fetch_site,
|
||||||
|
__req->sec_fetch_mode, __req->accept_language,
|
||||||
|
__req->accept_encoding, __req->connection);
|
||||||
|
}
|
||||||
|
|
||||||
|
void http_request_set(HttpRequest *__req, char *key, char *value) {
|
||||||
|
if (strcmp(key, "Host"))
|
||||||
|
__req->host = value;
|
||||||
|
else if (strcmp(key, "Sec-Fetch-Dest"))
|
||||||
|
__req->sec_fetch_dest = value;
|
||||||
|
else if (strcmp(key, "User-Agent"))
|
||||||
|
__req->user_agent = value;
|
||||||
|
else if (strcmp(key, "Upgrade-Insecure-Requests"))
|
||||||
|
__req->upgrade_insecure_requests = value;
|
||||||
|
else if (strcmp(key, "Accept"))
|
||||||
|
;
|
||||||
|
// __req->accept = value;
|
||||||
|
else if (strcmp(key, "Sec-Fetch-Site"))
|
||||||
|
__req->sec_fetch_site = value;
|
||||||
|
else if (strcmp(key, "Sec-Fetch-Mode"))
|
||||||
|
__req->sec_fetch_mode = value;
|
||||||
|
else if (strcmp(key, "Accept-Language"))
|
||||||
|
__req->accept_language = value;
|
||||||
|
else if (strcmp(key, "Accept-Encoding"))
|
||||||
|
__req->accept_encoding = value;
|
||||||
|
else if (strcmp(key, "Connection"))
|
||||||
|
__req->connection = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
HttpRequest *handle_request(char *__req) {
|
||||||
|
HttpRequest *request = malloc(sizeof(HttpRequest));
|
||||||
|
unsigned int line_count = 0;
|
||||||
|
char *line_start = __req;
|
||||||
|
char *line_end;
|
||||||
|
while ((line_end = strchr(line_start, '\n')) != NULL) {
|
||||||
|
line_count++;
|
||||||
|
size_t l_length = line_end - line_start;
|
||||||
|
char *line = malloc(sizeof(char) * l_length);
|
||||||
|
if (line == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
strncpy(line, line_start, l_length);
|
||||||
|
line[l_length] = 0;
|
||||||
|
if (line_count == 1) {
|
||||||
|
char method[10];
|
||||||
|
char *path = malloc(sizeof(char) * 1024);
|
||||||
|
if (sscanf(line, "%s %s", method, path) != 3) {
|
||||||
|
free(path);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
printf("%s", path);
|
||||||
|
request->method = get_http_method(method);
|
||||||
|
request->path = path;
|
||||||
|
} else {
|
||||||
|
char *key = malloc(sizeof(char) * 20);
|
||||||
|
char *value = malloc(sizeof(char) * 256);
|
||||||
|
if (sscanf(line, "%s: %s", key, value) == 2) {
|
||||||
|
http_request_set(request, key, value);
|
||||||
|
}
|
||||||
|
free(key);
|
||||||
|
}
|
||||||
|
// TODO: Analyze line
|
||||||
|
free(line);
|
||||||
|
line_start = line_end + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return request;
|
||||||
|
}
|
||||||
24
http/http_request.h
Normal file
24
http/http_request.h
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
#ifndef HTTP_REQUEST_H
|
||||||
|
#define HTTP_REQUEST_H
|
||||||
|
|
||||||
|
#include "http_content_type.h"
|
||||||
|
#include "http_method.h"
|
||||||
|
typedef struct {
|
||||||
|
HttpMethod method;
|
||||||
|
char *path;
|
||||||
|
char *host;
|
||||||
|
char *sec_fetch_dest;
|
||||||
|
char *user_agent;
|
||||||
|
char *upgrade_insecure_requests;
|
||||||
|
HttpContentType *accept;
|
||||||
|
char *sec_fetch_site;
|
||||||
|
char *sec_fetch_mode;
|
||||||
|
char *accept_language;
|
||||||
|
char *accept_encoding;
|
||||||
|
char *connection;
|
||||||
|
} HttpRequest;
|
||||||
|
|
||||||
|
HttpRequest *handle_request(char *__req);
|
||||||
|
void print_request(const HttpRequest *__req);
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -1,8 +1,12 @@
|
|||||||
#include "http_content_type.h"
|
#include "http_content_type.h"
|
||||||
#include "http_response.h"
|
#include "http_response.h"
|
||||||
#include "http_status.h"
|
#include "http_status.h"
|
||||||
|
#include <stddef.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
bool construct_response(HttpResponse __res, char *out) {
|
bool construct_response(HttpResponse __res, char *out) {
|
||||||
unsigned long length;
|
unsigned long length;
|
||||||
@@ -27,8 +31,61 @@ bool construct_response(HttpResponse __res, char *out) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void http_respond(HttpResponse __res) {
|
void http_respond(HttpResponse __res, int clientfd) {
|
||||||
char response[BUFSIZ];
|
char response[BUFSIZ];
|
||||||
// TODO: Handle return
|
// TODO: Handle return
|
||||||
construct_response(__res, response);
|
construct_response(__res, response);
|
||||||
|
|
||||||
|
send(clientfd, response, strlen(response), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
char *read_file(const char *__path) {
|
||||||
|
if (access(__path, F_OK) != 0) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
FILE *f = fopen(__path, "r");
|
||||||
|
if (f == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
fseek(f, 0, SEEK_END);
|
||||||
|
size_t length = ftell(f);
|
||||||
|
rewind(f);
|
||||||
|
|
||||||
|
char *content = malloc(length * sizeof(char));
|
||||||
|
|
||||||
|
if (content == NULL) {
|
||||||
|
fclose(f);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t bytesRead = fread(content, sizeof(char), length, f);
|
||||||
|
content[bytesRead] = 0;
|
||||||
|
|
||||||
|
fclose(f);
|
||||||
|
|
||||||
|
return content;
|
||||||
|
}
|
||||||
|
|
||||||
|
HttpResponse *from_file(const char *__path) {
|
||||||
|
char *content = read_file(__path);
|
||||||
|
if (content == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
HttpResponse response = {.status_code = HTTP_OK,
|
||||||
|
.content_length = strlen(content),
|
||||||
|
.content_type = HTTP_CT_HTML,
|
||||||
|
.body = content};
|
||||||
|
|
||||||
|
HttpResponse *res = malloc(sizeof(response));
|
||||||
|
*res = response;
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
void free_response(HttpResponse *__res) {
|
||||||
|
if (__res->body != NULL)
|
||||||
|
free(__res->body);
|
||||||
|
|
||||||
|
free(__res);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,4 +15,9 @@ typedef struct {
|
|||||||
|
|
||||||
bool construct_response(HttpResponse __res, char *out);
|
bool construct_response(HttpResponse __res, char *out);
|
||||||
|
|
||||||
|
void http_respond(HttpResponse __res, int clientfd);
|
||||||
|
char *read_file(const char *__path);
|
||||||
|
HttpResponse *from_file(const char *__path);
|
||||||
|
void free_response(HttpResponse *__res);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -4,259 +4,259 @@
|
|||||||
void http_status_message(HttpStatus __status, char *msg, size_t __size) {
|
void http_status_message(HttpStatus __status, char *msg, size_t __size) {
|
||||||
switch (__status) {
|
switch (__status) {
|
||||||
case HTTP_CONTINUE: {
|
case HTTP_CONTINUE: {
|
||||||
char http_continue[] = "Continue";
|
char http_continue[] = "CONTINUE";
|
||||||
strlcpy(msg, http_continue, __size);
|
strlcpy(msg, http_continue, __size);
|
||||||
} break;
|
} break;
|
||||||
case HTTP_SWITCHING_PROTOCOLS: {
|
case HTTP_SWITCHING_PROTOCOLS: {
|
||||||
char http_switching_protocols[] = "Switching Protocols";
|
char http_switching_protocols[] = "SWITCHING PROTOCOLS";
|
||||||
strlcpy(msg, http_switching_protocols, __size);
|
strlcpy(msg, http_switching_protocols, __size);
|
||||||
} break;
|
} break;
|
||||||
case HTTP_PROCESSING: {
|
case HTTP_PROCESSING: {
|
||||||
char http_processing[] = "Processing";
|
char http_processing[] = "PROCESSING";
|
||||||
strlcpy(msg, http_processing, __size);
|
strlcpy(msg, http_processing, __size);
|
||||||
} break;
|
} break;
|
||||||
case HTTP_EARLY_HINTS: {
|
case HTTP_EARLY_HINTS: {
|
||||||
char http_early_hints[] = "Early Hints";
|
char http_early_hints[] = "EARLY HINTS";
|
||||||
strlcpy(msg, http_early_hints, __size);
|
strlcpy(msg, http_early_hints, __size);
|
||||||
} break;
|
} break;
|
||||||
case HTTP_OK: {
|
case HTTP_OK: {
|
||||||
char http_ok[] = "Ok";
|
char http_ok[] = "OK";
|
||||||
strlcpy(msg, http_ok, __size);
|
strlcpy(msg, http_ok, __size);
|
||||||
} break;
|
} break;
|
||||||
case HTTP_CREATED: {
|
case HTTP_CREATED: {
|
||||||
char http_created[] = "Created";
|
char http_created[] = "CREATED";
|
||||||
strlcpy(msg, http_created, __size);
|
strlcpy(msg, http_created, __size);
|
||||||
} break;
|
} break;
|
||||||
case HTTP_ACCEPTED: {
|
case HTTP_ACCEPTED: {
|
||||||
char http_accepted[] = "Accepted";
|
char http_accepted[] = "ACCEPTED";
|
||||||
strlcpy(msg, http_accepted, __size);
|
strlcpy(msg, http_accepted, __size);
|
||||||
} break;
|
} break;
|
||||||
case HTTP_NON_AUTHORITATIVE_INFORMATION: {
|
case HTTP_NON_AUTHORITATIVE_INFORMATION: {
|
||||||
char http_non_authoritative_information[] =
|
char http_non_authoritative_information[] =
|
||||||
"Non Authoritative Information";
|
"NON AUTHORITATIVE INFORMATION";
|
||||||
strlcpy(msg, http_non_authoritative_information, __size);
|
strlcpy(msg, http_non_authoritative_information, __size);
|
||||||
} break;
|
} break;
|
||||||
case HTTP_NO_CONTENT: {
|
case HTTP_NO_CONTENT: {
|
||||||
char http_no_content[] = "No Content";
|
char http_no_content[] = "NO CONTENT";
|
||||||
strlcpy(msg, http_no_content, __size);
|
strlcpy(msg, http_no_content, __size);
|
||||||
} break;
|
} break;
|
||||||
case HTTP_RESET_CONTENT: {
|
case HTTP_RESET_CONTENT: {
|
||||||
char http_reset_content[] = "Reset Content";
|
char http_reset_content[] = "RESET CONTENT";
|
||||||
strlcpy(msg, http_reset_content, __size);
|
strlcpy(msg, http_reset_content, __size);
|
||||||
} break;
|
} break;
|
||||||
case HTTP_PARTIAL_CONTENT: {
|
case HTTP_PARTIAL_CONTENT: {
|
||||||
char http_partial_content[] = "Partial Content";
|
char http_partial_content[] = "PARTIAL CONTENT";
|
||||||
strlcpy(msg, http_partial_content, __size);
|
strlcpy(msg, http_partial_content, __size);
|
||||||
} break;
|
} break;
|
||||||
case HTTP_MULTI_STATUS: {
|
case HTTP_MULTI_STATUS: {
|
||||||
char http_multi_status[] = "Multi Status";
|
char http_multi_status[] = "MULTI STATUS";
|
||||||
strlcpy(msg, http_multi_status, __size);
|
strlcpy(msg, http_multi_status, __size);
|
||||||
} break;
|
} break;
|
||||||
case HTTP_ALREADY_REPORTED: {
|
case HTTP_ALREADY_REPORTED: {
|
||||||
char http_already_reported[] = "Already Reported";
|
char http_already_reported[] = "ALREADY REPORTED";
|
||||||
strlcpy(msg, http_already_reported, __size);
|
strlcpy(msg, http_already_reported, __size);
|
||||||
} break;
|
} break;
|
||||||
case HTTP_IM_USED: {
|
case HTTP_IM_USED: {
|
||||||
char http_im_used[] = "Im Used";
|
char http_im_used[] = "IM USED";
|
||||||
strlcpy(msg, http_im_used, __size);
|
strlcpy(msg, http_im_used, __size);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case HTTP_MULTIPLE_CHOICES: {
|
case HTTP_MULTIPLE_CHOICES: {
|
||||||
char http_multiple_choices[] = "Multiple Choices";
|
char http_multiple_choices[] = "MULTIPLE CHOICES";
|
||||||
strlcpy(msg, http_multiple_choices, __size);
|
strlcpy(msg, http_multiple_choices, __size);
|
||||||
} break;
|
} break;
|
||||||
case HTTP_MOVED_PERMANENTLY: {
|
case HTTP_MOVED_PERMANENTLY: {
|
||||||
char http_moved_permanently[] = "Moved Permanently";
|
char http_moved_permanently[] = "MOVED PERMANENTLY";
|
||||||
strlcpy(msg, http_moved_permanently, __size);
|
strlcpy(msg, http_moved_permanently, __size);
|
||||||
} break;
|
} break;
|
||||||
case HTTP_FOUND: {
|
case HTTP_FOUND: {
|
||||||
char http_found[] = "Found";
|
char http_found[] = "FOUND";
|
||||||
strlcpy(msg, http_found, __size);
|
strlcpy(msg, http_found, __size);
|
||||||
} break;
|
} break;
|
||||||
case HTTP_SEE_OTHER: {
|
case HTTP_SEE_OTHER: {
|
||||||
char http_see_other[] = "See Other";
|
char http_see_other[] = "SEE OTHER";
|
||||||
strlcpy(msg, http_see_other, __size);
|
strlcpy(msg, http_see_other, __size);
|
||||||
} break;
|
} break;
|
||||||
case HTTP_NOT_MODIFIED: {
|
case HTTP_NOT_MODIFIED: {
|
||||||
char http_not_modified[] = "Not Modified";
|
char http_not_modified[] = "NOT MODIFIED";
|
||||||
strlcpy(msg, http_not_modified, __size);
|
strlcpy(msg, http_not_modified, __size);
|
||||||
} break;
|
} break;
|
||||||
case HTTP_USE_PROXY: {
|
case HTTP_USE_PROXY: {
|
||||||
char http_use_proxy[] = "Use Proxy";
|
char http_use_proxy[] = "USE PROXY";
|
||||||
strlcpy(msg, http_use_proxy, __size);
|
strlcpy(msg, http_use_proxy, __size);
|
||||||
} break;
|
} break;
|
||||||
case HTTP_TEMPORARY_REDIRECT: {
|
case HTTP_TEMPORARY_REDIRECT: {
|
||||||
char http_temporary_redirect[] = "Temporary Redirect";
|
char http_temporary_redirect[] = "TEMPORARY REDIRECT";
|
||||||
strlcpy(msg, http_temporary_redirect, __size);
|
strlcpy(msg, http_temporary_redirect, __size);
|
||||||
} break;
|
} break;
|
||||||
case HTTP_PERMANENT_REDIRECT: {
|
case HTTP_PERMANENT_REDIRECT: {
|
||||||
char http_permanent_redirect[] = "Permanent Redirect";
|
char http_permanent_redirect[] = "PERMANENT REDIRECT";
|
||||||
strlcpy(msg, http_permanent_redirect, __size);
|
strlcpy(msg, http_permanent_redirect, __size);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case HTTP_BAD_REQUEST: {
|
case HTTP_BAD_REQUEST: {
|
||||||
char http_bad_request[] = "Bad Request";
|
char http_bad_request[] = "BAD REQUEST";
|
||||||
strlcpy(msg, http_bad_request, __size);
|
strlcpy(msg, http_bad_request, __size);
|
||||||
} break;
|
} break;
|
||||||
case HTTP_UNAUTHORIZED: {
|
case HTTP_UNAUTHORIZED: {
|
||||||
char http_unauthorized[] = "Unauthorized";
|
char http_unauthorized[] = "UNAUTHORIZED";
|
||||||
strlcpy(msg, http_unauthorized, __size);
|
strlcpy(msg, http_unauthorized, __size);
|
||||||
} break;
|
} break;
|
||||||
case HTTP_PAYMENT_REQUIRED: {
|
case HTTP_PAYMENT_REQUIRED: {
|
||||||
char http_payment_required[] = "Payment Required";
|
char http_payment_required[] = "PAYMENT REQUIRED";
|
||||||
strlcpy(msg, http_payment_required, __size);
|
strlcpy(msg, http_payment_required, __size);
|
||||||
} break;
|
} break;
|
||||||
case HTTP_FORBIDDEN: {
|
case HTTP_FORBIDDEN: {
|
||||||
char http_forbidden[] = "Forbidden";
|
char http_forbidden[] = "FORBIDDEN";
|
||||||
strlcpy(msg, http_forbidden, __size);
|
strlcpy(msg, http_forbidden, __size);
|
||||||
} break;
|
} break;
|
||||||
case HTTP_NOT_FOUND: {
|
case HTTP_NOT_FOUND: {
|
||||||
char http_not_found[] = "Not Found";
|
char http_not_found[] = "NOT FOUND";
|
||||||
strlcpy(msg, http_not_found, __size);
|
strlcpy(msg, http_not_found, __size);
|
||||||
} break;
|
} break;
|
||||||
case HTTP_METHOD_NOT_ALLOWED: {
|
case HTTP_METHOD_NOT_ALLOWED: {
|
||||||
char http_method_not_allowed[] = "Method Not Allowed";
|
char http_method_not_allowed[] = "METHOD NOT ALLOWED";
|
||||||
strlcpy(msg, http_method_not_allowed, __size);
|
strlcpy(msg, http_method_not_allowed, __size);
|
||||||
} break;
|
} break;
|
||||||
case HTTP_NOT_ACCEPTABLE: {
|
case HTTP_NOT_ACCEPTABLE: {
|
||||||
char http_not_acceptable[] = "Not Acceptable";
|
char http_not_acceptable[] = "NOT ACCEPTABLE";
|
||||||
strlcpy(msg, http_not_acceptable, __size);
|
strlcpy(msg, http_not_acceptable, __size);
|
||||||
} break;
|
} break;
|
||||||
case HTTP_PROXY_AUTHENTICATION_REQUIRED: {
|
case HTTP_PROXY_AUTHENTICATION_REQUIRED: {
|
||||||
char http_proxy_authentication_required[] =
|
char http_proxy_authentication_required[] =
|
||||||
"Proxy Authentication Required";
|
"PROXY AUTHENTICATION REQUIRED";
|
||||||
strlcpy(msg, http_proxy_authentication_required, __size);
|
strlcpy(msg, http_proxy_authentication_required, __size);
|
||||||
} break;
|
} break;
|
||||||
case HTTP_REQUEST_TIMEOUT: {
|
case HTTP_REQUEST_TIMEOUT: {
|
||||||
char http_request_timeout[] = "Request Timeout";
|
char http_request_timeout[] = "REQUEST TIMEOUT";
|
||||||
strlcpy(msg, http_request_timeout, __size);
|
strlcpy(msg, http_request_timeout, __size);
|
||||||
} break;
|
} break;
|
||||||
case HTTP_CONFLICT: {
|
case HTTP_CONFLICT: {
|
||||||
char http_conflict[] = "Conflict";
|
char http_conflict[] = "CONFLICT";
|
||||||
strlcpy(msg, http_conflict, __size);
|
strlcpy(msg, http_conflict, __size);
|
||||||
} break;
|
} break;
|
||||||
case HTTP_GONE: {
|
case HTTP_GONE: {
|
||||||
char http_gone[] = "Gone";
|
char http_gone[] = "GONE";
|
||||||
strlcpy(msg, http_gone, __size);
|
strlcpy(msg, http_gone, __size);
|
||||||
} break;
|
} break;
|
||||||
case HTTP_LENGTH_REQUIRED: {
|
case HTTP_LENGTH_REQUIRED: {
|
||||||
char http_length_required[] = "Length Required";
|
char http_length_required[] = "LENGTH REQUIRED";
|
||||||
strlcpy(msg, http_length_required, __size);
|
strlcpy(msg, http_length_required, __size);
|
||||||
} break;
|
} break;
|
||||||
case HTTP_PRECONDITION_FAILED: {
|
case HTTP_PRECONDITION_FAILED: {
|
||||||
char http_precondition_failed[] = "Precondition Failed";
|
char http_precondition_failed[] = "PRECONDITION FAILED";
|
||||||
strlcpy(msg, http_precondition_failed, __size);
|
strlcpy(msg, http_precondition_failed, __size);
|
||||||
} break;
|
} break;
|
||||||
case HTTP_PAYLOAD_TOO_LARGE: {
|
case HTTP_PAYLOAD_TOO_LARGE: {
|
||||||
char http_payload_too_large[] = "Payload Too Large";
|
char http_payload_too_large[] = "PAYLOAD TOO LARGE";
|
||||||
strlcpy(msg, http_payload_too_large, __size);
|
strlcpy(msg, http_payload_too_large, __size);
|
||||||
} break;
|
} break;
|
||||||
case HTTP_URI_TOO_LONG: {
|
case HTTP_URI_TOO_LONG: {
|
||||||
char http_uri_too_long[] = "Uri Too Long";
|
char http_uri_too_long[] = "URI TOO LONG";
|
||||||
strlcpy(msg, http_uri_too_long, __size);
|
strlcpy(msg, http_uri_too_long, __size);
|
||||||
} break;
|
} break;
|
||||||
case HTTP_UNSUPPORTED_MEDIA_TYPE: {
|
case HTTP_UNSUPPORTED_MEDIA_TYPE: {
|
||||||
char http_unsupported_media_type[] = "Unsupported Media Type";
|
char http_unsupported_media_type[] = "UNSUPPORTED MEDIA TYPE";
|
||||||
strlcpy(msg, http_unsupported_media_type, __size);
|
strlcpy(msg, http_unsupported_media_type, __size);
|
||||||
} break;
|
} break;
|
||||||
case HTTP_RANGE_NOT_SATISFIABLE: {
|
case HTTP_RANGE_NOT_SATISFIABLE: {
|
||||||
char http_range_not_satisfiable[] = "Range Not Satisfiable";
|
char http_range_not_satisfiable[] = "RANGE NOT SATISFIABLE";
|
||||||
strlcpy(msg, http_range_not_satisfiable, __size);
|
strlcpy(msg, http_range_not_satisfiable, __size);
|
||||||
} break;
|
} break;
|
||||||
case HTTP_EXPECTATION_FAILED: {
|
case HTTP_EXPECTATION_FAILED: {
|
||||||
char http_expectation_failed[] = "Expectation Failed";
|
char http_expectation_failed[] = "EXPECTATION FAILED";
|
||||||
strlcpy(msg, http_expectation_failed, __size);
|
strlcpy(msg, http_expectation_failed, __size);
|
||||||
} break;
|
} break;
|
||||||
case HTTP_IM_A_TEAPOT: {
|
case HTTP_IM_A_TEAPOT: {
|
||||||
char http_im_a_teapot[] = "Im A Teapot";
|
char http_im_a_teapot[] = "IM A TEAPOT";
|
||||||
strlcpy(msg, http_im_a_teapot, __size);
|
strlcpy(msg, http_im_a_teapot, __size);
|
||||||
} break;
|
} break;
|
||||||
case HTTP_MISDIRECTED_REQUEST: {
|
case HTTP_MISDIRECTED_REQUEST: {
|
||||||
char http_misdirected_request[] = "Misdirected Request";
|
char http_misdirected_request[] = "MISDIRECTED REQUEST";
|
||||||
strlcpy(msg, http_misdirected_request, __size);
|
strlcpy(msg, http_misdirected_request, __size);
|
||||||
} break;
|
} break;
|
||||||
case HTTP_UNPROCESSABLE_ENTITY: {
|
case HTTP_UNPROCESSABLE_ENTITY: {
|
||||||
char http_unprocessable_entity[] = "Unprocessable Entity";
|
char http_unprocessable_entity[] = "UNPROCESSABLE ENTITY";
|
||||||
strlcpy(msg, http_unprocessable_entity, __size);
|
strlcpy(msg, http_unprocessable_entity, __size);
|
||||||
} break;
|
} break;
|
||||||
case HTTP_LOCKED: {
|
case HTTP_LOCKED: {
|
||||||
char http_locked[] = "Locked";
|
char http_locked[] = "LOCKED";
|
||||||
strlcpy(msg, http_locked, __size);
|
strlcpy(msg, http_locked, __size);
|
||||||
} break;
|
} break;
|
||||||
case HTTP_FAILED_DEPENDENCY: {
|
case HTTP_FAILED_DEPENDENCY: {
|
||||||
char http_failed_dependency[] = "Failed Dependency";
|
char http_failed_dependency[] = "FAILED DEPENDENCY";
|
||||||
strlcpy(msg, http_failed_dependency, __size);
|
strlcpy(msg, http_failed_dependency, __size);
|
||||||
} break;
|
} break;
|
||||||
case HTTP_TOO_EARLY: {
|
case HTTP_TOO_EARLY: {
|
||||||
char http_too_early[] = "Too Early";
|
char http_too_early[] = "TOO EARLY";
|
||||||
strlcpy(msg, http_too_early, __size);
|
strlcpy(msg, http_too_early, __size);
|
||||||
} break;
|
} break;
|
||||||
case HTTP_UPGRADE_REQUIRED: {
|
case HTTP_UPGRADE_REQUIRED: {
|
||||||
char http_upgrade_required[] = "Upgrade Required";
|
char http_upgrade_required[] = "UPGRADE REQUIRED";
|
||||||
strlcpy(msg, http_upgrade_required, __size);
|
strlcpy(msg, http_upgrade_required, __size);
|
||||||
} break;
|
} break;
|
||||||
case HTTP_PRECONDITION_REQUIRED: {
|
case HTTP_PRECONDITION_REQUIRED: {
|
||||||
char http_precondition_required[] = "Precondition Required";
|
char http_precondition_required[] = "PRECONDITION REQUIRED";
|
||||||
strlcpy(msg, http_precondition_required, __size);
|
strlcpy(msg, http_precondition_required, __size);
|
||||||
} break;
|
} break;
|
||||||
case HTTP_TOO_MANY_REQUESTS: {
|
case HTTP_TOO_MANY_REQUESTS: {
|
||||||
char http_too_many_requests[] = "Too Many Requests";
|
char http_too_many_requests[] = "TOO MANY REQUESTS";
|
||||||
strlcpy(msg, http_too_many_requests, __size);
|
strlcpy(msg, http_too_many_requests, __size);
|
||||||
} break;
|
} break;
|
||||||
case HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE: {
|
case HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE: {
|
||||||
char http_request_header_fields_too_large[] =
|
char http_request_header_fields_too_large[] =
|
||||||
"Request Header Fields Too Large";
|
"REQUEST HEADER FIELDS TOO LARGE";
|
||||||
strlcpy(msg, http_request_header_fields_too_large, __size);
|
strlcpy(msg, http_request_header_fields_too_large, __size);
|
||||||
} break;
|
} break;
|
||||||
case HTTP_UNAVAILABLE_FOR_LEGAL_REASONS: {
|
case HTTP_UNAVAILABLE_FOR_LEGAL_REASONS: {
|
||||||
char http_unavailable_for_legal_reasons[] =
|
char http_unavailable_for_legal_reasons[] =
|
||||||
"Unavailable For Legal Reasons";
|
"UNAVAILABLE FOR LEGAL REASONS";
|
||||||
strlcpy(msg, http_unavailable_for_legal_reasons, __size);
|
strlcpy(msg, http_unavailable_for_legal_reasons, __size);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case HTTP_INTERNAL_SERVER_ERROR: {
|
case HTTP_INTERNAL_SERVER_ERROR: {
|
||||||
char http_internal_server_error[] = "Internal Server Error";
|
char http_internal_server_error[] = "INTERNAL SERVER ERROR";
|
||||||
strlcpy(msg, http_internal_server_error, __size);
|
strlcpy(msg, http_internal_server_error, __size);
|
||||||
} break;
|
} break;
|
||||||
case HTTP_NOT_IMPLEMENTED: {
|
case HTTP_NOT_IMPLEMENTED: {
|
||||||
char http_not_implemented[] = "Not Implemented";
|
char http_not_implemented[] = "NOT IMPLEMENTED";
|
||||||
strlcpy(msg, http_not_implemented, __size);
|
strlcpy(msg, http_not_implemented, __size);
|
||||||
} break;
|
} break;
|
||||||
case HTTP_BAD_GATEWAY: {
|
case HTTP_BAD_GATEWAY: {
|
||||||
char http_bad_gateway[] = "Bad Gateway";
|
char http_bad_gateway[] = "BAD GATEWAY";
|
||||||
strlcpy(msg, http_bad_gateway, __size);
|
strlcpy(msg, http_bad_gateway, __size);
|
||||||
} break;
|
} break;
|
||||||
case HTTP_SERVICE_UNAVAILABLE: {
|
case HTTP_SERVICE_UNAVAILABLE: {
|
||||||
char http_service_unavailable[] = "Service Unavailable";
|
char http_service_unavailable[] = "SERVICE UNAVAILABLE";
|
||||||
strlcpy(msg, http_service_unavailable, __size);
|
strlcpy(msg, http_service_unavailable, __size);
|
||||||
} break;
|
} break;
|
||||||
case HTTP_GATEWAY_TIMEOUT: {
|
case HTTP_GATEWAY_TIMEOUT: {
|
||||||
char http_gateway_timeout[] = "Gateway Timeout";
|
char http_gateway_timeout[] = "GATEWAY TIMEOUT";
|
||||||
strlcpy(msg, http_gateway_timeout, __size);
|
strlcpy(msg, http_gateway_timeout, __size);
|
||||||
} break;
|
} break;
|
||||||
case HTTP_HTTP_VERSION_NOT_SUPPORTED: {
|
case HTTP_HTTP_VERSION_NOT_SUPPORTED: {
|
||||||
char http_http_version_not_supported[] = "Http Version Not Supported";
|
char http_http_version_not_supported[] = "HTTP VERSION NOT SUPPORTED";
|
||||||
strlcpy(msg, http_http_version_not_supported, __size);
|
strlcpy(msg, http_http_version_not_supported, __size);
|
||||||
} break;
|
} break;
|
||||||
case HTTP_VARIANT_ALSO_NEGOTIATES: {
|
case HTTP_VARIANT_ALSO_NEGOTIATES: {
|
||||||
char http_variant_also_negotiates[] = "Variant Also Negotiates";
|
char http_variant_also_negotiates[] = "VARIANT ALSO NEGOTIATES";
|
||||||
strlcpy(msg, http_variant_also_negotiates, __size);
|
strlcpy(msg, http_variant_also_negotiates, __size);
|
||||||
} break;
|
} break;
|
||||||
case HTTP_INSUFFICIENT_STORAGE: {
|
case HTTP_INSUFFICIENT_STORAGE: {
|
||||||
char http_insufficient_storage[] = "Insufficient Storage";
|
char http_insufficient_storage[] = "INSUFFICIENT STORAGE";
|
||||||
strlcpy(msg, http_insufficient_storage, __size);
|
strlcpy(msg, http_insufficient_storage, __size);
|
||||||
} break;
|
} break;
|
||||||
case HTTP_LOOP_DETECTED: {
|
case HTTP_LOOP_DETECTED: {
|
||||||
char http_loop_detected[] = "Loop Detected";
|
char http_loop_detected[] = "LOOP DETECTED";
|
||||||
strlcpy(msg, http_loop_detected, __size);
|
strlcpy(msg, http_loop_detected, __size);
|
||||||
} break;
|
} break;
|
||||||
case HTTP_NOT_EXTENDED: {
|
case HTTP_NOT_EXTENDED: {
|
||||||
char http_not_extended[] = "Not Extended";
|
char http_not_extended[] = "NOT EXTENDED";
|
||||||
strlcpy(msg, http_not_extended, __size);
|
strlcpy(msg, http_not_extended, __size);
|
||||||
} break;
|
} break;
|
||||||
case HTTP_NETWORK_AUTHENTICATION_REQUIRED: {
|
case HTTP_NETWORK_AUTHENTICATION_REQUIRED: {
|
||||||
char http_network_authentication_required[] =
|
char http_network_authentication_required[] =
|
||||||
"Network Authentication Required";
|
"NETWORK AUTHENTICATION REQUIRED";
|
||||||
strlcpy(msg, http_network_authentication_required, __size);
|
strlcpy(msg, http_network_authentication_required, __size);
|
||||||
} break;
|
} break;
|
||||||
}
|
}
|
||||||
|
|||||||
14
index.html
Normal file
14
index.html
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>cweb</title>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
Hello, World!
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
||||||
64
main.c
64
main.c
@@ -1,19 +1,65 @@
|
|||||||
|
#include "http/http_request.h"
|
||||||
#include "http/http_response.h"
|
#include "http/http_response.h"
|
||||||
#include "http/http_status.h"
|
#include <netinet/in.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
|
|
||||||
char body[BUFSIZ] = "<html><h1>Bonsoir</h1></html>";
|
const int PORT = 8080;
|
||||||
HttpResponse response = {.status_code = HTTP_OK,
|
|
||||||
.content_type = HTTP_CT_HTML,
|
|
||||||
.content_length = strlen(body),
|
|
||||||
.body = body};
|
|
||||||
|
|
||||||
char out[BUFSIZ];
|
int serverfd, clientfd;
|
||||||
construct_response(response, out);
|
ssize_t valread;
|
||||||
|
|
||||||
|
struct sockaddr_in address;
|
||||||
|
int opt = 1;
|
||||||
|
socklen_t addrlen = sizeof(address);
|
||||||
|
char request[BUFSIZ] = {0};
|
||||||
|
|
||||||
|
if ((serverfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
|
||||||
|
perror("socket failed");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Forcefully attaching socket to the port 8080
|
||||||
|
if (setsockopt(serverfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt))) {
|
||||||
|
perror("setsockopt");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
address.sin_family = AF_INET;
|
||||||
|
address.sin_addr.s_addr = INADDR_ANY;
|
||||||
|
address.sin_port = htons(PORT);
|
||||||
|
|
||||||
|
if (bind(serverfd, (struct sockaddr *)&address, sizeof(address)) < 0) {
|
||||||
|
perror("bind failed");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
if (listen(serverfd, 3) < 0) {
|
||||||
|
perror("listen");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
if ((clientfd = accept(serverfd, (struct sockaddr *)&address, &addrlen)) <
|
||||||
|
0) {
|
||||||
|
perror("accept");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
valread = read(clientfd, request,
|
||||||
|
1024 - 1); // subtract 1 for the null
|
||||||
|
// terminator at the end
|
||||||
|
HttpRequest *req = handle_request(request);
|
||||||
|
// print_request(req);
|
||||||
|
HttpResponse *res = from_file("./index.html");
|
||||||
|
http_respond(*res, clientfd);
|
||||||
|
free_response(res);
|
||||||
|
printf("Hello message sent\n");
|
||||||
|
|
||||||
|
// closing the connected socket
|
||||||
|
close(clientfd);
|
||||||
|
// closing the listening socket
|
||||||
|
close(clientfd);
|
||||||
|
|
||||||
printf("%s", out);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
28
premake5.lua
Normal file
28
premake5.lua
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
workspace "CWeb"
|
||||||
|
configurations { "Debug", "Release" }
|
||||||
|
|
||||||
|
project "CWebLibrary"
|
||||||
|
kind "StaticLib"
|
||||||
|
language "C"
|
||||||
|
targetdir "bin/%{cfg.buildcfg}"
|
||||||
|
|
||||||
|
files {
|
||||||
|
"http/*.c",
|
||||||
|
"http/*.h"
|
||||||
|
}
|
||||||
|
|
||||||
|
project "cweb"
|
||||||
|
kind "ConsoleApp"
|
||||||
|
language "C"
|
||||||
|
targetdir "bin/%{cfg.buildcfg}"
|
||||||
|
|
||||||
|
files { "main.c" }
|
||||||
|
|
||||||
|
includedirs { "http" }
|
||||||
|
links { "CWebLibrary" }
|
||||||
|
|
||||||
|
filter "configurations:Debug"
|
||||||
|
symbols "On"
|
||||||
|
|
||||||
|
filter "configurations:Release"
|
||||||
|
optimize "On"
|
||||||
Reference in New Issue
Block a user