diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/core/browser.cc | 49 | ||||
| -rw-r--r-- | src/net/http_client.cc | 23 |
2 files changed, 58 insertions, 14 deletions
diff --git a/src/core/browser.cc b/src/core/browser.cc index 57ed496..e9f1fce 100644 --- a/src/core/browser.cc +++ b/src/core/browser.cc @@ -191,7 +191,11 @@ PageData load_page( const HttpRequest& req ) const net::HttpClient client; auto response_result = client.fetch( req.url, req.method, req.body ); if ( !response_result.has_value() ) { - return { .lines = { "[!] Failed to load: " + req.url }, .links = {}, .inputs = {}, .title = "Error" }; + return { .lines + = { "\033[1;31m[!] Failed to load:\033[0m " + req.url, "", "Reason: " + response_result.error() }, + .links = {}, + .inputs = {}, + .title = "Error" }; } const auto& resp = response_result.value(); @@ -223,6 +227,41 @@ PageData load_page( const HttpRequest& req ) .lines = split_into_lines( result.text ), .links = result.links, .inputs = result.inputs, .title = title }; } +// --- 🔪 智能底部排版:优先截断 URL,誓死保卫快捷键 --- +std::string build_footer( std::string_view url, std::size_t width ) +{ + const std::string_view keys = " | [j/k]Scroll [/]Nav [f]Link [i]In [r]Ref [H/L]Hist [b/B]Mark [q]Quit "; + const std::string_view prefix = " URL: "; + + std::string footer; + if ( width <= keys.length() + prefix.length() + 3 ) { + footer.reserve( prefix.length() + url.length() + keys.length() ); + footer += prefix; + footer += url; + footer += keys; + if ( footer.length() > width && width > 3 ) { + footer.erase( width - 3 ); + footer += "..."; + } + } else { + const std::size_t max_url_len = width - keys.length() - prefix.length(); + footer.reserve( width ); + footer += prefix; + if ( url.length() > max_url_len ) { + footer += url.substr( 0, max_url_len - 3 ); + footer += "..."; + } else { + footer += url; + } + footer += keys; + } + + if ( footer.length() < width ) { + footer.append( width - footer.length(), ' ' ); + } + return footer; +} + void draw_view( const tui::Terminal& terminal, const std::vector<std::string>& lines, std::size_t scroll_y, @@ -262,13 +301,7 @@ void draw_view( const tui::Terminal& terminal, } } - std::string footer - = " URL: " + std::string( url ) + " | [j/k]Scroll [/]Jump [f]Follow [i]Input [b]Mark [B]Marks [q]Quit "; - if ( footer.size() < width ) { - footer.append( width - footer.size(), ' ' ); - } else if ( footer.size() > width && width > 3 ) { - footer = footer.substr( 0, width - 3 ) + "..."; - } + const std::string footer = build_footer( url, width ); std::cout << "\033[7m" << footer << "\033[0m"; std::cout.flush(); } diff --git a/src/net/http_client.cc b/src/net/http_client.cc index 7372247..bbc5d17 100644 --- a/src/net/http_client.cc +++ b/src/net/http_client.cc @@ -308,13 +308,15 @@ std::expected<HttpResponse, std::string> HttpClient::fetch( std::string_view url return std::unexpected( net_res.error ); } const std::string& raw_response = net_res.raw_response; - update_cookies( raw_response ); HttpResponse response; const auto header_end = raw_response.find( "\r\n\r\n" ); + const std::string headers + = ( header_end != std::string::npos ) ? raw_response.substr( 0, header_end ) : raw_response; + update_cookies( headers ); + if ( header_end != std::string::npos ) { response.body = raw_response.substr( header_end + 4 ); - const std::string headers = raw_response.substr( 0, header_end ); std::size_t ct_pos = headers.find( "Content-Type: " ); if ( ct_pos == std::string::npos ) { ct_pos = headers.find( "content-type: " ); @@ -339,7 +341,7 @@ std::expected<HttpResponse, std::string> HttpClient::fetch( std::string_view url } if ( response.status_code >= 300 && response.status_code < 400 ) { - const std::string next_url = extract_redirect_url( raw_response, is_https, host ); + const std::string next_url = extract_redirect_url( headers, is_https, host ); if ( !next_url.empty() ) { current_url = next_url; if ( response.status_code == 301 || response.status_code == 302 || response.status_code == 303 ) { @@ -353,9 +355,18 @@ std::expected<HttpResponse, std::string> HttpClient::fetch( std::string_view url if ( raw_response.contains( "Transfer-Encoding: chunked" ) ) { response.body = dechunk( response.body ); } - response.body = remove_html_comments( response.body ); - response.body = remove_tag_blocks( response.body, "script" ); - response.body = remove_tag_blocks( response.body, "style" ); + std::string ct_lower = response.content_type; + for ( char& c : ct_lower ) { + if ( c >= 'A' && c <= 'Z' ) { + c = static_cast<char>( c + 32 ); + } + } + + if ( ct_lower.starts_with( "text/" ) || ct_lower.contains( "xml" ) ) { + response.body = remove_html_comments( response.body ); + response.body = remove_tag_blocks( response.body, "script" ); + response.body = remove_tag_blocks( response.body, "style" ); + } return response; } |
