瀏覽代碼

Fix bridge bug & Refactor ContentGeneratorAPI

xcbosa-itx 2 年之前
父節點
當前提交
acfbd4df33

二進制
.DS_Store


+ 1 - 9
controller/StaticWebPageController.cpp

@@ -11,15 +11,7 @@ using namespace xc::processor;
 
 
 namespace xc::controller {
 namespace xc::controller {
 
 
-    static ContentGenerator staticWebPageController([] (auto p) {
-        if (p.getMethod() != "GET") { return false; }
-        struct stat buffer;
-        string filePath = "html/" + p.getURL();
-        return stat(filePath.c_str(), &buffer) == 0;
-    }, [] (auto p) {
-        string filePath = "html/" + p.getURL();
-        return new BinaryResponseData(200, filePath, "");
-    });
+
 
 
 }
 }
 
 

二進制
data/.DS_Store


二進制
data/html/.DS_Store


+ 18 - 0
httpserver/ClientConnection.cpp

@@ -37,6 +37,7 @@ namespace xc {
             this->clWrite = clWrite;
             this->clWrite = clWrite;
             char *requestBuff = (char *)::malloc(urlRequestBuffSize);
             char *requestBuff = (char *)::malloc(urlRequestBuffSize);
             this->requestBuff = requestBuff;
             this->requestBuff = requestBuff;
+
             ::fgets(requestBuff, urlRequestBuffSize, clRead);
             ::fgets(requestBuff, urlRequestBuffSize, clRead);
 
 
             if (::strstr(requestBuff, "HTTP/") == NULL) {
             if (::strstr(requestBuff, "HTTP/") == NULL) {
@@ -62,6 +63,8 @@ namespace xc {
                 ostringstream body;
                 ostringstream body;
 
 
                 bool isHeader = true;
                 bool isHeader = true;
+                bool lastLineIsEmpty = false;
+                bool lastLineEmptyAndZero = false;
                 while (::fgets(requestBuff, urlRequestBuffSize, clRead)) {
                 while (::fgets(requestBuff, urlRequestBuffSize, clRead)) {
                     int len = ::strlen(requestBuff);
                     int len = ::strlen(requestBuff);
                     char *lineBuff = (char *) ::malloc(len + 1), *pLineBuff = lineBuff;
                     char *lineBuff = (char *) ::malloc(len + 1), *pLineBuff = lineBuff;
@@ -86,8 +89,23 @@ namespace xc {
                     }
                     }
                     if (::strlen(lineBuff) == 0) {
                     if (::strlen(lineBuff) == 0) {
                         isHeader = false;
                         isHeader = false;
+                        lastLineIsEmpty = true;
+                        if (lastLineEmptyAndZero) {
+                            break;
+                        } else {
+                            lastLineEmptyAndZero = false;
+                        }
+                        if (method == "GET") {
+                            break;
+                        }
                         continue;
                         continue;
                     }
                     }
+                    if (lineBuff[0] == '0') {
+                        if (lastLineIsEmpty) {
+                            lastLineEmptyAndZero = true;
+                            lastLineIsEmpty = false;
+                        }
+                    }
                     if (isHeader) {
                     if (isHeader) {
                         char *headerValue;
                         char *headerValue;
                         char *headerName = strtok_r(lineBuff, ":", &headerValue);
                         char *headerName = strtok_r(lineBuff, ":", &headerValue);

+ 22 - 10
main.cpp

@@ -1,5 +1,5 @@
 #include <iostream>
 #include <iostream>
-#include "webui.h"
+#include <sys/stat.h>
 
 
 #include "httpserver/http-server.h"
 #include "httpserver/http-server.h"
 #include "utils/utils.h"
 #include "utils/utils.h"
@@ -8,17 +8,29 @@
 using namespace xc::httpserver;
 using namespace xc::httpserver;
 using namespace xc::processor;
 using namespace xc::processor;
 
 
+ContentGeneratorDefine({
+    if (request.getMethod() != "GET") { return false; }
+    struct stat buffer;
+    string filePath = "html/" + request.getURL();
+    return stat(filePath.c_str(), &buffer) == 0;
+}, {
+    string filePath = "html" + request.getURL();
+    return new BinaryResponseData(200, filePath, mimeTypeOfFile(filePath));
+})
+
+ContentGeneratorDefine(return request.getURL() == "/test1", {
+    return new TextResponseData(200, "test1 controller response");
+})
+
+ContentGeneratorDefine(return request.getURL() == "/test2", {
+    return new TextResponseData(200, "test2 controller response");
+})
+
 int main() {
 int main() {
     std::cout << "Hello, World!" << std::endl;
     std::cout << "Hello, World!" << std::endl;
     HTTPServer server(8192);
     HTTPServer server(8192);
-    thread serverThread([&server] {
-        server.serverLoop();
-    });
-    serverThread.detach();
+    thread([&server] { server.serverLoop(); }).detach();
     RequestProcessWorker worker;
     RequestProcessWorker worker;
-    thread workerThread([&worker] {
-        worker.workerLoop();
-    });
-    while (true) ;
-    return 0;
+    thread([&worker] { worker.workerLoop(); }).detach();
+    while (true) usleep(1000);
 }
 }

+ 3 - 2
processor/ContentGenerator.cpp

@@ -6,12 +6,13 @@
 
 
 namespace xc {
 namespace xc {
     namespace processor {
     namespace processor {
-        extern vector<ContentGenerator *> generators;
+        ContentGenerator *generators[1024];
+        int generatorsCnt = 0;
 
 
         ContentGenerator::ContentGenerator(RequestCheckBlock checker, ContentGenerateBlock generator) {
         ContentGenerator::ContentGenerator(RequestCheckBlock checker, ContentGenerateBlock generator) {
             this->checker = checker;
             this->checker = checker;
             this->generator = generator;
             this->generator = generator;
-            generators.push_back(this);
+            generators[generatorsCnt++] = this;
         }
         }
 
 
         bool ContentGenerator::matchRequest(RequestData request) {
         bool ContentGenerator::matchRequest(RequestData request) {

+ 7 - 0
processor/ContentGenerator.h

@@ -7,6 +7,13 @@
 #include "processor-private.h"
 #include "processor-private.h"
 #include "../utils/utils.h"
 #include "../utils/utils.h"
 
 
+#define __merge_body(a, b) a ## b
+#define __merge(a, b) __merge_body(a, b)
+#define __uniqueVarName(name) __merge(name, __LINE__)
+
+#define ContentGeneratorDefine(cond, eval) \
+const ContentGenerator __uniqueVarName(AutoContentGenerator)([] (auto request) { cond; }, [] (auto request) { eval; });
+
 using namespace std;
 using namespace std;
 
 
 namespace xc {
 namespace xc {

+ 6 - 7
processor/RequestProcessWorker.cpp

@@ -9,14 +9,13 @@
 namespace xc {
 namespace xc {
     namespace processor {
     namespace processor {
 
 
-        vector<ContentGenerator *> generators;
-
         void RequestProcessWorker::workerLoop() {
         void RequestProcessWorker::workerLoop() {
             while (true) {
             while (true) {
-                RequestProcessTask task = processor::dequeueTaskSync();
+                RequestProcessTask *task = processor::dequeueTaskSync();
                 ContentGenerator *generator = nullptr;
                 ContentGenerator *generator = nullptr;
-                for (auto it : generators) {
-                    if (it->matchRequest(task.getRequest())) {
+                for (int i = 0; i < generatorsCnt; i++) {
+                    auto it = generators[i];
+                    if (it->matchRequest(task->getRequest())) {
                         generator = it;
                         generator = it;
                     }
                     }
                 }
                 }
@@ -24,9 +23,9 @@ namespace xc {
                 if (generator == nullptr) {
                 if (generator == nullptr) {
                     resp = new FileResponseData(conf::errorPage404);
                     resp = new FileResponseData(conf::errorPage404);
                 } else {
                 } else {
-                    resp = generator->generateResponse(task.getRequest());
+                    resp = generator->generateResponse(task->getRequest());
                 }
                 }
-                task.processFinish(resp);
+                task->processFinish(resp);
             }
             }
         }
         }
 
 

+ 2 - 2
processor/RequestProcessorManager.cpp

@@ -21,11 +21,11 @@ namespace xc {
             taskQueueMutex.unlock();
             taskQueueMutex.unlock();
         }
         }
 
 
-        RequestProcessTask dequeueTaskSync() {
+        RequestProcessTask *dequeueTaskSync() {
             while (true) {
             while (true) {
                 taskQueueMutex.lock();
                 taskQueueMutex.lock();
                 if (!taskQueue.empty()) {
                 if (!taskQueue.empty()) {
-                    RequestProcessTask task = *taskQueue.front();
+                    RequestProcessTask *task = taskQueue.front();
                     taskQueue.pop_front();
                     taskQueue.pop_front();
                     taskQueueMutex.unlock();
                     taskQueueMutex.unlock();
                     return task;
                     return task;

+ 1 - 1
processor/RequestProcessorManager.h

@@ -16,6 +16,6 @@ namespace xc {
         void deleteTask(RequestProcessTask *task);
         void deleteTask(RequestProcessTask *task);
 
 
         /*从处理队列中取出一个,如果没有则等待*/
         /*从处理队列中取出一个,如果没有则等待*/
-        RequestProcessTask dequeueTaskSync();
+        RequestProcessTask *dequeueTaskSync();
     }
     }
 }
 }

+ 6 - 0
processor/processor-private.h

@@ -19,3 +19,9 @@
 
 
 using namespace std;
 using namespace std;
 using namespace xc::utils;
 using namespace xc::utils;
+
+namespace xc::processor {
+    class ContentGenerator;
+    extern ContentGenerator *generators[];
+    extern int generatorsCnt;
+}

+ 1 - 1
utils/BinaryResponseData.cpp

@@ -57,7 +57,7 @@ namespace xc {
                 if (inputFile) {
                 if (inputFile) {
                     ::uint8_t buff[mtu];
                     ::uint8_t buff[mtu];
                     long readPerPack = 0;
                     long readPerPack = 0;
-                    while ((readPerPack = ::fread(buff, 1, mtu, inputFile)) == mtu) {
+                    while ((readPerPack = ::fread(buff, 1, mtu, inputFile)) > 0) {
                         ::fwrite(buff, 1, readPerPack, fp);
                         ::fwrite(buff, 1, readPerPack, fp);
                     }
                     }
                 } else {
                 } else {

+ 14 - 0
utils/FileReader.cpp

@@ -20,4 +20,18 @@ namespace xc::utils {
         fin.close();
         fin.close();
         return str;
         return str;
     }
     }
+
+    string mimeTypeOfFile(string filePath) {
+        std::filesystem::path p(filePath);
+        string ext = p.extension();
+        auto cit = conf::fileExtensionToMimeTypes.find(ext);
+        if (cit != conf::fileExtensionToMimeTypes.end()) {
+            return cit->second;
+        }
+        cit = conf::fileExtensionToMimeTypes.find("default");
+        if (cit != conf::fileExtensionToMimeTypes.end()) {
+            return cit->second;
+        }
+        return "data";
+    }
 }
 }

+ 1 - 0
utils/utils.h

@@ -14,4 +14,5 @@ using namespace std;
 
 
 namespace xc::utils {
 namespace xc::utils {
     string contentsOfTextFile(string filePath);
     string contentsOfTextFile(string filePath);
+    string mimeTypeOfFile(string filePath);
 }
 }