aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Qin <richard.qin.x@gmail.com>2026-04-13 04:34:50 +0800
committerRichard Qin <richard.qin.x@gmail.com>2026-04-13 04:34:50 +0800
commit8449f5fcefc5406f1666257bacb3bb1afda978e1 (patch)
treefe3dc5b34916f69b4aef6795d7f14abc298609e1
parent466e609d1a3c8efa4eea4b0fb4b1aeecd0d0706a (diff)
downloadrwebbrowser-8449f5fcefc5406f1666257bacb3bb1afda978e1.tar.gz
rwebbrowser-8449f5fcefc5406f1666257bacb3bb1afda978e1.tar.xz
feat: implement configurable homepage and user-agent via config.txt
-rw-r--r--include/ricochet/core/browser.hh1
-rw-r--r--src/core/browser.cc15
-rw-r--r--src/main.cc28
-rw-r--r--src/net/http_client.cc61
4 files changed, 77 insertions, 28 deletions
diff --git a/include/ricochet/core/browser.hh b/include/ricochet/core/browser.hh
index a8d2cd3..36e876d 100644
--- a/include/ricochet/core/browser.hh
+++ b/include/ricochet/core/browser.hh
@@ -33,6 +33,7 @@ public:
Browser( Browser&& ) = delete;
Browser& operator=( Browser&& ) = delete;
+ static std::string get_configured_homepage();
static int run( std::string_view initial_url );
};
diff --git a/src/core/browser.cc b/src/core/browser.cc
index dd96c7c..571783a 100644
--- a/src/core/browser.cc
+++ b/src/core/browser.cc
@@ -1003,6 +1003,21 @@ std::vector<std::string> wrap_lines( const std::vector<std::string>& original_li
} // namespace
+std::string Browser::get_configured_homepage()
+{
+ std::ifstream file( get_config_path( "config.txt" ) );
+ if ( file.is_open() ) {
+ std::string line;
+ while ( std::getline( file, line ) ) {
+ const std::size_t eq = line.find( '=' );
+ if ( eq != std::string::npos && line.substr( 0, eq ) == "homepage" ) {
+ return line.substr( eq + 1 );
+ }
+ }
+ }
+ return "https://wikipedia.org";
+}
+
int Browser::run( std::string_view initial_url )
{
std::vector<HttpRequest> history;
diff --git a/src/main.cc b/src/main.cc
index 1037833..562861a 100644
--- a/src/main.cc
+++ b/src/main.cc
@@ -16,6 +16,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
+#include <fstream>
#include <iostream>
#include <span>
#include <string_view>
@@ -41,28 +42,27 @@ int main( int argc, char* argv[] )
ricochet::core::print_license_notice();
+ std::string start_url;
if ( args.size() < 2 ) {
- std::cerr << "Error: No URL provided.\n";
- print_usage( args[0] );
- return 1;
+ start_url = ricochet::core::Browser::get_configured_homepage();
+ } else {
+ start_url = std::string( args[1] );
}
- const std::string_view input = args[1];
-
- if ( input == "show" ) {
- if ( args[2] == "w" ) {
+ if ( args.size() >= 2 && args[1] == "show" ) {
+ if ( args.size() >= 3 && args[2] == "w" ) {
ricochet::core::show_warranty();
- } else if ( args[2] == "c" ) {
+ return 0;
+ }
+ if ( args.size() >= 3 && args[2] == "c" ) {
ricochet::core::show_copying();
- } else {
- std::cerr << "Error: Invalid argument for show command.\n";
- print_usage( args[0] );
- return 1;
+ return 0;
}
- return 0;
+ std::cerr << "Error: Invalid argument for show command.\n";
+ print_usage( args[0] );
+ return 1;
}
- std::string start_url( input );
if ( !start_url.starts_with( "http://" ) && !start_url.starts_with( "https://" ) ) {
start_url.insert( 0, "https://" );
}
diff --git a/src/net/http_client.cc b/src/net/http_client.cc
index 2ed33e3..5f5b449 100644
--- a/src/net/http_client.cc
+++ b/src/net/http_client.cc
@@ -174,6 +174,40 @@ std::string get_config_path( const std::string& filename )
return dir + "/" + filename;
}
+struct BrowserConfig
+{
+ std::string user_agent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) "
+ "Chrome/124.0.0.0 Safari/537.36";
+ std::string homepage = "https://wikipedia.org";
+};
+
+BrowserConfig& get_browser_config()
+{
+ static BrowserConfig config;
+ static bool loaded = false;
+ if ( !loaded ) {
+ std::ifstream file( get_config_path( "config.txt" ) );
+ if ( file.is_open() ) {
+ std::string line;
+ while ( std::getline( file, line ) ) {
+ const std::size_t eq = line.find( '=' );
+ if ( eq == std::string::npos ) {
+ continue;
+ }
+ const std::string key = line.substr( 0, eq );
+ const std::string val = line.substr( eq + 1 );
+ if ( key == "user_agent" ) {
+ config.user_agent = val;
+ } else if ( key == "homepage" ) {
+ config.homepage = val;
+ }
+ }
+ }
+ loaded = true;
+ }
+ return config;
+}
+
using CookieJar = std::unordered_map<std::string, std::unordered_map<std::string, std::string>>;
void load_cookies_from_file( CookieJar& jar )
@@ -290,20 +324,19 @@ FetchResult do_network_request( const std::string& host,
FetchResult res;
try {
const Address server_addr( host, service );
- std::string request
- = std::format( "{} {} HTTP/1.1\r\n"
- "Host: {}\r\n"
- "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) "
- "Chrome/124.0.0.0 Safari/537.36\r\n"
- "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n"
- "Accept-Language: en-US,en;q=0.9\r\n"
- "DNT: 1\r\n"
- "{}"
- "Connection: close\r\n",
- method,
- path,
- host,
- cookie_header );
+ std::string request = std::format( "{} {} HTTP/1.1\r\n"
+ "Host: {}\r\n"
+ "User-Agent: {}\r\n"
+ "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n"
+ "Accept-Language: en-US,en;q=0.9\r\n"
+ "DNT: 1\r\n"
+ "{}"
+ "Connection: close\r\n",
+ method,
+ path,
+ host,
+ get_browser_config().user_agent,
+ cookie_header );
if ( !body.empty() ) {
request += std::format( "Content-Length: {}\r\n"
"Content-Type: application/x-www-form-urlencoded\r\n",