Loading editor/src/webedit_api.cpp +31 −56 Original line number Diff line number Diff line Loading @@ -780,74 +780,49 @@ void webedit::Api::handlePreviewPage(libhttppp::HttpRequest &curreq, return; } // Export the current document as XML std::string xmlData; // Render the document tree to HTML locally std::string widgetHtml; { auto &doc = getDocState(sessionid); std::lock_guard<std::mutex> lk(doc.mtx); xmlData = exportTreeXml(doc); widgetHtml = renderTree(doc.root); } try { // 1. Send ImportXml to blog server json_object *importArr = json_object_new_array(); json_object *authObj = json_object_new_object(); json_object_object_add(authObj, "authid", json_object_new_string(authid.c_str())); json_object_array_add(importArr, authObj); json_object *importCmd = json_object_new_object(); json_object_object_add(importCmd, "command", json_object_new_string("ImportXml")); json_object_object_add(importCmd, "xml", json_object_new_string(xmlData.c_str())); json_object_array_add(importArr, importCmd); json_object *importResp = blogApiCall(blogUrl, importArr); json_object_put(importArr); if (importResp) json_object_put(importResp); // 2. Send ExportHtml to get the rendered HTML json_object *exportArr = json_object_new_array(); json_object *authObj2 = json_object_new_object(); json_object_object_add(authObj2, "authid", json_object_new_string(authid.c_str())); json_object_array_add(exportArr, authObj2); json_object *exportCmd = json_object_new_object(); json_object_object_add(exportCmd, "command", json_object_new_string("ExportHtml")); json_object_array_add(exportArr, exportCmd); json_object *exportResp = blogApiCall(blogUrl, exportArr); json_object_put(exportArr); if (!exportResp) { sendJsonError(curreq, 502, "No response from blog server"); return; } // POST to the blog's /render endpoint with authid + html libhttppp::HttpUrl url(blogUrl + "/render"); libhttppp::HttpClient client(url); client.setTimeout(15); // Extract rendered HTML from response std::string renderedHtml; if (json_object_is_type(exportResp, json_type_array)) { size_t len = json_object_array_length(exportResp); for (size_t i = 0; i < len; ++i) { json_object *item = json_object_array_get_idx(exportResp, i); json_object *htmlObj = nullptr; if (json_object_object_get_ex(item, "html", &htmlObj)) { const char *h = json_object_get_string(htmlObj); if (h) renderedHtml = h; } } } json_object_put(exportResp); libhttppp::HttpRequest renderReq; renderReq.setRequestURL(url.getPath()); renderReq.setHeaderData("content-type")->push_back("application/x-www-form-urlencoded"); // Build complete HTML page std::string page; page += "<!DOCTYPE html>\n<html>\n<head>\n"; page += "<meta charset=\"utf-8\">\n"; page += "<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n"; page += "</head>\n<body>\n"; page += renderedHtml; page += "\n</body>\n</html>"; // URL-encode the form data std::string encodedAuthid, encodedHtml; libhttppp::HttpForm::urlEncode(authid, encodedAuthid); libhttppp::HttpForm::urlEncode(widgetHtml, encodedHtml); std::string formBody = "authid=" + encodedAuthid + "&html=" + encodedHtml; std::vector<char> postData(formBody.begin(), formBody.end()); std::vector<char> respData = client.Post(renderReq, postData); if (respData.empty()) { std::string errPage = "<!DOCTYPE html><html><body><p>Preview error: " "empty response from blog server</p></body></html>"; libhttppp::HttpResponse curres; curres.setState(HTTP200); curres.setContentType("text/html"); curres.send(curreq, page.data(), page.size()); curres.send(curreq, errPage.data(), errPage.size()); return; } // The blog returns a complete themed HTML page — forward it directly libhttppp::HttpResponse curres; curres.setState(HTTP200); curres.setContentType("text/html"); curres.send(curreq, respData.data(), respData.size()); } catch (const std::exception &e) { std::string errPage = "<!DOCTYPE html><html><body><p>Preview error: " + Loading Loading
editor/src/webedit_api.cpp +31 −56 Original line number Diff line number Diff line Loading @@ -780,74 +780,49 @@ void webedit::Api::handlePreviewPage(libhttppp::HttpRequest &curreq, return; } // Export the current document as XML std::string xmlData; // Render the document tree to HTML locally std::string widgetHtml; { auto &doc = getDocState(sessionid); std::lock_guard<std::mutex> lk(doc.mtx); xmlData = exportTreeXml(doc); widgetHtml = renderTree(doc.root); } try { // 1. Send ImportXml to blog server json_object *importArr = json_object_new_array(); json_object *authObj = json_object_new_object(); json_object_object_add(authObj, "authid", json_object_new_string(authid.c_str())); json_object_array_add(importArr, authObj); json_object *importCmd = json_object_new_object(); json_object_object_add(importCmd, "command", json_object_new_string("ImportXml")); json_object_object_add(importCmd, "xml", json_object_new_string(xmlData.c_str())); json_object_array_add(importArr, importCmd); json_object *importResp = blogApiCall(blogUrl, importArr); json_object_put(importArr); if (importResp) json_object_put(importResp); // 2. Send ExportHtml to get the rendered HTML json_object *exportArr = json_object_new_array(); json_object *authObj2 = json_object_new_object(); json_object_object_add(authObj2, "authid", json_object_new_string(authid.c_str())); json_object_array_add(exportArr, authObj2); json_object *exportCmd = json_object_new_object(); json_object_object_add(exportCmd, "command", json_object_new_string("ExportHtml")); json_object_array_add(exportArr, exportCmd); json_object *exportResp = blogApiCall(blogUrl, exportArr); json_object_put(exportArr); if (!exportResp) { sendJsonError(curreq, 502, "No response from blog server"); return; } // POST to the blog's /render endpoint with authid + html libhttppp::HttpUrl url(blogUrl + "/render"); libhttppp::HttpClient client(url); client.setTimeout(15); // Extract rendered HTML from response std::string renderedHtml; if (json_object_is_type(exportResp, json_type_array)) { size_t len = json_object_array_length(exportResp); for (size_t i = 0; i < len; ++i) { json_object *item = json_object_array_get_idx(exportResp, i); json_object *htmlObj = nullptr; if (json_object_object_get_ex(item, "html", &htmlObj)) { const char *h = json_object_get_string(htmlObj); if (h) renderedHtml = h; } } } json_object_put(exportResp); libhttppp::HttpRequest renderReq; renderReq.setRequestURL(url.getPath()); renderReq.setHeaderData("content-type")->push_back("application/x-www-form-urlencoded"); // Build complete HTML page std::string page; page += "<!DOCTYPE html>\n<html>\n<head>\n"; page += "<meta charset=\"utf-8\">\n"; page += "<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n"; page += "</head>\n<body>\n"; page += renderedHtml; page += "\n</body>\n</html>"; // URL-encode the form data std::string encodedAuthid, encodedHtml; libhttppp::HttpForm::urlEncode(authid, encodedAuthid); libhttppp::HttpForm::urlEncode(widgetHtml, encodedHtml); std::string formBody = "authid=" + encodedAuthid + "&html=" + encodedHtml; std::vector<char> postData(formBody.begin(), formBody.end()); std::vector<char> respData = client.Post(renderReq, postData); if (respData.empty()) { std::string errPage = "<!DOCTYPE html><html><body><p>Preview error: " "empty response from blog server</p></body></html>"; libhttppp::HttpResponse curres; curres.setState(HTTP200); curres.setContentType("text/html"); curres.send(curreq, page.data(), page.size()); curres.send(curreq, errPage.data(), errPage.size()); return; } // The blog returns a complete themed HTML page — forward it directly libhttppp::HttpResponse curres; curres.setState(HTTP200); curres.setContentType("text/html"); curres.send(curreq, respData.data(), respData.size()); } catch (const std::exception &e) { std::string errPage = "<!DOCTYPE html><html><body><p>Preview error: " + Loading