From 6cb14218988950fbe0c858b001e0c324e487d26e Mon Sep 17 00:00:00 2001 From: chmodsayshello Date: Wed, 9 Aug 2023 16:41:27 +0200 Subject: [PATCH 01/10] add option to display webpage titles by right clicking --- builtin/settingtypes.txt | 2 + src/defaultsettings.cpp | 1 + src/gui/guiChatConsole.cpp | 99 ++++++++++++++++++++++++++++++++------ src/gui/guiChatConsole.h | 10 +++- 4 files changed, 97 insertions(+), 15 deletions(-) diff --git a/builtin/settingtypes.txt b/builtin/settingtypes.txt index 172616194cc9..646548efb885 100644 --- a/builtin/settingtypes.txt +++ b/builtin/settingtypes.txt @@ -714,6 +714,8 @@ chat_weblink_color (Weblink color) string #8888FF # Value 0 will use the default font size. chat_font_size (Chat font size) int 0 0 72 +# Right Click links to show webpage title +right_click_chat_web_titles (Rightclick webpage title) bool false [**Content Repository] diff --git a/src/defaultsettings.cpp b/src/defaultsettings.cpp index 8744de44d6a3..c5b773460cd2 100644 --- a/src/defaultsettings.cpp +++ b/src/defaultsettings.cpp @@ -68,6 +68,7 @@ void set_default_settings() settings->setDefault("occlusion_culler", "bfs"); settings->setDefault("enable_raytraced_culling", "true"); settings->setDefault("chat_weblink_color", "#8888FF"); + settings->setDefault("right_click_chat_web_titles","false"); // Keymap settings->setDefault("remote_port", "30000"); diff --git a/src/gui/guiChatConsole.cpp b/src/gui/guiChatConsole.cpp index 986a9a530d25..11e2579a97b4 100644 --- a/src/gui/guiChatConsole.cpp +++ b/src/gui/guiChatConsole.cpp @@ -33,6 +33,11 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "util/string.h" #include +#ifdef USE_CURL +#include +#include // we only need threads when curl is there (as getting a webpage title could freeze the entire client otherwise) +#endif + inline u32 clamp_u8(s32 value) { return (u32) MYMIN(MYMAX(value, 0), 255); @@ -96,6 +101,7 @@ GUIChatConsole::GUIChatConsole( // track ctrl keys for mouse event m_is_ctrl_down = false; m_cache_clickable_chat_weblinks = g_settings->getBool("clickable_chat_weblinks"); + m_cache_right_click_chat_web_titles = g_settings->getBool("right_click_chat_web_titles"); } GUIChatConsole::~GUIChatConsole() @@ -673,7 +679,7 @@ bool GUIChatConsole::OnEvent(const SEvent& event) { // Translate pixel position to font position bool was_url_pressed = m_cache_clickable_chat_weblinks && - weblinkClick(event.MouseInput.X / m_fontsize.X, + weblinkClickOpen(event.MouseInput.X / m_fontsize.X, event.MouseInput.Y / m_fontsize.Y); if (!was_url_pressed @@ -690,6 +696,15 @@ bool GUIChatConsole::OnEvent(const SEvent& event) } } } +#ifdef USE_CURL + else if(event.MouseInput.Event == EMIE_RMOUSE_PRESSED_DOWN && m_cache_right_click_chat_web_titles){ + if (event.MouseInput.Y / m_fontsize.Y < (m_height / m_fontsize.Y) - 1 ){ + std::thread t(&GUIChatConsole::weblinkClickTitle, this, (event.MouseInput.X / m_fontsize.X), + (event.MouseInput.Y / m_fontsize.Y)); + t.detach(); + } + } +#endif } else if(event.EventType == EET_STRING_INPUT_EVENT) { @@ -710,26 +725,16 @@ void GUIChatConsole::setVisible(bool visible) } } -bool GUIChatConsole::weblinkClick(s32 col, s32 row) -{ - // Prevent accidental rapid clicking - static u64 s_oldtime = 0; - u64 newtime = porting::getTimeMs(); - - // 0.6 seconds should suffice - if (newtime - s_oldtime < 600) - return false; - s_oldtime = newtime; - +std::string GUIChatConsole::getLinkAt(s32 col, s32 row){ const std::vector & - frags = m_chat_backend->getConsoleBuffer().getFormattedLine(row).fragments; + frags = m_chat_backend->getConsoleBuffer().getFormattedLine(row).fragments; std::string weblink = ""; // from frag meta // Identify targetted fragment, if exists int indx = frags.size() - 1; if (indx < 0) { // Invalid row, frags is empty - return false; + return ""; } // Scan from right to left, offset by 1 font space because left margin while (indx > -1 && (u32)col < frags[indx].column + 1) { @@ -737,8 +742,28 @@ bool GUIChatConsole::weblinkClick(s32 col, s32 row) } if (indx > -1) { weblink = frags[indx].weblink; + return weblink; // Note if(indx < 0) then a frag somehow had a corrupt column field } + return ""; +} + +bool GUIChatConsole::weblinkClickOpen(s32 col, s32 row) +{ + // Prevent accidental rapid clicking + static u64 s_oldtime = 0; + u64 newtime = porting::getTimeMs(); + + // 0.6 seconds should suffice + if (newtime - s_oldtime < 600) + return false; + s_oldtime = newtime; + + std::string weblink = getLinkAt(col, row); + + if (weblink.empty()){ + return false; + } /* // Debug help. Please keep this in case adjustments are made later. @@ -773,6 +798,52 @@ bool GUIChatConsole::weblinkClick(s32 col, s32 row) return false; } +#ifdef USE_CURL +// This is a function for CURL to write the page's html into a string +size_t writeHtml(void* contents, size_t size, size_t nmemb, std::string* strptr) { + size_t totalSize = size * nmemb; + strptr->append((char*)contents, totalSize); + return totalSize; +} +#endif + +void GUIChatConsole::weblinkClickTitle(s32 col, s32 row){ + std::ostringstream msg; + msg << " * "; +#ifdef USE_CURL + std::string weblink, html, title; + weblink = getLinkAt(col, row); + CURL* curl = curl_easy_init(); + + if(weblink.empty() || !curl){ + return; + } + + curl_easy_setopt(curl, CURLOPT_URL, weblink.c_str()); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writeHtml); + curl_easy_setopt(curl, CURLOPT_WRITEDATA, &html); + curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); // Important for services like https://bit.ly or https://is.gd + curl_easy_setopt(curl, CURLOPT_TIMEOUT, 10L); // As we don't know if we are stuck in an infinite loop of redirects or if the specifiec server exists at ALL, 10 secs is max! + CURLcode res = curl_easy_perform(curl); + curl_easy_cleanup(curl); + + if(res == CURLE_OPERATION_TIMEDOUT || res == CURLE_COULDNT_RESOLVE_HOST) { + msg << gettext("Host does not exist or timeout for 3rd party webpages reached!"); + } else { + if (res != CURLE_OK || html.find("") == std::string::npos || html.find("") == std::string::npos) { + msg << gettext("Unkown error while fetching page title!"); + } + size_t start = html.find("") + 7; // +7 so the html tag isn't in there... + size_t end = html.find(""); + title = html.substr(start, end - start); + msg << gettext("Webpage title:") << " '" << title << "'" ; + } + +#else + msg << gettext("Unable to get webpage title (cURL missing)!"); +#endif + m_chat_backend->addUnparsedMessage(utf8_to_wide(msg.str())); +} void GUIChatConsole::updatePrimarySelection() { #if IRRLICHT_VERSION_MT_REVISION >= 11 diff --git a/src/gui/guiChatConsole.h b/src/gui/guiChatConsole.h index 7555dabe3f54..343a58ebc538 100644 --- a/src/gui/guiChatConsole.h +++ b/src/gui/guiChatConsole.h @@ -84,9 +84,15 @@ class GUIChatConsole : public gui::IGUIElement void drawText(); void drawPrompt(); + // If there is a weblink at the specified place, it gets returned. Empty string otherwise + std::string getLinkAt(s32 col, s32 row); + // If clicked fragment has a web url, send it to the system default web browser. // Returns true if, and only if a web url was pressed. - bool weblinkClick(s32 col, s32 row); + bool weblinkClickOpen(s32 col, s32 row); + + // If a weblink was clicked, this will get the page's title and display it in chat + void weblinkClickTitle(s32 col, s32 row); // If the selected text changed, we need to update the (X11) primary selection. void updatePrimarySelection(); @@ -136,6 +142,8 @@ class GUIChatConsole : public gui::IGUIElement // Enable clickable chat weblinks bool m_cache_clickable_chat_weblinks; + // Enable right clickable chat website titles + bool m_cache_right_click_chat_web_titles; // Track if a ctrl key is currently held down bool m_is_ctrl_down; }; From 5837a59a50ec7db8bd31203987145469cebf0c83 Mon Sep 17 00:00:00 2001 From: chmodsayshello Date: Thu, 10 Aug 2023 16:17:02 +0200 Subject: [PATCH 02/10] implement some feedback --- src/gui/guiChatConsole.cpp | 74 ++++++++++++++++++-------------------- src/gui/guiChatConsole.h | 2 +- 2 files changed, 36 insertions(+), 40 deletions(-) diff --git a/src/gui/guiChatConsole.cpp b/src/gui/guiChatConsole.cpp index 11e2579a97b4..7faf4431f82c 100644 --- a/src/gui/guiChatConsole.cpp +++ b/src/gui/guiChatConsole.cpp @@ -34,7 +34,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include #ifdef USE_CURL -#include +#include "httpfetch.h" #include // we only need threads when curl is there (as getting a webpage title could freeze the entire client otherwise) #endif @@ -696,15 +696,14 @@ bool GUIChatConsole::OnEvent(const SEvent& event) } } } -#ifdef USE_CURL else if(event.MouseInput.Event == EMIE_RMOUSE_PRESSED_DOWN && m_cache_right_click_chat_web_titles){ if (event.MouseInput.Y / m_fontsize.Y < (m_height / m_fontsize.Y) - 1 ){ - std::thread t(&GUIChatConsole::weblinkClickTitle, this, (event.MouseInput.X / m_fontsize.X), - (event.MouseInput.Y / m_fontsize.Y)); + std::thread t(&GUIChatConsole::weblinkClickTitle, this, getLinkAt(event.MouseInput.X / m_fontsize.X, + event.MouseInput.Y / m_fontsize.Y), + m_chat_backend); t.detach(); } } -#endif } else if(event.EventType == EET_STRING_INPUT_EVENT) { @@ -798,51 +797,48 @@ bool GUIChatConsole::weblinkClickOpen(s32 col, s32 row) return false; } -#ifdef USE_CURL -// This is a function for CURL to write the page's html into a string -size_t writeHtml(void* contents, size_t size, size_t nmemb, std::string* strptr) { - size_t totalSize = size * nmemb; - strptr->append((char*)contents, totalSize); - return totalSize; -} -#endif +void GUIChatConsole::weblinkClickTitle(std::string weblink, ChatBackend* chat_backend){ + if (weblink.empty()){ + return; + } -void GUIChatConsole::weblinkClickTitle(s32 col, s32 row){ std::ostringstream msg; msg << " * "; + #ifdef USE_CURL - std::string weblink, html, title; - weblink = getLinkAt(col, row); - CURL* curl = curl_easy_init(); - - if(weblink.empty() || !curl){ - return; + u64 caller = httpfetch_caller_alloc_secure(); + HTTPFetchResult fetch_result; + HTTPFetchRequest fetch_request; + fetch_request.url = weblink; + fetch_request.caller = caller; + httpfetch_sync(fetch_request, fetch_result); // sync because this is not the main thread + + if (fetch_result.succeeded) { + const std::string start_tag = "' missing in case it's actually something like + unsigned int start = fetch_result.data.find(start_tag); + unsigned int end = fetch_result.data.find(end_tag); + if (start == std::string::npos || end == std::string::npos){ + msg << gettext("Unable to find title tags in webpage!"); + } else { + std::string title = fetch_result.data.substr(start + start_tag.length(), end - start - end_tag.length() + 1); + unsigned int start_end = title.find(">"); // the reason we need to do this is title tags like (like above) + if (start_end == std::string::npos){ start_end = 0; } // this should never happen, but it's better to have the end of a tag somewhere than notthing + title = title.substr(start_end + 1); + msg << gettext("Webpage title:") << " '" << title << "'"; + } + } else { + msg << gettext("Error while getting webpage title!"); } - curl_easy_setopt(curl, CURLOPT_URL, weblink.c_str()); - curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writeHtml); - curl_easy_setopt(curl, CURLOPT_WRITEDATA, &html); - curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); // Important for services like https://bit.ly or https://is.gd - curl_easy_setopt(curl, CURLOPT_TIMEOUT, 10L); // As we don't know if we are stuck in an infinite loop of redirects or if the specifiec server exists at ALL, 10 secs is max! - CURLcode res = curl_easy_perform(curl); - curl_easy_cleanup(curl); - if(res == CURLE_OPERATION_TIMEDOUT || res == CURLE_COULDNT_RESOLVE_HOST) { - msg << gettext("Host does not exist or timeout for 3rd party webpages reached!"); - } else { - if (res != CURLE_OK || html.find("<title>") == std::string::npos || html.find("") == std::string::npos) { - msg << gettext("Unkown error while fetching page title!"); - } - size_t start = html.find("") + 7; // +7 so the html tag isn't in there... - size_t end = html.find(""); - title = html.substr(start, end - start); - msg << gettext("Webpage title:") << " '" << title << "'" ; - } + httpfetch_caller_free(caller); #else msg << gettext("Unable to get webpage title (cURL missing)!"); #endif - m_chat_backend->addUnparsedMessage(utf8_to_wide(msg.str())); + chat_backend->addUnparsedMessage(utf8_to_wide(msg.str())); + } void GUIChatConsole::updatePrimarySelection() { diff --git a/src/gui/guiChatConsole.h b/src/gui/guiChatConsole.h index 343a58ebc538..e32e9d552f27 100644 --- a/src/gui/guiChatConsole.h +++ b/src/gui/guiChatConsole.h @@ -92,7 +92,7 @@ class GUIChatConsole : public gui::IGUIElement bool weblinkClickOpen(s32 col, s32 row); // If a weblink was clicked, this will get the page's title and display it in chat - void weblinkClickTitle(s32 col, s32 row); + void weblinkClickTitle(std::string weblink, ChatBackend* chat_backen); // If the selected text changed, we need to update the (X11) primary selection. void updatePrimarySelection(); From d1ec1ec36dae9aa5ff5ce31ab33f31b845831409 Mon Sep 17 00:00:00 2001 From: chmodsayshello Date: Thu, 10 Aug 2023 16:54:27 +0200 Subject: [PATCH 03/10] fix github build --- src/gui/guiChatConsole.cpp | 4 ++-- src/gui/guiChatConsole.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/gui/guiChatConsole.cpp b/src/gui/guiChatConsole.cpp index 7faf4431f82c..1c2c2a41fbd7 100644 --- a/src/gui/guiChatConsole.cpp +++ b/src/gui/guiChatConsole.cpp @@ -797,7 +797,7 @@ bool GUIChatConsole::weblinkClickOpen(s32 col, s32 row) return false; } -void GUIChatConsole::weblinkClickTitle(std::string weblink, ChatBackend* chat_backend){ +void GUIChatConsole::weblinkClickTitle(const std::string &weblink, ChatBackend* chat_backend){ if (weblink.empty()){ return; } @@ -822,7 +822,7 @@ void GUIChatConsole::weblinkClickTitle(std::string weblink, ChatBackend* chat_ba msg << gettext("Unable to find title tags in webpage!"); } else { std::string title = fetch_result.data.substr(start + start_tag.length(), end - start - end_tag.length() + 1); - unsigned int start_end = title.find(">"); // the reason we need to do this is title tags like (like above) + unsigned int start_end = title.find('>'); // the reason we need to do this is title tags like <title foo="bar"> (like above) if (start_end == std::string::npos){ start_end = 0; } // this should never happen, but it's better to have the end of a tag somewhere than notthing title = title.substr(start_end + 1); msg << gettext("Webpage title:") << " '" << title << "'"; diff --git a/src/gui/guiChatConsole.h b/src/gui/guiChatConsole.h index e32e9d552f27..7eeef7b55151 100644 --- a/src/gui/guiChatConsole.h +++ b/src/gui/guiChatConsole.h @@ -92,7 +92,7 @@ class GUIChatConsole : public gui::IGUIElement bool weblinkClickOpen(s32 col, s32 row); // If a weblink was clicked, this will get the page's title and display it in chat - void weblinkClickTitle(std::string weblink, ChatBackend* chat_backen); + void weblinkClickTitle(const std::string &weblink, ChatBackend* chat_backen); // If the selected text changed, we need to update the (X11) primary selection. void updatePrimarySelection(); From fd80ec84320d388802267f5a68598eea218804bf Mon Sep 17 00:00:00 2001 From: chmodsayshello <chmodsayshello@hotmail.com> Date: Thu, 10 Aug 2023 20:30:10 +0200 Subject: [PATCH 04/10] use regex instead of string.find --- src/gui/guiChatConsole.cpp | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/src/gui/guiChatConsole.cpp b/src/gui/guiChatConsole.cpp index 1c2c2a41fbd7..f895440b72a7 100644 --- a/src/gui/guiChatConsole.cpp +++ b/src/gui/guiChatConsole.cpp @@ -33,9 +33,12 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "util/string.h" #include <string> -#ifdef USE_CURL +#ifdef USE_CURL //specific to the webpage title feature #include "httpfetch.h" #include <thread> // we only need threads when curl is there (as getting a webpage title could freeze the entire client otherwise) +#include <regex> + +#define HTMLTITLEREGEX "<title.*?>(.*?)</title.*?>" #endif inline u32 clamp_u8(s32 value) @@ -806,7 +809,7 @@ void GUIChatConsole::weblinkClickTitle(const std::string &weblink, ChatBackend* msg << " * "; #ifdef USE_CURL - u64 caller = httpfetch_caller_alloc_secure(); + const u64 caller = httpfetch_caller_alloc_secure(); HTTPFetchResult fetch_result; HTTPFetchRequest fetch_request; fetch_request.url = weblink; @@ -814,18 +817,13 @@ void GUIChatConsole::weblinkClickTitle(const std::string &weblink, ChatBackend* httpfetch_sync(fetch_request, fetch_result); // sync because this is not the main thread if (fetch_result.succeeded) { - const std::string start_tag = "<title"; - const std::string end_tag = "</title"; // '>' missing in case it's actually something like - unsigned int start = fetch_result.data.find(start_tag); - unsigned int end = fetch_result.data.find(end_tag); - if (start == std::string::npos || end == std::string::npos){ - msg << gettext("Unable to find title tags in webpage!"); - } else { - std::string title = fetch_result.data.substr(start + start_tag.length(), end - start - end_tag.length() + 1); - unsigned int start_end = title.find('>'); // the reason we need to do this is title tags like (like above) - if (start_end == std::string::npos){ start_end = 0; } // this should never happen, but it's better to have the end of a tag somewhere than notthing - title = title.substr(start_end + 1); + const std::regex r(HTMLTITLEREGEX); + std::smatch matches; + if (std::regex_search(fetch_result.data, matches, r) || !matches.empty()){ + const std::string title = matches.str(1); // pick the first one, what if this is a webpage teaching html and explain the title tag in the CONTENT section... msg << gettext("Webpage title:") << " '" << title << "'"; + } else { + msg << gettext("Unable to get the title from HTML!"); } } else { msg << gettext("Error while getting webpage title!"); From 75ef0b1397ba4f56b98581fde82f49253250b26e Mon Sep 17 00:00:00 2001 From: chmodsayshello <chmodsayshello@hotmail.com> Date: Thu, 10 Aug 2023 20:32:26 +0200 Subject: [PATCH 05/10] remove defined value for regex (hardcoded) --- src/gui/guiChatConsole.cpp | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/gui/guiChatConsole.cpp b/src/gui/guiChatConsole.cpp index f895440b72a7..4d41f5304617 100644 --- a/src/gui/guiChatConsole.cpp +++ b/src/gui/guiChatConsole.cpp @@ -37,8 +37,6 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "httpfetch.h" #include <thread> // we only need threads when curl is there (as getting a webpage title could freeze the entire client otherwise) #include <regex> - -#define HTMLTITLEREGEX "<title.*?>(.*?)</title.*?>" #endif inline u32 clamp_u8(s32 value) @@ -817,7 +815,7 @@ void GUIChatConsole::weblinkClickTitle(const std::string &weblink, ChatBackend* httpfetch_sync(fetch_request, fetch_result); // sync because this is not the main thread if (fetch_result.succeeded) { - const std::regex r(HTMLTITLEREGEX); + const std::regex r("<title.*?>(.*?)</title.*?>"); std::smatch matches; if (std::regex_search(fetch_result.data, matches, r) || !matches.empty()){ const std::string title = matches.str(1); // pick the first one, what if this is a webpage teaching html and explain the title tag in the CONTENT section... @@ -829,9 +827,7 @@ void GUIChatConsole::weblinkClickTitle(const std::string &weblink, ChatBackend* msg << gettext("Error while getting webpage title!"); } - httpfetch_caller_free(caller); - #else msg << gettext("Unable to get webpage title (cURL missing)!"); #endif From 82176e9c6b3c285437cd6edc0d4f9b9bbc55259e Mon Sep 17 00:00:00 2001 From: chmodsayshello <chmodsayshello@hotmail.com> Date: Thu, 10 Aug 2023 20:35:20 +0200 Subject: [PATCH 06/10] free httpfetch caller earlier --- src/gui/guiChatConsole.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gui/guiChatConsole.cpp b/src/gui/guiChatConsole.cpp index 4d41f5304617..8b15474a279b 100644 --- a/src/gui/guiChatConsole.cpp +++ b/src/gui/guiChatConsole.cpp @@ -813,6 +813,8 @@ void GUIChatConsole::weblinkClickTitle(const std::string &weblink, ChatBackend* fetch_request.url = weblink; fetch_request.caller = caller; httpfetch_sync(fetch_request, fetch_result); // sync because this is not the main thread + + httpfetch_caller_free(caller); if (fetch_result.succeeded) { const std::regex r("<title.*?>(.*?)</title.*?>"); @@ -826,8 +828,6 @@ void GUIChatConsole::weblinkClickTitle(const std::string &weblink, ChatBackend* } else { msg << gettext("Error while getting webpage title!"); } - - httpfetch_caller_free(caller); #else msg << gettext("Unable to get webpage title (cURL missing)!"); #endif From d1c6a3028119d8baeafa421f6c93c550a326bf98 Mon Sep 17 00:00:00 2001 From: chmodsayshello <chmodsayshello@hotmail.com> Date: Thu, 10 Aug 2023 20:39:12 +0200 Subject: [PATCH 07/10] adjust error messages --- src/gui/guiChatConsole.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/gui/guiChatConsole.cpp b/src/gui/guiChatConsole.cpp index 8b15474a279b..97e822301c9e 100644 --- a/src/gui/guiChatConsole.cpp +++ b/src/gui/guiChatConsole.cpp @@ -815,7 +815,7 @@ void GUIChatConsole::weblinkClickTitle(const std::string &weblink, ChatBackend* httpfetch_sync(fetch_request, fetch_result); // sync because this is not the main thread httpfetch_caller_free(caller); - + if (fetch_result.succeeded) { const std::regex r("<title.*?>(.*?)</title.*?>"); std::smatch matches; @@ -826,10 +826,10 @@ void GUIChatConsole::weblinkClickTitle(const std::string &weblink, ChatBackend* msg << gettext("Unable to get the title from HTML!"); } } else { - msg << gettext("Error while getting webpage title!"); + msg << gettext("Unable to get HTML from the webpage (contains title)!"); } #else - msg << gettext("Unable to get webpage title (cURL missing)!"); + msg << gettext("Unable to connect to webpage (cURL missing)!"); #endif chat_backend->addUnparsedMessage(utf8_to_wide(msg.str())); From 9d4c3daa9b975931791ad276cc6586a9fa8b8914 Mon Sep 17 00:00:00 2001 From: chmodsayshello <chmodsayshello@hotmail.com> Date: Thu, 10 Aug 2023 21:46:24 +0200 Subject: [PATCH 08/10] filesize limit and actively ask for html --- src/gui/guiChatConsole.cpp | 4 ++++ src/httpfetch.cpp | 1 + src/httpfetch.h | 3 +++ 3 files changed, 8 insertions(+) diff --git a/src/gui/guiChatConsole.cpp b/src/gui/guiChatConsole.cpp index 97e822301c9e..426e11e4ff38 100644 --- a/src/gui/guiChatConsole.cpp +++ b/src/gui/guiChatConsole.cpp @@ -812,6 +812,10 @@ void GUIChatConsole::weblinkClickTitle(const std::string &weblink, ChatBackend* HTTPFetchRequest fetch_request; fetch_request.url = weblink; fetch_request.caller = caller; + fetch_request.max_file_size = 1.5 * 1024 * 1024; // 1.5 megabyte should be more than enoght for HTML! + std::vector<std::string> htmlheader {"Accept: text/html"}; + fetch_request.extra_headers = htmlheader; + httpfetch_sync(fetch_request, fetch_result); // sync because this is not the main thread httpfetch_caller_free(caller); diff --git a/src/httpfetch.cpp b/src/httpfetch.cpp index cb599fbdd74a..37dd639a89a8 100644 --- a/src/httpfetch.cpp +++ b/src/httpfetch.cpp @@ -275,6 +275,7 @@ HTTPFetchOngoing::HTTPFetchOngoing(const HTTPFetchRequest &request_, request.timeout); curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT_MS, request.connect_timeout); + curl_easy_setopt(curl, CURLOPT_MAXFILESIZE , request.max_file_size); if (!request.useragent.empty()) curl_easy_setopt(curl, CURLOPT_USERAGENT, request.useragent.c_str()); diff --git a/src/httpfetch.h b/src/httpfetch.h index a4901e63b71d..dd5351de1cae 100644 --- a/src/httpfetch.h +++ b/src/httpfetch.h @@ -66,6 +66,9 @@ struct HTTPFetchRequest // application/x-www-form-urlencoded. POST-only. bool multipart = false; + // The maximum file size in bytes. Allow any size by default + long max_file_size = -1; + // The Method to use default = GET // Avaible methods GET, POST, PUT, DELETE HttpMethod method = HTTP_GET; From 8591da588548aba3e842f5aee17542f0d04a2543 Mon Sep 17 00:00:00 2001 From: chmodsayshello <chmodsayshello@hotmail.com> Date: Sat, 12 Aug 2023 13:29:38 +0200 Subject: [PATCH 09/10] finalise for review --- src/gui/guiChatConsole.cpp | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/gui/guiChatConsole.cpp b/src/gui/guiChatConsole.cpp index 426e11e4ff38..12bc5921a34d 100644 --- a/src/gui/guiChatConsole.cpp +++ b/src/gui/guiChatConsole.cpp @@ -823,15 +823,13 @@ void GUIChatConsole::weblinkClickTitle(const std::string &weblink, ChatBackend* if (fetch_result.succeeded) { const std::regex r("<title.*?>(.*?)</title.*?>"); std::smatch matches; - if (std::regex_search(fetch_result.data, matches, r) || !matches.empty()){ + if (std::regex_search(fetch_result.data, matches, r) || !matches.empty()) { const std::string title = matches.str(1); // pick the first one, what if this is a webpage teaching html and explain the title tag in the CONTENT section... msg << gettext("Webpage title:") << " '" << title << "'"; } else { - msg << gettext("Unable to get the title from HTML!"); + msg << gettext("Unable to get the title from webpage!"); // Either the HTML document doesn't have a title tag OR the server reponded with another format } - } else { - msg << gettext("Unable to get HTML from the webpage (contains title)!"); - } + } // No need to print some text of it fails here, httpfetch already does that #else msg << gettext("Unable to connect to webpage (cURL missing)!"); #endif From 6927e8c75d52a63ce40f75c1451dde9a6cad5144 Mon Sep 17 00:00:00 2001 From: chmodsayshello <chmodsayshello@hotmail.com> Date: Sun, 13 Aug 2023 14:49:48 +0200 Subject: [PATCH 10/10] remove redundant vector --- src/gui/guiChatConsole.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/gui/guiChatConsole.cpp b/src/gui/guiChatConsole.cpp index 12bc5921a34d..d76891220440 100644 --- a/src/gui/guiChatConsole.cpp +++ b/src/gui/guiChatConsole.cpp @@ -813,8 +813,7 @@ void GUIChatConsole::weblinkClickTitle(const std::string &weblink, ChatBackend* fetch_request.url = weblink; fetch_request.caller = caller; fetch_request.max_file_size = 1.5 * 1024 * 1024; // 1.5 megabyte should be more than enoght for HTML! - std::vector<std::string> htmlheader {"Accept: text/html"}; - fetch_request.extra_headers = htmlheader; + fetch_request.extra_headers = {"Accept: text/html"}; httpfetch_sync(fetch_request, fetch_result); // sync because this is not the main thread