diff --git a/Libraries/LibWebView/Autocomplete.cpp b/Libraries/LibWebView/Autocomplete.cpp index 64c6f1382ab..15180a6007e 100644 --- a/Libraries/LibWebView/Autocomplete.cpp +++ b/Libraries/LibWebView/Autocomplete.cpp @@ -9,8 +9,10 @@ #include #include #include +#include #include #include +#include #include #include @@ -67,7 +69,7 @@ void Autocomplete::query_autocomplete_engine(String query) m_query = move(query); m_request->set_buffered_request_finished_callback( - [this, engine = engine.release_value()](u64, Requests::RequestTimingInfo const&, Optional const& network_error, HTTP::HeaderMap const&, Optional response_code, Optional const& reason_phrase, ReadonlyBytes payload) { + [this, engine = engine.release_value()](u64, Requests::RequestTimingInfo const&, Optional const& network_error, HTTP::HeaderMap const& response_headers, Optional response_code, Optional const& reason_phrase, ReadonlyBytes payload) { Core::deferred_invoke([this]() { m_request.clear(); }); if (network_error.has_value()) { @@ -81,7 +83,9 @@ void Autocomplete::query_autocomplete_engine(String query) return; } - if (auto result = received_autocomplete_respsonse(engine, payload); result.is_error()) { + auto content_type = response_headers.get("Content-Type"sv); + + if (auto result = received_autocomplete_respsonse(engine, content_type, payload); result.is_error()) { warnln("Unable to handle autocomplete response: {}", result.error()); invoke_autocomplete_query_complete({}); } else { @@ -166,9 +170,28 @@ static ErrorOr> parse_yahoo_autocomplete(JsonValue const& json) return results; } -ErrorOr> Autocomplete::received_autocomplete_respsonse(AutocompleteEngine const& engine, StringView response) +ErrorOr> Autocomplete::received_autocomplete_respsonse(AutocompleteEngine const& engine, Optional content_type, StringView response) { - auto json = TRY(JsonValue::from_string(response)); + auto decoder = [&]() -> Optional { + if (!content_type.has_value()) + return {}; + + auto mime_type = Web::MimeSniff::MimeType::parse(*content_type); + if (!mime_type.has_value()) + return {}; + + auto charset = mime_type->parameters().get("charset"sv); + if (!charset.has_value()) + return {}; + + return TextCodec::decoder_for_exact_name(*charset); + }(); + + if (!decoder.has_value()) + decoder = TextCodec::decoder_for_exact_name("UTF-8"sv); + + auto decoded_response = TRY(decoder->to_utf8(response)); + auto json = TRY(JsonValue::from_string(decoded_response)); if (engine.name == "DuckDuckGo") return parse_duckduckgo_autocomplete(json); diff --git a/Libraries/LibWebView/Autocomplete.h b/Libraries/LibWebView/Autocomplete.h index 595c0ddf6b2..408c5ec6904 100644 --- a/Libraries/LibWebView/Autocomplete.h +++ b/Libraries/LibWebView/Autocomplete.h @@ -34,7 +34,7 @@ public: void query_autocomplete_engine(String); private: - static ErrorOr> received_autocomplete_respsonse(AutocompleteEngine const&, StringView response); + static ErrorOr> received_autocomplete_respsonse(AutocompleteEngine const&, Optional content_type, StringView response); void invoke_autocomplete_query_complete(Vector suggestions) const; String m_query; diff --git a/Libraries/LibWebView/CMakeLists.txt b/Libraries/LibWebView/CMakeLists.txt index 8df67c07af1..2c2c764e621 100644 --- a/Libraries/LibWebView/CMakeLists.txt +++ b/Libraries/LibWebView/CMakeLists.txt @@ -81,7 +81,7 @@ set(GENERATED_SOURCES ) serenity_lib(LibWebView webview) -target_link_libraries(LibWebView PRIVATE LibCore LibDevTools LibFileSystem LibGfx LibImageDecoderClient LibIPC LibRequests LibJS LibWeb LibUnicode LibURL LibSyntax) +target_link_libraries(LibWebView PRIVATE LibCore LibDevTools LibFileSystem LibGfx LibImageDecoderClient LibIPC LibRequests LibJS LibWeb LibUnicode LibURL LibSyntax LibTextCodec) if (APPLE) target_link_libraries(LibWebView PRIVATE LibThreading)