diff --git a/CMakeLists.txt b/CMakeLists.txt index 11c1d3d..f760331 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,7 +4,8 @@ set(CMAKE_CXX_STANDARD 23) add_subdirectory(netlib) -add_executable(web_serv main.cpp) +add_executable(web_serv main.cpp +) target_link_libraries(web_serv PRIVATE netlib) diff --git a/main.cpp b/main.cpp index b004e84..5f8382f 100644 --- a/main.cpp +++ b/main.cpp @@ -4,6 +4,7 @@ #endif #include #include +#include int atoi_newline(const char *data) { @@ -34,6 +35,97 @@ std::string get_filename(std::string_view data) return ret; } +static std::vector split_until_newline(const std::string &data, const char c) +{ + std::vector ret; + size_t index = 0; + size_t previous_start = 0; + + while (data[index] != '\n' && data[index] != '\0') + { + if (data[index] == c || data[index] == '\r') + { + ret.push_back(data.substr(previous_start, index - previous_start)); + previous_start = index + 1; + } + index++; + } + ret.push_back(data.substr(previous_start, index - previous_start)); + return ret; +} + +static std::vector split(const std::string &data, const std::string d) +{ + std::vector ret; + size_t index = 0; + size_t index2 = 0; + size_t previous_start = 0; + + while (index < data.size()) + { + if (data[index] == d[index2]) + { + index2++; + if (index2 >= d.size()) + { + ret.push_back(data.substr(previous_start, (index - previous_start))); + previous_start = index + 1; + index2 = 0; + } + } + else + index2 = 0; + index++; + } + ret.push_back(data.substr(previous_start, index - previous_start)); + return ret; +} + +template +void print_container(T &container) +{ + for (auto x: container) + { + std::println("{}", x); + } +} + +template +void print_map(T container) +{ + for (auto [key, value]: container) + { + value.erase(std::remove(value.begin(), value.end(), '\n'), value.end()); + value.erase(std::remove(value.begin(), value.end(), '\r'), value.end()); + std::println("key {} value {}", key, value); + } +} + +std::map parse_header(const std::string &x) +{ + std::map ret; + if (x.contains(": ")) + { + std::vector s = split(x, ": "); + ret.insert({s[0], s[1]}); + } + return ret; +} + +std::map parse_headers(const std::vector &data) +{ + std::map ret; + for (auto &x: data) + { + if (x.contains(": ")) + { + std::vector s = split(x, ": "); + ret.insert({s[0], s[1]}); + } + } + return ret; +} + int main() { netlib::server_raw server(false, 0); @@ -42,26 +134,18 @@ int main() while (true) { std::vector readable = server.wait_readable(); - //std::this_thread::sleep_for(std::chrono::milliseconds(50)); + std::this_thread::sleep_for(std::chrono::milliseconds(50)); for (auto user: readable) { - char *data = server.receive_data_ensured(user, 3000); + char * data = server.get_line(user); if (data) { - std::string_view dat(data); - if (dat.starts_with("GET") && dat.size() > 4) + std::string dat = std::string(data); + std::vector head = split(dat, " "); + print_container(head); + if (head[0] == "GET") { - dat.remove_prefix(4); - int ins_size = 0; - for (auto c: dat) - { - if (c == ' ') - break; - ins_size++; - } - dat.remove_suffix(dat.size() - ins_size); - std::println("{}", dat); - if (dat == "/") + if (head[1] == "/") { netlib::send_packet(std::make_tuple(std::string("HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n")), user); std::ifstream file("../test.html",std::ios::binary); @@ -77,49 +161,26 @@ int main() sendfile(filefd, user, 0, (long long*)&size, nullptr, 0); #endif } - server.disconnect_user(user); } - if (dat.starts_with("POST")) + else if (head[0] == "POST") { - size_t pos = dat.find("Content-Length"); - dat.remove_prefix(pos); - dat.remove_prefix(strlen("Content-Length: ")); - int lenght = atoi_newline(dat.data()); - std::println("{} {}", dat, lenght); - - pos = dat.find("filename="); - if (pos == dat.npos) - - dat.remove_prefix(pos); - dat.remove_prefix(strlen("filename=")); - std::string_view file_data(data); - std::string filename = get_filename(dat); - std::println("Filename {}", filename); - dat.remove_prefix(dat.find("\r\n\r\n")); - dat.remove_prefix(dat.find("\r\n\r\n")); - dat.remove_prefix(4); - std::println("{}", dat); - if (lenght > 1000) + while (true) { - std::println("set a target"); - server.set_target(user , lenght - (dat.data() - data)); - server.wait_readable(); - auto data_res = server.receive_everything(user); - char *buffer = data_res.first; - data = (char *)realloc(data, lenght + 1000); - if (!data) - throw std::runtime_error("Memory allocation failed"); - memcpy(data, buffer, lenght + 1000); - dat = std::string_view(data); + char *line = server.get_line(user); + if (line) + { + std::string str = std::string(line); + auto head = parse_header(str); + print_map(head); + } + else + break; + free(line); } - std::ofstream a(filename, std::ios::binary); - a.write(dat.data(), lenght); - netlib::send_packet(std::make_tuple(std::string("HTTP/1.1 200 OK")), user); - server.disconnect_user(user); } + server.disconnect_user(user); free(data); } - } } } diff --git a/netlib b/netlib index 99838bb..a91be41 160000 --- a/netlib +++ b/netlib @@ -1 +1 @@ -Subproject commit 99838bb7ecf8cbc698d9aaa45707b1fec23710a1 +Subproject commit a91be412a9a5b05911e0029241ce0ff6fd5c2d6b