From c668d8ffce65973da7641d26eba7c0090453c308 Mon Sep 17 00:00:00 2001 From: Brando Date: Wed, 26 Feb 2025 14:24:17 -0800 Subject: [PATCH 01/39] temp work --- external/libs | 2 +- makefile | 22 +++++++++++----------- src/main.cpp | 31 ++++++++++++++++++++++++++++--- 3 files changed, 40 insertions(+), 15 deletions(-) diff --git a/external/libs b/external/libs index 075a26b..ac09548 160000 --- a/external/libs +++ b/external/libs @@ -1 +1 @@ -Subproject commit 075a26b8f9ec93110cd3dd22a6e319e970b40519 +Subproject commit ac095483c478f543b07eeb88a664e3e32d5b274e diff --git a/makefile b/makefile index ae0766b..2e7ca2f 100644 --- a/makefile +++ b/makefile @@ -37,41 +37,41 @@ BIN_PATH = bin/$(CONFIG) BUILD_TYPE = executable SOURCE_EXT = cpp HEADER_EXT = hpp -FILES = \ +FILES = ifeq ($(CONFIG),release) # release -LIBRARIES += \ - external/bin/libs/release/bflibc/libbfc.a \ +LIBRARIES = \ + external/bin/libs/release/bfnet/libbfnet.a \ external/bin/libs/release/bflibcpp/libbfcpp.a \ - external/bin/libs/release/bfnet/libbfnet.a + external/bin/libs/release/bflibc/libbfc.a else -LIBRARIES += \ - external/bin/libs/debug/bflibc/libbfc-debug.a \ +LIBRARIES = \ + external/bin/libs/debug/bfnet/libbfnet-debug.a \ external/bin/libs/debug/bflibcpp/libbfcpp-debug.a \ - external/bin/libs/debug/bfnet/libbfnet-debug.a + external/bin/libs/debug/bflibc/libbfc-debug.a endif -LINKS = $(BF_LIB_C_FLAGS) +LINKS = -lpthread $(BF_LIB_C_FLAGS) -ldl ### Release settings ifeq ($(CONFIG),release) # release MAIN_FILE = src/main.cpp BIN_NAME = http -FLAGS = $(CPPFLAGS) -Isrc/ $(CPPSTD) -Iexternal/bin/libs/release $(OPENSSL_INCLUDE_PATH) +FLAGS = $(CPPFLAGS) -Isrc/ $(CPPSTD) -Iexternal/bin/libs/release ### Debug settings else ifeq ($(CONFIG),debug) # debug MAIN_FILE = src/main.cpp BIN_NAME = http #ADDR_SANITIZER = -fsanitize=address -FLAGS = $(CPPFLAGS) -DDEBUG -g -Isrc/ $(ADDR_SANITIZER) $(CPPSTD) -Iexternal/bin/libs/debug $(OPENSSL_INCLUDE_PATH) +FLAGS = $(CPPFLAGS) -DDEBUG -g -Isrc/ $(ADDR_SANITIZER) $(CPPSTD) -Iexternal/bin/libs/debug ### Test settings else ifeq ($(CONFIG),test) # test MAIN_FILE = testbench/tests.cpp BIN_NAME = http-test #ADDR_SANITIZER = -fsanitize=address -FLAGS = $(CPPFLAGS) -DDEBUG -DTESTING -g -Isrc/ $(ADDR_SANITIZER) $(CPPSTD) -Iexternal/bin/libs/debug $(OPENSSL_INCLUDE_PATH) +FLAGS = $(CPPFLAGS) -DDEBUG -DTESTING -g -Isrc/ $(ADDR_SANITIZER) $(CPPSTD) -Iexternal/bin/libs/debug LIBRARIES += external/bin/libs/debug/bftest/libbftest-debug.a endif # ($(CONFIG),...) diff --git a/src/main.cpp b/src/main.cpp index be62cce..6d4e034 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -3,10 +3,35 @@ * date: 2/26/25 */ -#include +#include +#include +#include +#include + +extern "C" { +#include +} + + +using namespace BF::Net; +using namespace std; int main() { - printf("Hello world!\n"); - return 0; + int error = 0; + Socket * skt = Socket::create(SOCKET_MODE_SERVER, "127.0.0.1", 8080, &error); + if (!error) { + error = skt->start(); + } + + cout << "Press any key to stop..."; + cin.get(); + + if (!error) { + error = skt->stop(); + } + + BFRelease(skt); + + return error; } From 0433f7e77100e748c84c9c517132f074198b85d1 Mon Sep 17 00:00:00 2001 From: Brando Date: Wed, 26 Feb 2025 14:53:44 -0800 Subject: [PATCH 02/39] saving work --- external/libs | 2 +- src/main.cpp | 24 +++++++++++++++++++----- 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/external/libs b/external/libs index ac09548..c14b177 160000 --- a/external/libs +++ b/external/libs @@ -1 +1 @@ -Subproject commit ac095483c478f543b07eeb88a664e3e32d5b274e +Subproject commit c14b177f2708fead08f87f5565de2404282a036a diff --git a/src/main.cpp b/src/main.cpp index 6d4e034..d7f1fb6 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -12,21 +12,35 @@ extern "C" { #include } - using namespace BF::Net; using namespace std; +void __LogCallbackBFNet(const char * buf) { \ + cout << "bfnet: " << buf << endl; +} + +void __NewConnection(Connection * sc) { + cout << "new connection made" << endl; +} + +void __PacketReceive(SocketEnvelope * envelope) { + cout << envelope->buf()->data() << endl; +} + int main() { int error = 0; - Socket * skt = Socket::create(SOCKET_MODE_SERVER, "127.0.0.1", 8080, &error); + Log::SetCallback(__LogCallbackBFNet); + Socket * skt = Socket::create(SOCKET_MODE_SERVER, "0.0.0.0", 8080, &error); if (!error) { + skt->setInStreamCallback(__PacketReceive); + skt->setNewConnectionCallback(__NewConnection); + skt->setBufferSize(1024); error = skt->start(); } - cout << "Press any key to stop..."; - cin.get(); - if (!error) { + cout << "Press any key to stop..."; + cin.get(); error = skt->stop(); } From b9da158cfdc1c3bac0fb566e174ab2a24c1c7d50 Mon Sep 17 00:00:00 2001 From: Brando Date: Wed, 26 Feb 2025 15:30:41 -0800 Subject: [PATCH 03/39] updating --- src/main.cpp | 4 ++-- todo.md | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index d7f1fb6..21975ba 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -24,7 +24,7 @@ void __NewConnection(Connection * sc) { } void __PacketReceive(SocketEnvelope * envelope) { - cout << envelope->buf()->data() << endl; + cout << "envelope: " << (const char *) envelope->buf()->data() << endl; } int main() { @@ -34,7 +34,7 @@ int main() { if (!error) { skt->setInStreamCallback(__PacketReceive); skt->setNewConnectionCallback(__NewConnection); - skt->setBufferSize(1024); + skt->setBufferSize(1024 * 1024 * 100); error = skt->start(); } diff --git a/todo.md b/todo.md index 7c0a2f3..09acf15 100644 --- a/todo.md +++ b/todo.md @@ -1,2 +1,3 @@ **0.1** -- [ ] server html +- [ ] serve html + - [ ] receive http requests from client From b6d7035d3ccd3ec4feb0f6b08598014c7c5e9717 Mon Sep 17 00:00:00 2001 From: Brando Date: Tue, 25 Mar 2025 14:21:30 -0700 Subject: [PATCH 04/39] updating libs --- external/libs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/external/libs b/external/libs index c14b177..81635d0 160000 --- a/external/libs +++ b/external/libs @@ -1 +1 @@ -Subproject commit c14b177f2708fead08f87f5565de2404282a036a +Subproject commit 81635d08903c47cbf5d8dc08826139749bb152c5 From b6c2c38d806897e87850d47efb74194167cc3f8d Mon Sep 17 00:00:00 2001 From: Brando Date: Tue, 25 Mar 2025 14:21:51 -0700 Subject: [PATCH 05/39] saving work --- todo.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/todo.md b/todo.md index 09acf15..792f63c 100644 --- a/todo.md +++ b/todo.md @@ -1,3 +1,3 @@ **0.1** - [ ] serve html - - [ ] receive http requests from client + - [ ] receive http requests from client (be sure to assemble the packets) From f8b38a490955c1e9990663374438c6dee1da7aeb Mon Sep 17 00:00:00 2001 From: Brando Date: Wed, 2 Apr 2025 16:40:30 -0700 Subject: [PATCH 06/39] Can read input --- src/main.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 21975ba..1b2420b 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -23,8 +23,8 @@ void __NewConnection(Connection * sc) { cout << "new connection made" << endl; } -void __PacketReceive(SocketEnvelope * envelope) { - cout << "envelope: " << (const char *) envelope->buf()->data() << endl; +void __PacketReceive(Envelope * envelope) { + cout << "envelope: " << (const char *) envelope->data()->buffer() << endl; } int main() { From 7e15e38acbaf0752b31ad6ece18cbaaadc3e119a Mon Sep 17 00:00:00 2001 From: Brando Date: Thu, 3 Apr 2025 13:26:16 -0700 Subject: [PATCH 07/39] can handle requests on separate queue --- src/main.cpp | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 52 insertions(+), 1 deletion(-) diff --git a/src/main.cpp b/src/main.cpp index 1b2420b..af1abe6 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -13,8 +13,19 @@ extern "C" { } using namespace BF::Net; +using namespace BF; using namespace std; +/** + * holds all incoming envelopes from open socket + * + * all envelopes are retained, so these should be released + * once popped from queue + */ +Atomic> _incomingRequests; +BFThreadAsyncID _tidRequestQueue = NULL; +BFLock _queueSema; + void __LogCallbackBFNet(const char * buf) { \ cout << "bfnet: " << buf << endl; } @@ -24,12 +35,46 @@ void __NewConnection(Connection * sc) { } void __PacketReceive(Envelope * envelope) { - cout << "envelope: " << (const char *) envelope->data()->buffer() << endl; + _incomingRequests.lock(); + + BFRetain(envelope); + _incomingRequests.unsafeget().push(envelope); + + _incomingRequests.unlock(); + BFLockRelease(&_queueSema); +} + +void _IncomingRequestsWorkerThread(void * in) { + while (!BFThreadAsyncIsCanceled(_tidRequestQueue)) { + if (_incomingRequests.get().empty()) { + BFLockWait(&_queueSema); + } else { + _incomingRequests.lock(); + + // get first item from the queue + Envelope * envelope = _incomingRequests.unsafeget().front(); + + // pop off + _incomingRequests.unsafeget().pop(); + + cout << "envelope: " << (const char *) envelope->data()->buffer() << endl; + + // release memory + BFRelease(envelope); + + _incomingRequests.unlock(); + } + } + } int main() { int error = 0; Log::SetCallback(__LogCallbackBFNet); + + BFLockCreate(&_queueSema); + _tidRequestQueue = BFThreadAsync(_IncomingRequestsWorkerThread, NULL); + Socket * skt = Socket::create(SOCKET_MODE_SERVER, "0.0.0.0", 8080, &error); if (!error) { skt->setInStreamCallback(__PacketReceive); @@ -46,6 +91,12 @@ int main() { BFRelease(skt); + BFThreadAsyncCancel(_tidRequestQueue); + BFThreadAsyncWait(_tidRequestQueue); + BFThreadAsyncDestroy(_tidRequestQueue); + + BFLockDestroy(&_queueSema); + return error; } From 607721e08058857ba41c252b43eb34bcda09e866 Mon Sep 17 00:00:00 2001 From: Brando Date: Thu, 3 Apr 2025 13:36:42 -0700 Subject: [PATCH 08/39] moving logic to office source file --- makefile | 2 +- src/main.cpp | 58 +++------------------------------------- src/office.cpp | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/office.hpp | 20 ++++++++++++++ 4 files changed, 97 insertions(+), 55 deletions(-) create mode 100644 src/office.cpp create mode 100644 src/office.hpp diff --git a/makefile b/makefile index 2e7ca2f..d1402e7 100644 --- a/makefile +++ b/makefile @@ -37,7 +37,7 @@ BIN_PATH = bin/$(CONFIG) BUILD_TYPE = executable SOURCE_EXT = cpp HEADER_EXT = hpp -FILES = +FILES = office ifeq ($(CONFIG),release) # release LIBRARIES = \ diff --git a/src/main.cpp b/src/main.cpp index af1abe6..c7e89ea 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -3,6 +3,7 @@ * date: 2/26/25 */ +#include "office.hpp" #include #include #include @@ -16,16 +17,6 @@ using namespace BF::Net; using namespace BF; using namespace std; -/** - * holds all incoming envelopes from open socket - * - * all envelopes are retained, so these should be released - * once popped from queue - */ -Atomic> _incomingRequests; -BFThreadAsyncID _tidRequestQueue = NULL; -BFLock _queueSema; - void __LogCallbackBFNet(const char * buf) { \ cout << "bfnet: " << buf << endl; } @@ -34,50 +25,14 @@ void __NewConnection(Connection * sc) { cout << "new connection made" << endl; } -void __PacketReceive(Envelope * envelope) { - _incomingRequests.lock(); - - BFRetain(envelope); - _incomingRequests.unsafeget().push(envelope); - - _incomingRequests.unlock(); - BFLockRelease(&_queueSema); -} - -void _IncomingRequestsWorkerThread(void * in) { - while (!BFThreadAsyncIsCanceled(_tidRequestQueue)) { - if (_incomingRequests.get().empty()) { - BFLockWait(&_queueSema); - } else { - _incomingRequests.lock(); - - // get first item from the queue - Envelope * envelope = _incomingRequests.unsafeget().front(); - - // pop off - _incomingRequests.unsafeget().pop(); - - cout << "envelope: " << (const char *) envelope->data()->buffer() << endl; - - // release memory - BFRelease(envelope); - - _incomingRequests.unlock(); - } - } - -} - int main() { int error = 0; Log::SetCallback(__LogCallbackBFNet); - BFLockCreate(&_queueSema); - _tidRequestQueue = BFThreadAsync(_IncomingRequestsWorkerThread, NULL); - + Office::start(); Socket * skt = Socket::create(SOCKET_MODE_SERVER, "0.0.0.0", 8080, &error); if (!error) { - skt->setInStreamCallback(__PacketReceive); + skt->setInStreamCallback(Office::envelopeReceive); skt->setNewConnectionCallback(__NewConnection); skt->setBufferSize(1024 * 1024 * 100); error = skt->start(); @@ -90,12 +45,7 @@ int main() { } BFRelease(skt); - - BFThreadAsyncCancel(_tidRequestQueue); - BFThreadAsyncWait(_tidRequestQueue); - BFThreadAsyncDestroy(_tidRequestQueue); - - BFLockDestroy(&_queueSema); + Office::stop(); return error; } diff --git a/src/office.cpp b/src/office.cpp new file mode 100644 index 0000000..2e8b174 --- /dev/null +++ b/src/office.cpp @@ -0,0 +1,72 @@ +/** + * author: brando + * date: 4/3/25 + */ + +#include "office.hpp" +#include +#include +#include +#include + +using namespace BF::Net; +using namespace BF; +using namespace std; + +/** + * holds all incoming envelopes from open socket + * + * all envelopes are retained, so these should be released + * once popped from queue + */ +Atomic> _incomingRequests; +BFThreadAsyncID _tidRequestQueue = NULL; +BFLock _queueSema; + +void Office::envelopeReceive(Envelope * envelope) { + _incomingRequests.lock(); + + BFRetain(envelope); + _incomingRequests.unsafeget().push(envelope); + + _incomingRequests.unlock(); + BFLockRelease(&_queueSema); +} + +void __IncomingRequestsWorkerThread(void * in) { + while (!BFThreadAsyncIsCanceled(_tidRequestQueue)) { + if (_incomingRequests.get().empty()) { + BFLockWait(&_queueSema); + } else { + _incomingRequests.lock(); + + // get first item from the queue + Envelope * envelope = _incomingRequests.unsafeget().front(); + + // pop off + _incomingRequests.unsafeget().pop(); + + cout << "envelope: " << (const char *) envelope->data()->buffer() << endl; + + // release memory + BFRelease(envelope); + + _incomingRequests.unlock(); + } + } + +} + +void Office::start() { + BFLockCreate(&_queueSema); + _tidRequestQueue = BFThreadAsync(__IncomingRequestsWorkerThread, NULL); +} + +void Office::stop() { + BFThreadAsyncCancel(_tidRequestQueue); + BFThreadAsyncWait(_tidRequestQueue); + BFThreadAsyncDestroy(_tidRequestQueue); + + BFLockDestroy(&_queueSema); +} + diff --git a/src/office.hpp b/src/office.hpp new file mode 100644 index 0000000..8436b86 --- /dev/null +++ b/src/office.hpp @@ -0,0 +1,20 @@ +/** + * author: brando + * date: 4/3/25 + */ + +#ifndef OFFICE_HPP +#define OFFICE_HPP + +#include + +namespace Office { + +void envelopeReceive(BF::Net::Envelope * envelope); +void start(); +void stop(); + +} + +#endif // OFFICE_HPP + From 0d6caa3a062ab818cd1c2cb81855c03d8fd1d5e8 Mon Sep 17 00:00:00 2001 From: Brando Date: Thu, 3 Apr 2025 13:40:31 -0700 Subject: [PATCH 09/39] adding notes --- notes.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 notes.md diff --git a/notes.md b/notes.md new file mode 100644 index 0000000..aa9313a --- /dev/null +++ b/notes.md @@ -0,0 +1 @@ +* Using https://developer.mozilla.org/en-US/docs/Web/HTTP as a guide From c249779630de651eb6790f126e767d27dd72f5a2 Mon Sep 17 00:00:00 2001 From: Brando Date: Thu, 3 Apr 2025 15:19:40 -0700 Subject: [PATCH 10/39] adding request and response files --- external/libs | 2 +- makefile | 2 +- src/office.cpp | 13 +++++++++++-- src/request.cpp | 17 +++++++++++++++++ src/request.hpp | 22 ++++++++++++++++++++++ src/response.cpp | 17 +++++++++++++++++ src/response.hpp | 25 +++++++++++++++++++++++++ 7 files changed, 94 insertions(+), 4 deletions(-) create mode 100644 src/request.cpp create mode 100644 src/request.hpp create mode 100644 src/response.cpp create mode 100644 src/response.hpp diff --git a/external/libs b/external/libs index 81635d0..3647633 160000 --- a/external/libs +++ b/external/libs @@ -1 +1 @@ -Subproject commit 81635d08903c47cbf5d8dc08826139749bb152c5 +Subproject commit 3647633e910e4d20e655259647e598ea7dc8f156 diff --git a/makefile b/makefile index d1402e7..34fd328 100644 --- a/makefile +++ b/makefile @@ -37,7 +37,7 @@ BIN_PATH = bin/$(CONFIG) BUILD_TYPE = executable SOURCE_EXT = cpp HEADER_EXT = hpp -FILES = office +FILES = office request response ifeq ($(CONFIG),release) # release LIBRARIES = \ diff --git a/src/office.cpp b/src/office.cpp index 2e8b174..eee214b 100644 --- a/src/office.cpp +++ b/src/office.cpp @@ -4,6 +4,8 @@ */ #include "office.hpp" +#include "request.hpp" +#include "response.hpp" #include #include #include @@ -33,6 +35,10 @@ void Office::envelopeReceive(Envelope * envelope) { BFLockRelease(&_queueSema); } +void __IncomingRequestHandle(Request * request) { + +} + void __IncomingRequestsWorkerThread(void * in) { while (!BFThreadAsyncIsCanceled(_tidRequestQueue)) { if (_incomingRequests.get().empty()) { @@ -47,14 +53,17 @@ void __IncomingRequestsWorkerThread(void * in) { _incomingRequests.unsafeget().pop(); cout << "envelope: " << (const char *) envelope->data()->buffer() << endl; + Request * req = new Request(envelope->data()); - // release memory + Response * resp = Response::fromRequest(req); + + BFRelease(resp); + BFRelease(req); BFRelease(envelope); _incomingRequests.unlock(); } } - } void Office::start() { diff --git a/src/request.cpp b/src/request.cpp new file mode 100644 index 0000000..f9a22ff --- /dev/null +++ b/src/request.cpp @@ -0,0 +1,17 @@ +/** + * author: brando + * date: 4/3/25 + */ + +#include "request.hpp" +#include + +using namespace BF; + +Request::Request(const Data * data) { + this->_message.alloc(data->size(), (const unsigned char *) data->buffer()); +} + +Request::~Request() { +} + diff --git a/src/request.hpp b/src/request.hpp new file mode 100644 index 0000000..3983857 --- /dev/null +++ b/src/request.hpp @@ -0,0 +1,22 @@ +/** + * author: brando + * date: 4/3/25 + */ + +#ifndef REQUEST_HPP +#define REQUEST_HPP + +#include +#include + +class Request : public BF::Object { +public: + Request(const BF::Data * data); + virtual ~Request(); + +private: + BF::Data _message; +}; + +#endif // REQUEST_HPP + diff --git a/src/response.cpp b/src/response.cpp new file mode 100644 index 0000000..ffd3e05 --- /dev/null +++ b/src/response.cpp @@ -0,0 +1,17 @@ +/** + * author: brando + * date: 4/3/25 + */ + +#include "response.hpp" + +Response::Response() { +} + +Response::~Response() { +} + +Response * Response::fromRequest(const Request * request) { + return new Response; +} + diff --git a/src/response.hpp b/src/response.hpp new file mode 100644 index 0000000..87de806 --- /dev/null +++ b/src/response.hpp @@ -0,0 +1,25 @@ +/** + * author: brando + * date: 4/3/25 + */ + +#ifndef RESPONSE_HPP +#define RESPONSE_HPP + +#include +#include +#include "request.hpp" + +class Response : public BF::Object { +public: + static Response * fromRequest(const Request *); + virtual ~Response(); +private: + Response(); + +private: + BF::Data _message; +}; + +#endif // RESPONSE_HPP + From 794805bd0b0a15e73436c05ca5da544ccdcd7b1c Mon Sep 17 00:00:00 2001 From: Brando Date: Thu, 3 Apr 2025 15:26:56 -0700 Subject: [PATCH 11/39] init test bench --- makefile | 2 +- src/office.cpp | 2 ++ testbench/request_tests.hpp | 32 ++++++++++++++++++++++++++++++++ testbench/tests.cpp | 11 +++++++++++ 4 files changed, 46 insertions(+), 1 deletion(-) create mode 100644 testbench/request_tests.hpp create mode 100644 testbench/tests.cpp diff --git a/makefile b/makefile index 34fd328..4252203 100644 --- a/makefile +++ b/makefile @@ -62,7 +62,7 @@ FLAGS = $(CPPFLAGS) -Isrc/ $(CPPSTD) -Iexternal/bin/libs/release ### Debug settings else ifeq ($(CONFIG),debug) # debug MAIN_FILE = src/main.cpp -BIN_NAME = http +BIN_NAME = http-debug #ADDR_SANITIZER = -fsanitize=address FLAGS = $(CPPFLAGS) -DDEBUG -g -Isrc/ $(ADDR_SANITIZER) $(CPPSTD) -Iexternal/bin/libs/debug diff --git a/src/office.cpp b/src/office.cpp index eee214b..eedc72a 100644 --- a/src/office.cpp +++ b/src/office.cpp @@ -56,6 +56,8 @@ void __IncomingRequestsWorkerThread(void * in) { Request * req = new Request(envelope->data()); Response * resp = Response::fromRequest(req); + if (resp) { + } BFRelease(resp); BFRelease(req); diff --git a/testbench/request_tests.hpp b/testbench/request_tests.hpp new file mode 100644 index 0000000..d2325e4 --- /dev/null +++ b/testbench/request_tests.hpp @@ -0,0 +1,32 @@ +/** + * author: Brando + * date: 4/3/25 + */ + +#ifndef REQUEST_TESTS_HPP +#define REQUEST_TESTS_HPP + +#define ASSERT_PUBLIC_MEMBER_ACCESS + +#include +#include "request.hpp" + +extern "C" { +#include +#include +} + +using namespace BF; + +BFTEST_UNIT_FUNC(test_requestInit, 1, { + Data d; + Request * req = new Request(&d); + BFRelease(req); +}) + +BFTEST_COVERAGE_FUNC(request_tests, { + BFTEST_LAUNCH(test_requestInit); +}) + +#endif // REQUEST_TESTS_HPP + diff --git a/testbench/tests.cpp b/testbench/tests.cpp new file mode 100644 index 0000000..904572d --- /dev/null +++ b/testbench/tests.cpp @@ -0,0 +1,11 @@ +/** + * author: brando + * date: 4/3/25 + */ + +#include "request_tests.hpp" + +BFTEST_SUITE_FUNC({ + BFTEST_SUITE_LAUNCH(request_tests); +}) + From fc536cff21c3a74b2d2a186f9404afbad272cc46 Mon Sep 17 00:00:00 2001 From: Brando Date: Thu, 3 Apr 2025 15:30:23 -0700 Subject: [PATCH 12/39] saving work --- testbench/request_tests.hpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/testbench/request_tests.hpp b/testbench/request_tests.hpp index d2325e4..2ad13c4 100644 --- a/testbench/request_tests.hpp +++ b/testbench/request_tests.hpp @@ -24,8 +24,17 @@ BFTEST_UNIT_FUNC(test_requestInit, 1, { BFRelease(req); }) +BFTEST_UNIT_FUNC(test_simpleClientRequest, 1, { + String str = "Hello world"; + Data d(str); + Request * req = new Request(&d); + BFRelease(req); +}) + BFTEST_COVERAGE_FUNC(request_tests, { BFTEST_LAUNCH(test_requestInit); + BFTEST_LAUNCH(test_simpleClientRequest); + }) #endif // REQUEST_TESTS_HPP From 43b5607a275985fea9ea34eedbc846a7563fa87f Mon Sep 17 00:00:00 2001 From: Brando Date: Tue, 8 Apr 2025 15:23:40 -0700 Subject: [PATCH 13/39] can get method --- external/libs | 2 +- src/office.cpp | 1 + src/request.cpp | 33 +++++++++++++++++++++++++++++++-- src/request.hpp | 15 ++++++++++++++- src/response.cpp | 15 ++++++++++++++- src/response.hpp | 1 + testbench/request_tests.hpp | 24 ++++++++++++++++++++---- 7 files changed, 82 insertions(+), 9 deletions(-) diff --git a/external/libs b/external/libs index 3647633..d272600 160000 --- a/external/libs +++ b/external/libs @@ -1 +1 @@ -Subproject commit 3647633e910e4d20e655259647e598ea7dc8f156 +Subproject commit d272600d84d7d66c58d2d7876c1c1ab861969892 diff --git a/src/office.cpp b/src/office.cpp index eedc72a..7e13f26 100644 --- a/src/office.cpp +++ b/src/office.cpp @@ -57,6 +57,7 @@ void __IncomingRequestsWorkerThread(void * in) { Response * resp = Response::fromRequest(req); if (resp) { + envelope->connection()->queueData(resp->data()); } BFRelease(resp); diff --git a/src/request.cpp b/src/request.cpp index f9a22ff..ea3c68e 100644 --- a/src/request.cpp +++ b/src/request.cpp @@ -6,12 +6,41 @@ #include "request.hpp" #include +#include + using namespace BF; -Request::Request(const Data * data) { - this->_message.alloc(data->size(), (const unsigned char *) data->buffer()); +Request::Request(const Data * data) : _message(data == NULL ? 0 : (const char *) data->buffer(), data == NULL ? 0 : data->size()) { } Request::~Request() { } +RequestMethod Request::method() const { + std::regex methodRegex(R"((GET|POST|PUT|DELETE|HEAD|OPTIONS|CONNECT|TRACE|PATCH)\s+)"); + std::smatch match; + if (!std::regex_search(this->_message, match, methodRegex)) { + return kRequestMethodNone; + } + + std::string matchStr = match[1].str(); + if (matchStr == "GET") { + return kRequestMethodGet; + } else if (matchStr == "POST") { + return kRequestMethodPost; + } else { + return kRequestMethodNone; + } +} + +String Request::target() const { + return ""; +} +String Request::protocol() const { + return ""; +} + +String Request::host() const { + return ""; +} + diff --git a/src/request.hpp b/src/request.hpp index 3983857..8bd69ff 100644 --- a/src/request.hpp +++ b/src/request.hpp @@ -8,14 +8,27 @@ #include #include +#include + +typedef enum { + kRequestMethodNone = 0, + kRequestMethodGet, + kRequestMethodPost, +} RequestMethod; class Request : public BF::Object { public: Request(const BF::Data * data); virtual ~Request(); + RequestMethod method() const; + BF::String target() const; + BF::String protocol() const; + + BF::String host() const; + private: - BF::Data _message; + std::string _message; }; #endif // REQUEST_HPP diff --git a/src/response.cpp b/src/response.cpp index ffd3e05..c7bac37 100644 --- a/src/response.cpp +++ b/src/response.cpp @@ -4,6 +4,9 @@ */ #include "response.hpp" +#include + +using namespace BF; Response::Response() { } @@ -12,6 +15,16 @@ Response::~Response() { } Response * Response::fromRequest(const Request * request) { - return new Response; + String s = "HTTP/1.1 200 OK\n Content-Type: text/html\n Hello World"; + + Response * res = new Response; + if (!res) return NULL; + + res->_message.alloc(s.length(), (const unsigned char *) s.c_str()); + return res; +} + +const Data * Response::data() const { + return &this->_message; } diff --git a/src/response.hpp b/src/response.hpp index 87de806..1831d58 100644 --- a/src/response.hpp +++ b/src/response.hpp @@ -14,6 +14,7 @@ class Response : public BF::Object { public: static Response * fromRequest(const Request *); virtual ~Response(); + const BF::Data * data() const; private: Response(); diff --git a/testbench/request_tests.hpp b/testbench/request_tests.hpp index 2ad13c4..0750c84 100644 --- a/testbench/request_tests.hpp +++ b/testbench/request_tests.hpp @@ -24,10 +24,26 @@ BFTEST_UNIT_FUNC(test_requestInit, 1, { BFRelease(req); }) -BFTEST_UNIT_FUNC(test_simpleClientRequest, 1, { - String str = "Hello world"; - Data d(str); - Request * req = new Request(&d); +BFTEST_UNIT_FUNC(test_simpleClientRequest, 2 << 10, { + String get_str = "GET /index.html HTTP/1.1\r\nHost: example.com\r\n\r\n"; + Data get_buf(get_str); + String post_str = "POST /submit.php HTTP/1.1\r\nHost: another.com\r\nContent-Length: 10\r\n\r\ndata=value"; + Data post_buf(post_str); + String invalid_str = "Invalid Request Line"; + Data invalid_buf(invalid_str); + + Request * req = NULL; + + req = new Request(&get_buf); + BF_ASSERT(req->method() == kRequestMethodGet); + BFRelease(req); + + req = new Request(&post_buf); + BF_ASSERT(req->method() == kRequestMethodPost); + BFRelease(req); + + req = new Request(&invalid_buf); + BF_ASSERT(req->method() == kRequestMethodNone); BFRelease(req); }) From 4f27ffc029a813d41687b3a2a899f426bd5ade07 Mon Sep 17 00:00:00 2001 From: Brando Date: Tue, 8 Apr 2025 16:16:41 -0700 Subject: [PATCH 14/39] can parse request with regex --- external/libs | 2 +- src/request.cpp | 39 +++++++++++++++++++++++-------------- src/request.hpp | 2 +- testbench/request_tests.hpp | 22 +++++++++++++++++---- 4 files changed, 44 insertions(+), 21 deletions(-) diff --git a/external/libs b/external/libs index d272600..dafd24d 160000 --- a/external/libs +++ b/external/libs @@ -1 +1 @@ -Subproject commit d272600d84d7d66c58d2d7876c1c1ab861969892 +Subproject commit dafd24d87d5f147a4f1d7d876520ec7adfb0d1ff diff --git a/src/request.cpp b/src/request.cpp index ea3c68e..3a3b610 100644 --- a/src/request.cpp +++ b/src/request.cpp @@ -16,28 +16,37 @@ Request::Request(const Data * data) : _message(data == NULL ? 0 : (const char *) Request::~Request() { } -RequestMethod Request::method() const { +String Request::method() const { std::regex methodRegex(R"((GET|POST|PUT|DELETE|HEAD|OPTIONS|CONNECT|TRACE|PATCH)\s+)"); std::smatch match; - if (!std::regex_search(this->_message, match, methodRegex)) { - return kRequestMethodNone; - } - - std::string matchStr = match[1].str(); - if (matchStr == "GET") { - return kRequestMethodGet; - } else if (matchStr == "POST") { - return kRequestMethodPost; - } else { - return kRequestMethodNone; - } + + if (std::regex_search(this->_message, match, methodRegex)) { + return match[1].str(); // The second capturing group contains the target + } else { + return ""; // Or throw an exception if no target is found + } } String Request::target() const { - return ""; + std::regex targetRegex(R"((?:GET|POST|PUT|DELETE|HEAD|OPTIONS|CONNECT|TRACE|PATCH)\s+([^\s]+)\s+HTTP/\d\.\d)"); + std::smatch match; + + if (std::regex_search(this->_message, match, targetRegex)) { + return match[1].str(); // The second capturing group contains the target + } else { + return ""; // Or throw an exception if no target is found + } } + String Request::protocol() const { - return ""; + std::regex protocolRegex(R"((?:GET|POST|PUT|DELETE|HEAD|OPTIONS|CONNECT|TRACE|PATCH)\s+[^\s]+\s+(HTTP/\d\.\d))"); + std::smatch match; + + if (std::regex_search(this->_message, match, protocolRegex)) { + return match[1].str(); // The second capturing group contains the protocol + } else { + return ""; // Or throw an exception if no protocol is found + } } String Request::host() const { diff --git a/src/request.hpp b/src/request.hpp index 8bd69ff..9128e46 100644 --- a/src/request.hpp +++ b/src/request.hpp @@ -21,7 +21,7 @@ class Request : public BF::Object { Request(const BF::Data * data); virtual ~Request(); - RequestMethod method() const; + BF::String method() const; BF::String target() const; BF::String protocol() const; diff --git a/testbench/request_tests.hpp b/testbench/request_tests.hpp index 0750c84..099a863 100644 --- a/testbench/request_tests.hpp +++ b/testbench/request_tests.hpp @@ -24,26 +24,40 @@ BFTEST_UNIT_FUNC(test_requestInit, 1, { BFRelease(req); }) -BFTEST_UNIT_FUNC(test_simpleClientRequest, 2 << 10, { +BFTEST_UNIT_FUNC(test_simpleClientRequest, 2 << 8, { String get_str = "GET /index.html HTTP/1.1\r\nHost: example.com\r\n\r\n"; Data get_buf(get_str); String post_str = "POST /submit.php HTTP/1.1\r\nHost: another.com\r\nContent-Length: 10\r\n\r\ndata=value"; Data post_buf(post_str); + String head_str = "HEAD /static/image.png HTTP/1.0\r\n\r\n"; + Data head_buf(head_str); String invalid_str = "Invalid Request Line"; Data invalid_buf(invalid_str); Request * req = NULL; req = new Request(&get_buf); - BF_ASSERT(req->method() == kRequestMethodGet); + BF_ASSERT(req->method() == "GET"); + BF_ASSERT(req->target() == "/index.html"); + BF_ASSERT(req->protocol() == "HTTP/1.1"); BFRelease(req); req = new Request(&post_buf); - BF_ASSERT(req->method() == kRequestMethodPost); + BF_ASSERT(req->method() == "POST"); + BF_ASSERT(req->target() == "/submit.php"); + BF_ASSERT(req->protocol() == "HTTP/1.1"); + BFRelease(req); + + req = new Request(&head_buf); + BF_ASSERT(req->method() == "HEAD"); + BF_ASSERT(req->target() == "/static/image.png"); + BF_ASSERT(req->protocol() == "HTTP/1.0"); BFRelease(req); req = new Request(&invalid_buf); - BF_ASSERT(req->method() == kRequestMethodNone); + BF_ASSERT(req->method() == ""); + BF_ASSERT(req->target().empty()); + BF_ASSERT(req->protocol().empty()); BFRelease(req); }) From abebf6bbb9ca5e4562cf6b9bab8de3b3d143f61f Mon Sep 17 00:00:00 2001 From: Brando Date: Wed, 9 Apr 2025 14:16:47 -0700 Subject: [PATCH 15/39] introduction resource and log --- makefile | 2 +- src/log.cpp | 53 +++++++++++++++++++++++++++++++++++ src/log.hpp | 72 ++++++++++++++++++++++++++++++++++++++++++++++++ src/main.cpp | 49 ++++++++++++++++++++++++++++++-- src/office.cpp | 6 +--- src/resource.cpp | 23 ++++++++++++++++ src/resource.hpp | 19 +++++++++++++ src/response.cpp | 12 ++++++-- src/response.hpp | 2 +- todo.md | 3 +- 10 files changed, 228 insertions(+), 13 deletions(-) create mode 100644 src/log.cpp create mode 100644 src/log.hpp create mode 100644 src/resource.cpp create mode 100644 src/resource.hpp diff --git a/makefile b/makefile index 4252203..5d4a931 100644 --- a/makefile +++ b/makefile @@ -37,7 +37,7 @@ BIN_PATH = bin/$(CONFIG) BUILD_TYPE = executable SOURCE_EXT = cpp HEADER_EXT = hpp -FILES = office request response +FILES = office request response resource log ifeq ($(CONFIG),release) # release LIBRARIES = \ diff --git a/src/log.cpp b/src/log.cpp new file mode 100644 index 0000000..8ab7b18 --- /dev/null +++ b/src/log.cpp @@ -0,0 +1,53 @@ +/** + * author: brando + * date: 4/9/25 + */ + +#include "log.hpp" +#include +#include +#include +#include + +extern "C" { +#include +} + +void _LogWriteEntry(BFFileWriter * filewriter, int mode, ...) { +#ifndef TESTING + if (!filewriter) return; + + va_list arg0, arg1; + va_start(arg0, mode); + va_start(arg1, mode); + + const char * format = va_arg(arg0, const char *); + if (!format) return; + + char * logstr = BFStringCreateFormatArgListString(format, arg0); + if (!logstr) return; + + BFDateTime dt = {0}; + if (BFTimeGetCurrentDateTime(&dt)) return; + + format = "[%02d/%02d/%04d, %02d:%02d:%02d] - %s"; + + BFFileWriterQueueFormatLine( + filewriter, + format, + dt.month, + dt.day, + dt.year, + dt.hour, + dt.minute, + dt.second, + logstr + ); + + va_end(arg0); + va_end(arg1); + + BFFree(logstr); +#endif +} + diff --git a/src/log.hpp b/src/log.hpp new file mode 100644 index 0000000..cb8519c --- /dev/null +++ b/src/log.hpp @@ -0,0 +1,72 @@ +/** + * author: brando + * date: 4/9/25 + */ + +#ifndef LOG_HPP +#define LOG_HPP + +extern "C" { +#include +} + +#define CHAT_LOG_PATH "/tmp/http.log" + +extern BFFileWriter gFileWriter; + +/** + * must define in a source file + */ +#define LOG_INIT \ +BFFileWriter gFileWriter = 0; \ +void __LogCallbackBFNet(const char * buf) { \ + LOG_DEBUG("bfnet: %s", buf); \ + LOG_FLUSH; \ +} + +/** + * initializes logs for: + * - http + * - bfnet + */ +#define LOG_OPEN \ +BFFileWriterCreate(&gFileWriter, CHAT_LOG_PATH); \ +BF::Net::Log::SetCallback(__LogCallbackBFNet); + +/** + * `mode`: 'd' for debug, 'e' for error, or 0 for normal + */ +void _LogWriteEntry(BFFileWriter * filewriter, int mode, ...); + +/** + * LOG_WRITE vs LOG_DEBUG vs LOG_ERROR + * + * - each writes a line into the same log file + * - each log entry will explicitly tell you what type of log entry it is + */ + +/** + * writes ent (line) to log file + */ +#define LOG_WRITE(...) _LogWriteEntry(&gFileWriter, 0, __VA_ARGS__) + +#define LOG_ERROR(...) _LogWriteEntry(&gFileWriter, 'e', __VA_ARGS__) + +#ifdef DEBUG +#define LOG_DEBUG(...) _LogWriteEntry(&gFileWriter, 'd', __VA_ARGS__) +#else // DEBUG +#define LOG_DEBUG(...) +#endif // DEBUG + +/** + * flushes write buffers + */ +#define LOG_FLUSH BFFileWriterFlush(&gFileWriter) + +/** + * closes log file + */ +#define LOG_CLOSE BFFileWriterClose(&gFileWriter) + +#endif // LOG_HPP + diff --git a/src/main.cpp b/src/main.cpp index c7e89ea..3985a1c 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -4,6 +4,8 @@ */ #include "office.hpp" +#include "log.hpp" +#include "resource.hpp" #include #include #include @@ -13,19 +15,58 @@ extern "C" { #include } +#define ARGUMENT_ROOT "-root" + using namespace BF::Net; using namespace BF; using namespace std; -void __LogCallbackBFNet(const char * buf) { \ - cout << "bfnet: " << buf << endl; +LOG_INIT; + +void help(const char * toolname) { + printf("usage: %s %s \n", toolname, ARGUMENT_ROOT); + printf("\n"); + printf("Arguments:\n"); + printf(" %s \tThis is the root folder where we will look for resources\n", ARGUMENT_ROOT); + printf("\nCopyright © 2025 Brando. All rights reserved.\n"); } void __NewConnection(Connection * sc) { cout << "new connection made" << endl; } -int main() { +void __PrintError(const char * format, ...) { + va_list args; + va_start(args, format); + printf("error: "); + vprintf(format, args); + va_end(args); +} + +int __ReadArguments(int argc, char * argv[]) { + if (argc == 1) { + help(argv[0]); + return -1; + } + + for (int i = 0; i < argc; i++) { + if (!strcmp(argv[i], ARGUMENT_ROOT)) { + if (!Resource::setRootFolder(argv[++i])) { + __PrintError("'%s' is not accepted as a root folder\n", argv[i]); + } + } + } + + return 0; +} + +int main(int argc, char * argv[]) { + LOG_OPEN; + + if (__ReadArguments(argc, argv)) { + return -1; + } + int error = 0; Log::SetCallback(__LogCallbackBFNet); @@ -47,6 +88,8 @@ int main() { BFRelease(skt); Office::stop(); + LOG_CLOSE; + return error; } diff --git a/src/office.cpp b/src/office.cpp index 7e13f26..7e6b6a8 100644 --- a/src/office.cpp +++ b/src/office.cpp @@ -35,10 +35,6 @@ void Office::envelopeReceive(Envelope * envelope) { BFLockRelease(&_queueSema); } -void __IncomingRequestHandle(Request * request) { - -} - void __IncomingRequestsWorkerThread(void * in) { while (!BFThreadAsyncIsCanceled(_tidRequestQueue)) { if (_incomingRequests.get().empty()) { @@ -57,7 +53,7 @@ void __IncomingRequestsWorkerThread(void * in) { Response * resp = Response::fromRequest(req); if (resp) { - envelope->connection()->queueData(resp->data()); + //envelope->connection()->queueData(resp->data()); } BFRelease(resp); diff --git a/src/resource.cpp b/src/resource.cpp new file mode 100644 index 0000000..ede6e9f --- /dev/null +++ b/src/resource.cpp @@ -0,0 +1,23 @@ +/** + * author: brando + * date: 4/9/25 + */ + +#include "resource.hpp" +#include + +using namespace BF; + +String _rootFolder; + +bool Resource::setRootFolder(const BF::String & rootFolder) { + _rootFolder = rootFolder; + return true; +} + +Data * Resource::copyContentForTarget(const String & target) { + Data * res = NULL; + + return res; +} + diff --git a/src/resource.hpp b/src/resource.hpp new file mode 100644 index 0000000..926859a --- /dev/null +++ b/src/resource.hpp @@ -0,0 +1,19 @@ +/** + * author: brando + * date: 4/9/25 + * + * handles resource requests from GET + */ + +#ifndef RESOURCE_HPP +#define RESOURCE_HPP + +#include + +namespace Resource { + BF::Data * copyContentForTarget(const BF::String & target); + bool setRootFolder(const BF::String & rootFolder); +} + +#endif // RESOURCE_HPP + diff --git a/src/response.cpp b/src/response.cpp index c7bac37..d747729 100644 --- a/src/response.cpp +++ b/src/response.cpp @@ -4,6 +4,7 @@ */ #include "response.hpp" +#include "resource.hpp" #include using namespace BF; @@ -12,19 +13,26 @@ Response::Response() { } Response::~Response() { + BFRelease(this->_body); } Response * Response::fromRequest(const Request * request) { + if (!request) return NULL; + String s = "HTTP/1.1 200 OK\n Content-Type: text/html\n Hello World"; Response * res = new Response; if (!res) return NULL; - res->_message.alloc(s.length(), (const unsigned char *) s.c_str()); + if (request->method() == "GET") { + String target = request->target(); + res->_body = Resource::copyContentForTarget(target); + } + return res; } const Data * Response::data() const { - return &this->_message; + return NULL; } diff --git a/src/response.hpp b/src/response.hpp index 1831d58..9a74618 100644 --- a/src/response.hpp +++ b/src/response.hpp @@ -19,7 +19,7 @@ class Response : public BF::Object { Response(); private: - BF::Data _message; + BF::Data * _body; }; #endif // RESPONSE_HPP diff --git a/todo.md b/todo.md index 792f63c..9613aab 100644 --- a/todo.md +++ b/todo.md @@ -1,3 +1,4 @@ **0.1** - [ ] serve html - - [ ] receive http requests from client (be sure to assemble the packets) + - [x] receive http requests from client (be sure to assemble the packets) + - [ ] Handle GET requests for resources From 67c1bc8621f836984cbf364d40b06ba7feffd4d4 Mon Sep 17 00:00:00 2001 From: Brando Date: Thu, 10 Apr 2025 10:22:49 -0700 Subject: [PATCH 16/39] Adding example root folder --- example/index.html | 12 ++++++++++++ external/libs | 2 +- 2 files changed, 13 insertions(+), 1 deletion(-) create mode 100644 example/index.html diff --git a/example/index.html b/example/index.html new file mode 100644 index 0000000..00e253b --- /dev/null +++ b/example/index.html @@ -0,0 +1,12 @@ + + + +Page Title + + + +

This is a Heading

+

This is a paragraph.

+ + + diff --git a/external/libs b/external/libs index dafd24d..8cd344c 160000 --- a/external/libs +++ b/external/libs @@ -1 +1 @@ -Subproject commit dafd24d87d5f147a4f1d7d876520ec7adfb0d1ff +Subproject commit 8cd344c734fbb1cf60787669ccf666ff72f37e68 From b430a79027f89cdf82d3797f019a81c32b84d0a4 Mon Sep 17 00:00:00 2001 From: Brando Date: Thu, 10 Apr 2025 14:15:26 -0700 Subject: [PATCH 17/39] separating by method --- external/libs | 2 +- src/resource.cpp | 28 +++++++++++++++++++++++++--- src/resource.hpp | 1 + src/response.cpp | 26 ++++++++++++++++++++------ src/response.hpp | 8 +++++++- 5 files changed, 54 insertions(+), 11 deletions(-) diff --git a/external/libs b/external/libs index 8cd344c..73796ea 160000 --- a/external/libs +++ b/external/libs @@ -1 +1 @@ -Subproject commit 8cd344c734fbb1cf60787669ccf666ff72f37e68 +Subproject commit 73796ead3f265ab5541b8f509ee6c974ec1b46b8 diff --git a/src/resource.cpp b/src/resource.cpp index ede6e9f..27d278f 100644 --- a/src/resource.cpp +++ b/src/resource.cpp @@ -6,18 +6,40 @@ #include "resource.hpp" #include +extern "C" { +#include +} + +#ifdef LINUX +#include +#endif +#include + using namespace BF; String _rootFolder; -bool Resource::setRootFolder(const BF::String & rootFolder) { +const BF::String & Resource::getRootFolder() { + return _rootFolder; +} + +bool Resource::setRootFolder(const String & rootFolder) { + URL url(rootFolder); + if (!BFFileSystemPathExists(url.abspath())) { + return false; + } _rootFolder = rootFolder; return true; } Data * Resource::copyContentForTarget(const String & target) { - Data * res = NULL; + URL url(_rootFolder); + url.append(target); + + if (!BFFileSystemPathExists(url.abspath())) { + return NULL; + } - return res; + return Data::fromFile(url); } diff --git a/src/resource.hpp b/src/resource.hpp index 926859a..9249a8b 100644 --- a/src/resource.hpp +++ b/src/resource.hpp @@ -13,6 +13,7 @@ namespace Resource { BF::Data * copyContentForTarget(const BF::String & target); bool setRootFolder(const BF::String & rootFolder); + const BF::String & getRootFolder(); } #endif // RESOURCE_HPP diff --git a/src/response.cpp b/src/response.cpp index d747729..0700972 100644 --- a/src/response.cpp +++ b/src/response.cpp @@ -7,10 +7,13 @@ #include "resource.hpp" #include +extern "C" { +#include +} + using namespace BF; -Response::Response() { -} +Response::Response() { } Response::~Response() { BFRelease(this->_body); @@ -19,19 +22,30 @@ Response::~Response() { Response * Response::fromRequest(const Request * request) { if (!request) return NULL; - String s = "HTTP/1.1 200 OK\n Content-Type: text/html\n Hello World"; - Response * res = new Response; if (!res) return NULL; + res->_statusCode = 200; if (request->method() == "GET") { - String target = request->target(); - res->_body = Resource::copyContentForTarget(target); + Response::handleRequestGET(request, res); } return res; } +void Response::handleRequestGET(const Request * request, Response * response) { + if (!request || !response) return; + + String target = request->target(); + URL url(Resource::getRootFolder()); + url.append(target); + if (BFFileSystemPathIsFile(url.abspath())) { + response->_body = Resource::copyContentForTarget(request->target()); + } else { + response->_statusCode = 404; + } +} + const Data * Response::data() const { return NULL; } diff --git a/src/response.hpp b/src/response.hpp index 9a74618..3af1e93 100644 --- a/src/response.hpp +++ b/src/response.hpp @@ -14,12 +14,18 @@ class Response : public BF::Object { public: static Response * fromRequest(const Request *); virtual ~Response(); + + /** + * the http response in raw text we will send back + */ const BF::Data * data() const; private: Response(); + + static void handleRequestGET(const Request * request, Response * response); -private: BF::Data * _body; + int _statusCode = 0; }; #endif // RESPONSE_HPP From 4b44cabf7172840f6d6e7e31e9b4c884e205bb4e Mon Sep 17 00:00:00 2001 From: Brando Date: Fri, 11 Apr 2025 09:08:22 -0700 Subject: [PATCH 18/39] structuring out --- external/libs | 2 +- src/response.cpp | 10 +++++++++- src/response.hpp | 5 ++++- 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/external/libs b/external/libs index 73796ea..696ac9a 160000 --- a/external/libs +++ b/external/libs @@ -1 +1 @@ -Subproject commit 73796ead3f265ab5541b8f509ee6c974ec1b46b8 +Subproject commit 696ac9acc026435b5a0e929f0de547b7bddef4d4 diff --git a/src/response.cpp b/src/response.cpp index 0700972..3493f66 100644 --- a/src/response.cpp +++ b/src/response.cpp @@ -46,7 +46,15 @@ void Response::handleRequestGET(const Request * request, Response * response) { } } -const Data * Response::data() const { +const Data * Response::createData() const { + String content; + this->writeStatusLine(content); + if (this->_statusCode == 404) { + } return NULL; } +void Response::writeStatusLine(String & content) const { + +} + diff --git a/src/response.hpp b/src/response.hpp index 3af1e93..1ea9b36 100644 --- a/src/response.hpp +++ b/src/response.hpp @@ -17,12 +17,15 @@ class Response : public BF::Object { /** * the http response in raw text we will send back + * + * caller owns data */ - const BF::Data * data() const; + const BF::Data * createData() const; private: Response(); static void handleRequestGET(const Request * request, Response * response); + void writeStatusLine(BF::String & content) const; BF::Data * _body; int _statusCode = 0; From c6eb2568d7743fec897057381796901b6495be29 Mon Sep 17 00:00:00 2001 From: Brando Date: Fri, 11 Apr 2025 09:57:15 -0700 Subject: [PATCH 19/39] can create http response --- src/response.cpp | 49 ++++++++++++++++++++++++++++++++++++++++++++---- src/response.hpp | 5 ++++- 2 files changed, 49 insertions(+), 5 deletions(-) diff --git a/src/response.cpp b/src/response.cpp index 3493f66..d385511 100644 --- a/src/response.cpp +++ b/src/response.cpp @@ -11,12 +11,14 @@ extern "C" { #include } +#define HTTP_DATE_BUFSIZE 128 + using namespace BF; Response::Response() { } Response::~Response() { - BFRelease(this->_body); + BFRelease(this->_content); } Response * Response::fromRequest(const Request * request) { @@ -40,21 +42,60 @@ void Response::handleRequestGET(const Request * request, Response * response) { URL url(Resource::getRootFolder()); url.append(target); if (BFFileSystemPathIsFile(url.abspath())) { - response->_body = Resource::copyContentForTarget(request->target()); + response->_content = Resource::copyContentForTarget(request->target()); + response->_contentType = "text/html; charset=utf-8"; } else { response->_statusCode = 404; + response->_content = new Data("404 Not Found

404 Not Found

Sorry, the page you are looking for does not exist.

"); + response->_contentType = "text/html; charset=utf-8"; } } const Data * Response::createData() const { String content; this->writeStatusLine(content); - if (this->_statusCode == 404) { - } + this->writeHeader(content); + return NULL; } void Response::writeStatusLine(String & content) const { + if (this->_statusCode == 404) { + content.append("HTTP/1.1 %d Not Found\n", this->_statusCode); + } else { + content.append("HTTP/1.1 %d Ok\n", this->_statusCode); + } +} + +void __ResponseGenerateDateString(char * buf) { + if (!buf) return; + + time_t now = time(NULL); + if (now == (time_t)(-1)) { + return; + } + + struct tm timeinfo_gmt; + if (gmtime_r(&now, &timeinfo_gmt) == NULL) { + return; + } + + strftime( + buf, + HTTP_DATE_BUFSIZE, + "%a, %d %b %Y %H:%M:%S GMT", + &timeinfo_gmt); +} + +void Response::writeHeader(String & content) const { + content.append("Server: brando's http server\n"); + + char buf[HTTP_DATE_BUFSIZE]; + __ResponseGenerateDateString(buf); + content.append("Date: %s", buf); + + content.append("Content-Length: %d\n", this->_content ? this->_content->size() : 0); + content.append("Content-Type: %s\n", this->_contentType.c_str()); } diff --git a/src/response.hpp b/src/response.hpp index 1ea9b36..688ca81 100644 --- a/src/response.hpp +++ b/src/response.hpp @@ -8,6 +8,7 @@ #include #include +#include #include "request.hpp" class Response : public BF::Object { @@ -26,8 +27,10 @@ class Response : public BF::Object { static void handleRequestGET(const Request * request, Response * response); void writeStatusLine(BF::String & content) const; + void writeHeader(BF::String & content) const; - BF::Data * _body; + BF::Data * _content; + BF::String _contentType; int _statusCode = 0; }; From 079d36f7608f3aaebd45b0b1c38501608c3bd9ad Mon Sep 17 00:00:00 2001 From: Brando Date: Sat, 12 Apr 2025 22:44:10 -0700 Subject: [PATCH 20/39] trying to connect --- external/libs | 2 +- src/log.cpp | 12 ++++++++++++ src/log.hpp | 2 +- src/main.cpp | 12 ++---------- src/office.cpp | 13 +++++++++---- src/response.cpp | 24 +++++++++++++++++++++++- 6 files changed, 48 insertions(+), 17 deletions(-) diff --git a/external/libs b/external/libs index 696ac9a..4ed09e1 160000 --- a/external/libs +++ b/external/libs @@ -1 +1 @@ -Subproject commit 696ac9acc026435b5a0e929f0de547b7bddef4d4 +Subproject commit 4ed09e19d5ddcab42d331fe4676e4694f0c0deba diff --git a/src/log.cpp b/src/log.cpp index 8ab7b18..b7c985a 100644 --- a/src/log.cpp +++ b/src/log.cpp @@ -44,6 +44,18 @@ void _LogWriteEntry(BFFileWriter * filewriter, int mode, ...) { logstr ); + printf( + format, + dt.month, + dt.day, + dt.year, + dt.hour, + dt.minute, + dt.second, + logstr + ); + printf("\n"); + va_end(arg0); va_end(arg1); diff --git a/src/log.hpp b/src/log.hpp index cb8519c..54a327a 100644 --- a/src/log.hpp +++ b/src/log.hpp @@ -20,7 +20,7 @@ extern BFFileWriter gFileWriter; #define LOG_INIT \ BFFileWriter gFileWriter = 0; \ void __LogCallbackBFNet(const char * buf) { \ - LOG_DEBUG("bfnet: %s", buf); \ + LOG_DEBUG("bfnet: %s\n", buf); \ LOG_FLUSH; \ } diff --git a/src/main.cpp b/src/main.cpp index 3985a1c..3b570fc 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -32,15 +32,7 @@ void help(const char * toolname) { } void __NewConnection(Connection * sc) { - cout << "new connection made" << endl; -} - -void __PrintError(const char * format, ...) { - va_list args; - va_start(args, format); - printf("error: "); - vprintf(format, args); - va_end(args); + LOG_WRITE("new connection made"); } int __ReadArguments(int argc, char * argv[]) { @@ -52,7 +44,7 @@ int __ReadArguments(int argc, char * argv[]) { for (int i = 0; i < argc; i++) { if (!strcmp(argv[i], ARGUMENT_ROOT)) { if (!Resource::setRootFolder(argv[++i])) { - __PrintError("'%s' is not accepted as a root folder\n", argv[i]); + LOG_ERROR("'%s' is not accepted as a root folder", argv[i]); } } } diff --git a/src/office.cpp b/src/office.cpp index 7e6b6a8..00eab00 100644 --- a/src/office.cpp +++ b/src/office.cpp @@ -6,6 +6,7 @@ #include "office.hpp" #include "request.hpp" #include "response.hpp" +#include "log.hpp" #include #include #include @@ -47,20 +48,23 @@ void __IncomingRequestsWorkerThread(void * in) { // pop off _incomingRequests.unsafeget().pop(); + + _incomingRequests.unlock(); - cout << "envelope: " << (const char *) envelope->data()->buffer() << endl; + LOG_WRITE("envelope: %s", (const char *) envelope->data()->buffer()); Request * req = new Request(envelope->data()); Response * resp = Response::fromRequest(req); if (resp) { - //envelope->connection()->queueData(resp->data()); + const Data * respData = resp->createData(); + envelope->connection()->queueData(respData); + + BFRelease(respData); } BFRelease(resp); BFRelease(req); BFRelease(envelope); - - _incomingRequests.unlock(); } } } @@ -72,6 +76,7 @@ void Office::start() { void Office::stop() { BFThreadAsyncCancel(_tidRequestQueue); + BFLockRelease(&_queueSema); BFThreadAsyncWait(_tidRequestQueue); BFThreadAsyncDestroy(_tidRequestQueue); diff --git a/src/response.cpp b/src/response.cpp index d385511..fa53ed9 100644 --- a/src/response.cpp +++ b/src/response.cpp @@ -5,6 +5,7 @@ #include "response.hpp" #include "resource.hpp" +#include "log.hpp" #include extern "C" { @@ -22,29 +23,44 @@ Response::~Response() { } Response * Response::fromRequest(const Request * request) { + LOG_DEBUG("%s:%d", __func__, __LINE__); if (!request) return NULL; + LOG_DEBUG("%s:%d", __func__, __LINE__); Response * res = new Response; if (!res) return NULL; res->_statusCode = 200; if (request->method() == "GET") { + LOG_DEBUG("%s:%d", __func__, __LINE__); Response::handleRequestGET(request, res); } + LOG_DEBUG("%s:%d", __func__, __LINE__); return res; } void Response::handleRequestGET(const Request * request, Response * response) { + LOG_DEBUG("%s:%d", __func__, __LINE__); if (!request || !response) return; + LOG_DEBUG("%s:%d", __func__, __LINE__); String target = request->target(); URL url(Resource::getRootFolder()); url.append(target); + + LOG_DEBUG("%s:%d", __func__, __LINE__); + if (BFFileSystemPathIsDirectory(url.abspath())) { + url.append("index.html"); + } + + LOG_DEBUG("%s:%d", __func__, __LINE__); if (BFFileSystemPathIsFile(url.abspath())) { + LOG_DEBUG("%s:%d", __func__, __LINE__); response->_content = Resource::copyContentForTarget(request->target()); response->_contentType = "text/html; charset=utf-8"; } else { + LOG_DEBUG("%s:%d", __func__, __LINE__); response->_statusCode = 404; response->_content = new Data("404 Not Found

404 Not Found

Sorry, the page you are looking for does not exist.

"); response->_contentType = "text/html; charset=utf-8"; @@ -56,7 +72,13 @@ const Data * Response::createData() const { this->writeStatusLine(content); this->writeHeader(content); - return NULL; + content.push_back('\n'); + + if (this->_content) { + content.append(*this->_content); + } + + return new Data(content); } void Response::writeStatusLine(String & content) const { From 73edab802a000a08ab7c56845d2ded8f55923db0 Mon Sep 17 00:00:00 2001 From: Brando Date: Mon, 14 Apr 2025 14:59:11 -0700 Subject: [PATCH 21/39] can send 404 responses --- src/response.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/response.cpp b/src/response.cpp index fa53ed9..1ca0492 100644 --- a/src/response.cpp +++ b/src/response.cpp @@ -62,8 +62,8 @@ void Response::handleRequestGET(const Request * request, Response * response) { } else { LOG_DEBUG("%s:%d", __func__, __LINE__); response->_statusCode = 404; - response->_content = new Data("404 Not Found

404 Not Found

Sorry, the page you are looking for does not exist.

"); - response->_contentType = "text/html; charset=utf-8"; + response->_content = new Data("404 Not Found"); + response->_contentType = "text/plain"; } } @@ -72,7 +72,7 @@ const Data * Response::createData() const { this->writeStatusLine(content); this->writeHeader(content); - content.push_back('\n'); + content.append("\r\n"); if (this->_content) { content.append(*this->_content); @@ -83,9 +83,9 @@ const Data * Response::createData() const { void Response::writeStatusLine(String & content) const { if (this->_statusCode == 404) { - content.append("HTTP/1.1 %d Not Found\n", this->_statusCode); + content.append("HTTP/1.1 %d Not Found\r\n", this->_statusCode); } else { - content.append("HTTP/1.1 %d Ok\n", this->_statusCode); + content.append("HTTP/1.1 %d Ok\r\n", this->_statusCode); } } @@ -110,14 +110,14 @@ void __ResponseGenerateDateString(char * buf) { } void Response::writeHeader(String & content) const { - content.append("Server: brando's http server\n"); + content.append("Server: brando's http server\r\n"); char buf[HTTP_DATE_BUFSIZE]; __ResponseGenerateDateString(buf); - content.append("Date: %s", buf); + content.append("Date: %s\r\n", buf); - content.append("Content-Length: %d\n", this->_content ? this->_content->size() : 0); + content.append("Content-Length: %d\r\n", this->_content ? this->_content->size() : 0); - content.append("Content-Type: %s\n", this->_contentType.c_str()); + content.append("Content-Type: %s\r\n", this->_contentType.c_str()); } From f66b1fb49270fef2d27e65b1fcf0bb20368cbefc Mon Sep 17 00:00:00 2001 From: Brando Date: Mon, 14 Apr 2025 15:08:16 -0700 Subject: [PATCH 22/39] can get content from server just ONCE --- src/resource.cpp | 8 ++++++-- src/resource.hpp | 2 +- src/response.cpp | 9 ++++++--- 3 files changed, 13 insertions(+), 6 deletions(-) diff --git a/src/resource.cpp b/src/resource.cpp index 27d278f..8642941 100644 --- a/src/resource.cpp +++ b/src/resource.cpp @@ -4,6 +4,7 @@ */ #include "resource.hpp" +#include "log.hpp" #include extern "C" { @@ -32,11 +33,14 @@ bool Resource::setRootFolder(const String & rootFolder) { return true; } -Data * Resource::copyContentForTarget(const String & target) { +Data * Resource::copyContentForFile(const String & file) { URL url(_rootFolder); - url.append(target); + + LOG_DEBUG("%s:%d - url-> '%s'", __func__, __LINE__, url.abspath()); + if (!BFFileSystemPathExists(url.abspath())) { + LOG_DEBUG("%s:%d - url above does not exist", __func__, __LINE__); return NULL; } diff --git a/src/resource.hpp b/src/resource.hpp index 9249a8b..5c3fb1d 100644 --- a/src/resource.hpp +++ b/src/resource.hpp @@ -11,7 +11,7 @@ #include namespace Resource { - BF::Data * copyContentForTarget(const BF::String & target); + BF::Data * copyContentForFile(const BF::String & target); bool setRootFolder(const BF::String & rootFolder); const BF::String & getRootFolder(); } diff --git a/src/response.cpp b/src/response.cpp index 1ca0492..df22ecf 100644 --- a/src/response.cpp +++ b/src/response.cpp @@ -57,8 +57,9 @@ void Response::handleRequestGET(const Request * request, Response * response) { LOG_DEBUG("%s:%d", __func__, __LINE__); if (BFFileSystemPathIsFile(url.abspath())) { LOG_DEBUG("%s:%d", __func__, __LINE__); - response->_content = Resource::copyContentForTarget(request->target()); - response->_contentType = "text/html; charset=utf-8"; + //response->_content = Resource::copyContentForFile(request->target()); + response->_content = Data::fromFile(url); + response->_contentType = "text/html"; } else { LOG_DEBUG("%s:%d", __func__, __LINE__); response->_statusCode = 404; @@ -74,7 +75,9 @@ const Data * Response::createData() const { content.append("\r\n"); - if (this->_content) { + if (!this->_content) { + LOG_DEBUG("%s:%d - null content", __func__, __LINE__); + } else { content.append(*this->_content); } From b8114b7a9665a8ce7143125fe0cdd2c8a89e33b5 Mon Sep 17 00:00:00 2001 From: Brando Date: Mon, 14 Apr 2025 15:08:39 -0700 Subject: [PATCH 23/39] saving work --- external/libs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/external/libs b/external/libs index 4ed09e1..c4c8ea7 160000 --- a/external/libs +++ b/external/libs @@ -1 +1 @@ -Subproject commit 4ed09e19d5ddcab42d331fe4676e4694f0c0deba +Subproject commit c4c8ea7807ea2b1d35c6fd8b05ee0e740c188915 From c0469d7bfe137ee638693dec5eccf91c793726ba Mon Sep 17 00:00:00 2001 From: Brando Date: Mon, 14 Apr 2025 16:57:19 -0700 Subject: [PATCH 24/39] can take multiple requests --- src/log.cpp | 1 + src/log.hpp | 2 +- src/main.cpp | 2 ++ src/office.cpp | 6 +++++- 4 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/log.cpp b/src/log.cpp index b7c985a..1a3a4de 100644 --- a/src/log.cpp +++ b/src/log.cpp @@ -55,6 +55,7 @@ void _LogWriteEntry(BFFileWriter * filewriter, int mode, ...) { logstr ); printf("\n"); + fflush(stdout); va_end(arg0); va_end(arg1); diff --git a/src/log.hpp b/src/log.hpp index 54a327a..cb8519c 100644 --- a/src/log.hpp +++ b/src/log.hpp @@ -20,7 +20,7 @@ extern BFFileWriter gFileWriter; #define LOG_INIT \ BFFileWriter gFileWriter = 0; \ void __LogCallbackBFNet(const char * buf) { \ - LOG_DEBUG("bfnet: %s\n", buf); \ + LOG_DEBUG("bfnet: %s", buf); \ LOG_FLUSH; \ } diff --git a/src/main.cpp b/src/main.cpp index 3b570fc..f463a26 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -75,6 +75,8 @@ int main(int argc, char * argv[]) { cout << "Press any key to stop..."; cin.get(); error = skt->stop(); + + cout << "Stopped..." << endl; } BFRelease(skt); diff --git a/src/office.cpp b/src/office.cpp index 00eab00..c74c6f2 100644 --- a/src/office.cpp +++ b/src/office.cpp @@ -51,7 +51,11 @@ void __IncomingRequestsWorkerThread(void * in) { _incomingRequests.unlock(); - LOG_WRITE("envelope: %s", (const char *) envelope->data()->buffer()); + if (envelope->data()->size() == 0) { + continue; + } + + LOG_WRITE("envelope.len(%ld):\n%s", envelope->data()->size(), (const char *) envelope->data()->buffer()); Request * req = new Request(envelope->data()); Response * resp = Response::fromRequest(req); From 4ec9387b5ddbe7f2acce23e03d5af076fe4f9668 Mon Sep 17 00:00:00 2001 From: Brando Date: Mon, 14 Apr 2025 17:26:16 -0700 Subject: [PATCH 25/39] lib update --- external/libs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/external/libs b/external/libs index c4c8ea7..c3326ea 160000 --- a/external/libs +++ b/external/libs @@ -1 +1 @@ -Subproject commit c4c8ea7807ea2b1d35c6fd8b05ee0e740c188915 +Subproject commit c3326ea91d4b1b6a99392c808f7e466b67be3ecb From a26c652b1fa71efb150a3bf9975df8e4d7c4a752 Mon Sep 17 00:00:00 2001 From: Brando Date: Mon, 14 Apr 2025 17:32:17 -0700 Subject: [PATCH 26/39] testing memory --- makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/makefile b/makefile index 5d4a931..10382fe 100644 --- a/makefile +++ b/makefile @@ -63,7 +63,7 @@ FLAGS = $(CPPFLAGS) -Isrc/ $(CPPSTD) -Iexternal/bin/libs/release else ifeq ($(CONFIG),debug) # debug MAIN_FILE = src/main.cpp BIN_NAME = http-debug -#ADDR_SANITIZER = -fsanitize=address +ADDR_SANITIZER = -fsanitize=address FLAGS = $(CPPFLAGS) -DDEBUG -g -Isrc/ $(ADDR_SANITIZER) $(CPPSTD) -Iexternal/bin/libs/debug ### Test settings From 0c20c5494bf5094c9b64e9b76c1fa338886d99f2 Mon Sep 17 00:00:00 2001 From: Brando Date: Mon, 14 Apr 2025 23:38:03 -0700 Subject: [PATCH 27/39] saving work --- external/libs | 2 +- src/office.cpp | 4 +++- src/request.cpp | 3 +++ 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/external/libs b/external/libs index c3326ea..49b0694 160000 --- a/external/libs +++ b/external/libs @@ -1 +1 @@ -Subproject commit c3326ea91d4b1b6a99392c808f7e466b67be3ecb +Subproject commit 49b0694d56c18a1f6869b85cf93cf7dc40b17139 diff --git a/src/office.cpp b/src/office.cpp index c74c6f2..59062b7 100644 --- a/src/office.cpp +++ b/src/office.cpp @@ -55,7 +55,9 @@ void __IncomingRequestsWorkerThread(void * in) { continue; } - LOG_WRITE("envelope.len(%ld):\n%s", envelope->data()->size(), (const char *) envelope->data()->buffer()); + //LOG_WRITE("envelope.len = %ld", envelope->data()->size()); + //LOG_WRITE("envelope:\n%s", (const char *) envelope->data()->buffer()); + //cout << "envelope:\n" << (const char *) envelope->data()->buffer() << endl; Request * req = new Request(envelope->data()); Response * resp = Response::fromRequest(req); diff --git a/src/request.cpp b/src/request.cpp index 3a3b610..545cd36 100644 --- a/src/request.cpp +++ b/src/request.cpp @@ -4,6 +4,7 @@ */ #include "request.hpp" +#include "log.hpp" #include #include @@ -11,6 +12,8 @@ using namespace BF; Request::Request(const Data * data) : _message(data == NULL ? 0 : (const char *) data->buffer(), data == NULL ? 0 : data->size()) { + LOG_WRITE("Request length = %ld", _message.size()); + LOG_WRITE("Request content = \n%s", _message.c_str()); } Request::~Request() { From 39a0f74cfadc3701bbfe0ec2176c8adfaafdbfce Mon Sep 17 00:00:00 2001 From: Brando Date: Wed, 16 Apr 2025 19:12:48 -0700 Subject: [PATCH 28/39] lib changes --- external/libs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/external/libs b/external/libs index 49b0694..addb406 160000 --- a/external/libs +++ b/external/libs @@ -1 +1 @@ -Subproject commit 49b0694d56c18a1f6869b85cf93cf7dc40b17139 +Subproject commit addb4060f93f66ee4d63ea5d9dc4c9929154e0d6 From c07b4edc28347e0819fff9c9ce505f8bdb9d4c4f Mon Sep 17 00:00:00 2001 From: Brando Date: Wed, 16 Apr 2025 19:42:08 -0700 Subject: [PATCH 29/39] can serve https://github.com/cloudacademy/static-website-example --- src/resource.cpp | 14 -------------- src/resource.hpp | 1 - src/response.cpp | 21 +++++++++++++++++++-- 3 files changed, 19 insertions(+), 17 deletions(-) diff --git a/src/resource.cpp b/src/resource.cpp index 8642941..a5c6c1f 100644 --- a/src/resource.cpp +++ b/src/resource.cpp @@ -33,17 +33,3 @@ bool Resource::setRootFolder(const String & rootFolder) { return true; } -Data * Resource::copyContentForFile(const String & file) { - URL url(_rootFolder); - - LOG_DEBUG("%s:%d - url-> '%s'", __func__, __LINE__, url.abspath()); - - - if (!BFFileSystemPathExists(url.abspath())) { - LOG_DEBUG("%s:%d - url above does not exist", __func__, __LINE__); - return NULL; - } - - return Data::fromFile(url); -} - diff --git a/src/resource.hpp b/src/resource.hpp index 5c3fb1d..95d0c8d 100644 --- a/src/resource.hpp +++ b/src/resource.hpp @@ -11,7 +11,6 @@ #include namespace Resource { - BF::Data * copyContentForFile(const BF::String & target); bool setRootFolder(const BF::String & rootFolder); const BF::String & getRootFolder(); } diff --git a/src/response.cpp b/src/response.cpp index df22ecf..52abcc4 100644 --- a/src/response.cpp +++ b/src/response.cpp @@ -40,6 +40,24 @@ Response * Response::fromRequest(const Request * request) { return res; } +String _ResponseTargetGetContentType(URL & target) { + if (!strcmp(target.extension(), "html")) { + return "text/html"; + } else if (!strcmp(target.extension(), "js")) { + return "text/javascript"; + } else if (!strcmp(target.extension(), "css")) { + return "text/css"; + } else if (!strcmp(target.extension(), "ico")) { + return "image/x-icon"; + } else if (!strcmp(target.extension(), "jpg") || !strcmp(target.extension(), "jpeg") + || !strcmp(target.extension(), "jfif") || !strcmp(target.extension(), "pjpeg") + || !strcmp(target.extension(), "pjp")) { + return "image/jpeg"; + } else { + return "text/plain"; + } +} + void Response::handleRequestGET(const Request * request, Response * response) { LOG_DEBUG("%s:%d", __func__, __LINE__); if (!request || !response) return; @@ -57,9 +75,8 @@ void Response::handleRequestGET(const Request * request, Response * response) { LOG_DEBUG("%s:%d", __func__, __LINE__); if (BFFileSystemPathIsFile(url.abspath())) { LOG_DEBUG("%s:%d", __func__, __LINE__); - //response->_content = Resource::copyContentForFile(request->target()); response->_content = Data::fromFile(url); - response->_contentType = "text/html"; + response->_contentType = _ResponseTargetGetContentType(url); } else { LOG_DEBUG("%s:%d", __func__, __LINE__); response->_statusCode = 404; From cc7a454e0027dbe93f98588b07a9ba41a76fc58b Mon Sep 17 00:00:00 2001 From: Brando Date: Wed, 16 Apr 2025 20:30:14 -0700 Subject: [PATCH 30/39] can get target absolute path --- makefile | 2 +- src/request.cpp | 46 +++++++++++++++++++++++++++++++++++++ src/request.hpp | 7 ++++++ src/response.cpp | 10 -------- testbench/request_tests.hpp | 18 ++++++++++++++- testbench/tests.cpp | 2 ++ 6 files changed, 73 insertions(+), 12 deletions(-) diff --git a/makefile b/makefile index 10382fe..7f0ff18 100644 --- a/makefile +++ b/makefile @@ -70,7 +70,7 @@ FLAGS = $(CPPFLAGS) -DDEBUG -g -Isrc/ $(ADDR_SANITIZER) $(CPPSTD) -Iexternal/bin else ifeq ($(CONFIG),test) # test MAIN_FILE = testbench/tests.cpp BIN_NAME = http-test -#ADDR_SANITIZER = -fsanitize=address +ADDR_SANITIZER = -fsanitize=address FLAGS = $(CPPFLAGS) -DDEBUG -DTESTING -g -Isrc/ $(ADDR_SANITIZER) $(CPPSTD) -Iexternal/bin/libs/debug LIBRARIES += external/bin/libs/debug/bftest/libbftest-debug.a endif # ($(CONFIG),...) diff --git a/src/request.cpp b/src/request.cpp index 545cd36..e819c91 100644 --- a/src/request.cpp +++ b/src/request.cpp @@ -7,6 +7,10 @@ #include "log.hpp" #include +extern "C" { +#include +} + #include using namespace BF; @@ -41,6 +45,48 @@ String Request::target() const { } } +String Request::targetPath() const { + String target = this->target(); + char * target_copy = BFStringCopyString(target.c_str()); + if (!target_copy) { + return target; + } + + const char * del = "?"; + char * sub = strtok(target_copy, del); + if (!sub) { + return target; + } + + String res = sub; + BFFree(target_copy); + + return res; +} + +HashMap Request::targetQuery() const { + HashMap res; + String target = this->target(); + char * target_copy = BFStringCopyString(target.c_str()); + if (!target_copy) { + return res; + } + + const char * del = "?"; + if (strtok(target_copy, del) == NULL) { + return res; + } + + char * sub = strtok(target_copy, del); + if (!sub) { + return res; + } + + BFFree(target_copy); + + return res; +} + String Request::protocol() const { std::regex protocolRegex(R"((?:GET|POST|PUT|DELETE|HEAD|OPTIONS|CONNECT|TRACE|PATCH)\s+[^\s]+\s+(HTTP/\d\.\d))"); std::smatch match; diff --git a/src/request.hpp b/src/request.hpp index 9128e46..4ae171f 100644 --- a/src/request.hpp +++ b/src/request.hpp @@ -7,6 +7,7 @@ #define REQUEST_HPP #include +#include #include #include @@ -25,6 +26,12 @@ class Request : public BF::Object { BF::String target() const; BF::String protocol() const; + // returns path without query string + BF::String targetPath() const; + + // returns query data + BF::HashMap targetQuery() const; + BF::String host() const; private: diff --git a/src/response.cpp b/src/response.cpp index 52abcc4..2645b77 100644 --- a/src/response.cpp +++ b/src/response.cpp @@ -23,20 +23,16 @@ Response::~Response() { } Response * Response::fromRequest(const Request * request) { - LOG_DEBUG("%s:%d", __func__, __LINE__); if (!request) return NULL; - LOG_DEBUG("%s:%d", __func__, __LINE__); Response * res = new Response; if (!res) return NULL; res->_statusCode = 200; if (request->method() == "GET") { - LOG_DEBUG("%s:%d", __func__, __LINE__); Response::handleRequestGET(request, res); } - LOG_DEBUG("%s:%d", __func__, __LINE__); return res; } @@ -59,26 +55,20 @@ String _ResponseTargetGetContentType(URL & target) { } void Response::handleRequestGET(const Request * request, Response * response) { - LOG_DEBUG("%s:%d", __func__, __LINE__); if (!request || !response) return; - LOG_DEBUG("%s:%d", __func__, __LINE__); String target = request->target(); URL url(Resource::getRootFolder()); url.append(target); - LOG_DEBUG("%s:%d", __func__, __LINE__); if (BFFileSystemPathIsDirectory(url.abspath())) { url.append("index.html"); } - LOG_DEBUG("%s:%d", __func__, __LINE__); if (BFFileSystemPathIsFile(url.abspath())) { - LOG_DEBUG("%s:%d", __func__, __LINE__); response->_content = Data::fromFile(url); response->_contentType = _ResponseTargetGetContentType(url); } else { - LOG_DEBUG("%s:%d", __func__, __LINE__); response->_statusCode = 404; response->_content = new Data("404 Not Found"); response->_contentType = "text/plain"; diff --git a/testbench/request_tests.hpp b/testbench/request_tests.hpp index 099a863..09981a6 100644 --- a/testbench/request_tests.hpp +++ b/testbench/request_tests.hpp @@ -61,10 +61,26 @@ BFTEST_UNIT_FUNC(test_simpleClientRequest, 2 << 8, { BFRelease(req); }) +BFTEST_UNIT_FUNC(test_requestTargetPathAndQuery, 1, { + String str = "GET /assets/fonts/fontawesome-webfont.ttf?v=4.6.3 HTTP/1.1\r\n\ + Host: 10.0.0.82:8080\r\n\ + User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:137.0) Gecko/20100101 Firefox/137.0\r\n\ + Accept: application/font-woff2;q=1.0,application/font-woff;q=0.9,*/*;q=0.8\r\n\ + Accept-Language: en-US,en;q=0.5\r\n\ + Accept-Encoding: gzip, deflate\r\n\ + Connection: keep-alive\r\n\ + Referer: http://10.0.0.82:8080/assets/css/font-awesome.min.css\r\n\ + "; + Data buf(str); + + Request req(&buf); + BF_ASSERT(req.targetPath() == "/assets/fonts/fontawesome-webfont.ttf"); +}) + BFTEST_COVERAGE_FUNC(request_tests, { BFTEST_LAUNCH(test_requestInit); BFTEST_LAUNCH(test_simpleClientRequest); - + BFTEST_LAUNCH(test_requestTargetPathAndQuery); }) #endif // REQUEST_TESTS_HPP diff --git a/testbench/tests.cpp b/testbench/tests.cpp index 904572d..b4c89f1 100644 --- a/testbench/tests.cpp +++ b/testbench/tests.cpp @@ -4,7 +4,9 @@ */ #include "request_tests.hpp" +#include "log.hpp" +LOG_INIT; BFTEST_SUITE_FUNC({ BFTEST_SUITE_LAUNCH(request_tests); }) From 15966b2a31dbe0a1f4d28ed80cd87c7c11451673 Mon Sep 17 00:00:00 2001 From: Brando Date: Wed, 16 Apr 2025 20:50:45 -0700 Subject: [PATCH 31/39] using a helper function --- external/libs | 2 +- src/office.cpp | 3 --- src/request.cpp | 55 ++++++++++++++++++++++++++++++++++-------------- src/response.cpp | 4 ++-- 4 files changed, 42 insertions(+), 22 deletions(-) diff --git a/external/libs b/external/libs index addb406..5e73e91 160000 --- a/external/libs +++ b/external/libs @@ -1 +1 @@ -Subproject commit addb4060f93f66ee4d63ea5d9dc4c9929154e0d6 +Subproject commit 5e73e917864a7fa6e87dc45ed9285b1c24dac0c2 diff --git a/src/office.cpp b/src/office.cpp index 59062b7..b756ab0 100644 --- a/src/office.cpp +++ b/src/office.cpp @@ -55,9 +55,6 @@ void __IncomingRequestsWorkerThread(void * in) { continue; } - //LOG_WRITE("envelope.len = %ld", envelope->data()->size()); - //LOG_WRITE("envelope:\n%s", (const char *) envelope->data()->buffer()); - //cout << "envelope:\n" << (const char *) envelope->data()->buffer() << endl; Request * req = new Request(envelope->data()); Response * resp = Response::fromRequest(req); diff --git a/src/request.cpp b/src/request.cpp index e819c91..5ee8ddd 100644 --- a/src/request.cpp +++ b/src/request.cpp @@ -45,7 +45,42 @@ String Request::target() const { } } +// component: 0=path, 1=query +String __RequestTargetParse(String & target, int component) { + int error = component != 0 && component != 1 ? 1 : 0; + String res; + char * target_copy = NULL; + + if (!error) { + target_copy = BFStringCopyString(target.c_str()); + if (!target_copy) { + res = target; + error = 1; + } + } + + const char * del = "?"; + char * sub = NULL; + while (!error && component-- >= 0) { + sub = strtok(target_copy, del); + if (!sub) { + res = target; + error = 1; + } + } + + if (!error) { + res = sub; + } + + BFFree(target_copy); + + return res; + +} + String Request::targetPath() const { + /* String target = this->target(); char * target_copy = BFStringCopyString(target.c_str()); if (!target_copy) { @@ -62,27 +97,15 @@ String Request::targetPath() const { BFFree(target_copy); return res; + */ + String target = this->target(); + return __RequestTargetParse(target, 0); } HashMap Request::targetQuery() const { HashMap res; String target = this->target(); - char * target_copy = BFStringCopyString(target.c_str()); - if (!target_copy) { - return res; - } - - const char * del = "?"; - if (strtok(target_copy, del) == NULL) { - return res; - } - - char * sub = strtok(target_copy, del); - if (!sub) { - return res; - } - - BFFree(target_copy); + String queryString = __RequestTargetParse(target, 1); return res; } diff --git a/src/response.cpp b/src/response.cpp index 2645b77..31a28f7 100644 --- a/src/response.cpp +++ b/src/response.cpp @@ -36,7 +36,7 @@ Response * Response::fromRequest(const Request * request) { return res; } -String _ResponseTargetGetContentType(URL & target) { +String __ResponseTargetGetContentType(URL & target) { if (!strcmp(target.extension(), "html")) { return "text/html"; } else if (!strcmp(target.extension(), "js")) { @@ -67,7 +67,7 @@ void Response::handleRequestGET(const Request * request, Response * response) { if (BFFileSystemPathIsFile(url.abspath())) { response->_content = Data::fromFile(url); - response->_contentType = _ResponseTargetGetContentType(url); + response->_contentType = __ResponseTargetGetContentType(url); } else { response->_statusCode = 404; response->_content = new Data("404 Not Found"); From af5637e32d8eeebe54e9fa6a65511c8402fa5ab2 Mon Sep 17 00:00:00 2001 From: Brando Date: Wed, 16 Apr 2025 21:56:03 -0700 Subject: [PATCH 32/39] saving work --- external/libs | 2 +- src/request.cpp | 49 +++++++++++++++++++++++-------------- testbench/request_tests.hpp | 3 +++ 3 files changed, 34 insertions(+), 20 deletions(-) diff --git a/external/libs b/external/libs index 5e73e91..98a21dd 160000 --- a/external/libs +++ b/external/libs @@ -1 +1 @@ -Subproject commit 5e73e917864a7fa6e87dc45ed9285b1c24dac0c2 +Subproject commit 98a21dd537bc17900cabe3b90f71295d880ebd8c diff --git a/src/request.cpp b/src/request.cpp index 5ee8ddd..e860628 100644 --- a/src/request.cpp +++ b/src/request.cpp @@ -52,7 +52,7 @@ String __RequestTargetParse(String & target, int component) { char * target_copy = NULL; if (!error) { - target_copy = BFStringCopyString(target.c_str()); + target_copy = target.cStringCopy(); if (!target_copy) { res = target; error = 1; @@ -61,12 +61,16 @@ String __RequestTargetParse(String & target, int component) { const char * del = "?"; char * sub = NULL; - while (!error && component-- >= 0) { - sub = strtok(target_copy, del); + int i = 0; + while (!error && component >= 0) { + sub = strtok(i == 0 ? target_copy : NULL, del); if (!sub) { res = target; error = 1; } + + component--; + i++; } if (!error) { @@ -80,32 +84,39 @@ String __RequestTargetParse(String & target, int component) { } String Request::targetPath() const { - /* String target = this->target(); - char * target_copy = BFStringCopyString(target.c_str()); - if (!target_copy) { - return target; - } + return __RequestTargetParse(target, 0); +} - const char * del = "?"; - char * sub = strtok(target_copy, del); - if (!sub) { - return target; - } +int __RequestQueryPairParse(HashMap & map, const char * pair) { + if (!pair) return 1; - String res = sub; - BFFree(target_copy); + char * pair_copy = BFStringCopyString(pair); + const char * del = "="; + String key = strtok(pair_copy, del); + String value = strtok(NULL, del); - return res; - */ - String target = this->target(); - return __RequestTargetParse(target, 0); + map.insert(key, value); + + BFFree(pair_copy); + + return 0; } HashMap Request::targetQuery() const { HashMap res; String target = this->target(); String queryString = __RequestTargetParse(target, 1); + char * query_copy = queryString.cStringCopy(); + + const char * del = "&"; + char * sub = NULL; + int i = 0; + while ((sub = strtok(i++ == 0 ? query_copy : NULL, del)) != NULL) { + __RequestQueryPairParse(res, sub); + } + + BFFree(query_copy); return res; } diff --git a/testbench/request_tests.hpp b/testbench/request_tests.hpp index 09981a6..92718f6 100644 --- a/testbench/request_tests.hpp +++ b/testbench/request_tests.hpp @@ -75,6 +75,9 @@ BFTEST_UNIT_FUNC(test_requestTargetPathAndQuery, 1, { Request req(&buf); BF_ASSERT(req.targetPath() == "/assets/fonts/fontawesome-webfont.ttf"); + + HashMap query = req.targetQuery(); + BF_ASSERT(query["v"] == "4.6.3"); }) BFTEST_COVERAGE_FUNC(request_tests, { From e1d65761a6710d920089d614059ed01e3bb3c6d1 Mon Sep 17 00:00:00 2001 From: Brando Date: Wed, 16 Apr 2025 22:12:49 -0700 Subject: [PATCH 33/39] updating libs --- external/libs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/external/libs b/external/libs index 98a21dd..84081e3 160000 --- a/external/libs +++ b/external/libs @@ -1 +1 @@ -Subproject commit 98a21dd537bc17900cabe3b90f71295d880ebd8c +Subproject commit 84081e3df8217289f87acfcc6ec11c64ef05680a From 852640cb0505515a6e5ddff4181369e3329a96cd Mon Sep 17 00:00:00 2001 From: Brando Date: Wed, 16 Apr 2025 22:19:09 -0700 Subject: [PATCH 34/39] lib update --- external/libs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/external/libs b/external/libs index 84081e3..3760207 160000 --- a/external/libs +++ b/external/libs @@ -1 +1 @@ -Subproject commit 84081e3df8217289f87acfcc6ec11c64ef05680a +Subproject commit 3760207566e0e1d7d01679519def0c37f6be4619 From e137bf0c55b1e94dbd9fc63ad2d9d6ea668d98a8 Mon Sep 17 00:00:00 2001 From: Brando Date: Wed, 16 Apr 2025 22:20:49 -0700 Subject: [PATCH 35/39] adding tests --- .github/workflows/test.yml | 48 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 .github/workflows/test.yml diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 0000000..d02a467 --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,48 @@ +name: CI + +on: + push: + branches: [ "dev" ] + paths-ignore: + - '*.md' + - 'docs/**' + pull_request: + branches: [ "dev" ] + paths-ignore: + - '*.md' + - 'docs/**' + +jobs: + unit-tests-linux: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + submodules: recursive + token: ${{ secrets.PAT_TOKEN }} + - name: Install uuid-dev + run: | + sudo apt -y update; + sudo apt -y upgrade; + sudo apt -y install uuid-dev; + - name: building libs + run: | + cd external; + make build-libs; + - name: building/running tests + run: make build CONFIG=test run + + unit-tests-macos: + runs-on: macos-latest + steps: + - uses: actions/checkout@v4 + with: + submodules: recursive + token: ${{ secrets.PAT_TOKEN }} + - name: building libs + run: | + cd external; + make build-libs; + - name: building/running tests + run: make build CONFIG=test run + From 7525b65fba5c7157ec0aa0e74619b64ace693ed5 Mon Sep 17 00:00:00 2001 From: Brando Date: Thu, 17 Apr 2025 11:36:05 -0700 Subject: [PATCH 36/39] updating --- external/libs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/external/libs b/external/libs index 3760207..67ca029 160000 --- a/external/libs +++ b/external/libs @@ -1 +1 @@ -Subproject commit 3760207566e0e1d7d01679519def0c37f6be4619 +Subproject commit 67ca029929ae21eba49f40afcac8c7958318cbbf From 85466c007c8b2162959185a9523919874e1db00e Mon Sep 17 00:00:00 2001 From: Brando Date: Thu, 17 Apr 2025 11:40:24 -0700 Subject: [PATCH 37/39] only worrying about the target path --- src/response.cpp | 2 +- testbench/request_tests.hpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/response.cpp b/src/response.cpp index 31a28f7..3c660a4 100644 --- a/src/response.cpp +++ b/src/response.cpp @@ -57,7 +57,7 @@ String __ResponseTargetGetContentType(URL & target) { void Response::handleRequestGET(const Request * request, Response * response) { if (!request || !response) return; - String target = request->target(); + String target = request->targetPath(); URL url(Resource::getRootFolder()); url.append(target); diff --git a/testbench/request_tests.hpp b/testbench/request_tests.hpp index 92718f6..362e47c 100644 --- a/testbench/request_tests.hpp +++ b/testbench/request_tests.hpp @@ -24,7 +24,7 @@ BFTEST_UNIT_FUNC(test_requestInit, 1, { BFRelease(req); }) -BFTEST_UNIT_FUNC(test_simpleClientRequest, 2 << 8, { +BFTEST_UNIT_FUNC(test_simpleClientRequest, 2 << 6, { String get_str = "GET /index.html HTTP/1.1\r\nHost: example.com\r\n\r\n"; Data get_buf(get_str); String post_str = "POST /submit.php HTTP/1.1\r\nHost: another.com\r\nContent-Length: 10\r\n\r\ndata=value"; @@ -61,7 +61,7 @@ BFTEST_UNIT_FUNC(test_simpleClientRequest, 2 << 8, { BFRelease(req); }) -BFTEST_UNIT_FUNC(test_requestTargetPathAndQuery, 1, { +BFTEST_UNIT_FUNC(test_requestTargetPathAndQuery, 2 << 8, { String str = "GET /assets/fonts/fontawesome-webfont.ttf?v=4.6.3 HTTP/1.1\r\n\ Host: 10.0.0.82:8080\r\n\ User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:137.0) Gecko/20100101 Firefox/137.0\r\n\ From 2bb071abd1907757a085e8a8da5b10dc694ca0cf Mon Sep 17 00:00:00 2001 From: Brando Date: Thu, 17 Apr 2025 11:42:37 -0700 Subject: [PATCH 38/39] disable sanitizer --- makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/makefile b/makefile index 7f0ff18..5d4a931 100644 --- a/makefile +++ b/makefile @@ -63,14 +63,14 @@ FLAGS = $(CPPFLAGS) -Isrc/ $(CPPSTD) -Iexternal/bin/libs/release else ifeq ($(CONFIG),debug) # debug MAIN_FILE = src/main.cpp BIN_NAME = http-debug -ADDR_SANITIZER = -fsanitize=address +#ADDR_SANITIZER = -fsanitize=address FLAGS = $(CPPFLAGS) -DDEBUG -g -Isrc/ $(ADDR_SANITIZER) $(CPPSTD) -Iexternal/bin/libs/debug ### Test settings else ifeq ($(CONFIG),test) # test MAIN_FILE = testbench/tests.cpp BIN_NAME = http-test -ADDR_SANITIZER = -fsanitize=address +#ADDR_SANITIZER = -fsanitize=address FLAGS = $(CPPFLAGS) -DDEBUG -DTESTING -g -Isrc/ $(ADDR_SANITIZER) $(CPPSTD) -Iexternal/bin/libs/debug LIBRARIES += external/bin/libs/debug/bftest/libbftest-debug.a endif # ($(CONFIG),...) From ad90cdee256d537ce8ce30c61ae88f3d573c2c44 Mon Sep 17 00:00:00 2001 From: Brando Date: Thu, 17 Apr 2025 13:31:56 -0700 Subject: [PATCH 39/39] update prep --- external/libs | 2 +- readme.md | 7 +++++++ todo.md | 6 ++++-- 3 files changed, 12 insertions(+), 3 deletions(-) create mode 100644 readme.md diff --git a/external/libs b/external/libs index 67ca029..35461a9 160000 --- a/external/libs +++ b/external/libs @@ -1 +1 @@ -Subproject commit 67ca029929ae21eba49f40afcac8c7958318cbbf +Subproject commit 35461a9eae5d0e552707aea329ca1c4beccbcb43 diff --git a/readme.md b/readme.md new file mode 100644 index 0000000..6092514 --- /dev/null +++ b/readme.md @@ -0,0 +1,7 @@ +# http +An http server using POSIX sockets + +## Resources +* [How I Built a Simple HTTP Server from Scratch using C ](https://dev.to/jeffreythecoder/how-i-built-a-simple-http-server-from-scratch-using-c-739) +* [Mozilla HTTP Documentation](https://developer.mozilla.org/en-US/docs/Web/HTTP) + diff --git a/todo.md b/todo.md index 9613aab..5231029 100644 --- a/todo.md +++ b/todo.md @@ -1,4 +1,6 @@ **0.1** -- [ ] serve html +- [x] serve html - [x] receive http requests from client (be sure to assemble the packets) - - [ ] Handle GET requests for resources + - [x] Handle GET requests for resources +- [ ] prevent requests from targetting anything outside of the root folder +