This is an automated email from the ASF dual-hosted git repository. bcall pushed a commit to branch webp_to_jpeg in repository https://gitbox.apache.org/repos/asf/trafficserver.git
The following commit(s) were added to refs/heads/webp_to_jpeg by this push: new 792d267 Revert back to original encoding when conversion fails (#7997) 792d267 is described below commit 792d2675d2c18dd6cae54537c56f903b4bf745c5 Author: constreference <75616549+constrefere...@users.noreply.github.com> AuthorDate: Mon Jun 28 21:44:47 2021 +0530 Revert back to original encoding when conversion fails (#7997) --- .../experimental/webp_transform/ImageTransform.cc | 63 ++++++++++++++-------- 1 file changed, 42 insertions(+), 21 deletions(-) diff --git a/plugins/experimental/webp_transform/ImageTransform.cc b/plugins/experimental/webp_transform/ImageTransform.cc index a14b9bc..1c37045 100644 --- a/plugins/experimental/webp_transform/ImageTransform.cc +++ b/plugins/experimental/webp_transform/ImageTransform.cc @@ -36,7 +36,7 @@ namespace { GlobalPlugin *plugin; -enum class TransformImageType { webp, jpeg }; +enum class ImageEncoding { webp, jpeg, png, unknown }; bool config_convert_to_webp = false; bool config_convert_to_jpeg = false; @@ -48,8 +48,8 @@ Stat stat_convert_to_jpeg; class ImageTransform : public TransformationPlugin { public: - ImageTransform(Transaction &transaction, TransformImageType image_type) - : TransformationPlugin(transaction, TransformationPlugin::RESPONSE_TRANSFORMATION), _image_type(image_type) + ImageTransform(Transaction &transaction, ImageEncoding input_image_type, ImageEncoding transform_image_type) + : TransformationPlugin(transaction, TransformationPlugin::RESPONSE_TRANSFORMATION), _input_image_type(input_image_type), _transform_image_type(transform_image_type) { TransformationPlugin::registerHook(HOOK_READ_RESPONSE_HEADERS); } @@ -57,12 +57,16 @@ public: void handleReadResponseHeaders(Transaction &transaction) override { - if (_image_type == TransformImageType::webp) { + if (_transform_image_type == ImageEncoding::webp) { transaction.getServerResponse().getHeaders()["Content-Type"] = "image/webp"; - } else { + } + if (_transform_image_type == ImageEncoding::jpeg) { transaction.getServerResponse().getHeaders()["Content-Type"] = "image/jpeg"; } - transaction.getServerResponse().getHeaders()["Vary"] = "Accpet"; // to have a separate cache entry + if (_transform_image_type == ImageEncoding::png) { + transaction.getServerResponse().getHeaders()["Content-Type"] = "image/png"; + } + transaction.getServerResponse().getHeaders()["Vary"] = "Accept"; // to have a separate cache entry TS_DEBUG(TAG, "url %s", transaction.getServerRequest().getUrl().getUrlString().c_str()); transaction.resume(); @@ -85,13 +89,13 @@ public: image.read(input_blob); Blob output_blob; - if (_image_type == TransformImageType::webp) { + if (_transform_image_type == ImageEncoding::webp) { stat_convert_to_webp.increment(1); TSDebug(TAG, "Transforming jpeg or png to webp"); image.magick("WEBP"); } else { stat_convert_to_jpeg.increment(1); - TSDebug(TAG, "Transforming wepb to jpeg"); + TSDebug(TAG, "Transforming webp to jpeg"); image.magick("JPEG"); } image.write(&output_blob); @@ -99,10 +103,12 @@ public: } catch (Magick::Warning &warning) { TSError("ImageMagick++ warning: %s", warning.what()); produce(std::string_view(reinterpret_cast<const char *>(input_blob.data()), input_blob.length())); + _transform_image_type = _input_image_type; // Revert to original encoding on error } catch (Magick::Error &error) { - TSError("ImageMagick++ error: %s _image_type: %d input_data.length(): %zd", error.what(), (int)_image_type, + TSError("ImageMagick++ error: %s _image_type: %d input_data.length(): %zd", error.what(), (int)_transform_image_type, input_data.length()); produce(std::string_view(reinterpret_cast<const char *>(input_blob.data()), input_blob.length())); + _transform_image_type = _input_image_type; // Revert to original encoding on error } setOutputComplete(); @@ -112,7 +118,8 @@ public: private: std::stringstream _img; - TransformImageType _image_type; + ImageEncoding _input_image_type; + ImageEncoding _transform_image_type; }; class GlobalHookPlugin : public GlobalPlugin @@ -122,37 +129,51 @@ public: void handleReadResponseHeaders(Transaction &transaction) override { + + // This variable stores the incoming image type + ImageEncoding input_image_type = ImageEncoding::unknown; + // This method tries to optimize the amount of string searching at the expense of double checking some of the booleans std::string ctype = transaction.getServerResponse().getHeaders().values("Content-Type"); - + // Test to if in this transaction we might want to convert jpeg or png to webp - bool transaction_convert_to_wepb = false; + bool transaction_convert_to_webp = false; if (config_convert_to_webp == true) { - transaction_convert_to_wepb = ctype.find("image/jpeg") != std::string::npos || ctype.find("image/png") != std::string::npos; + if (ctype.find("image/jpeg") != std::string::npos) { + input_image_type = ImageEncoding::jpeg; + transaction_convert_to_webp = true; + } + if (ctype.find("image/png") != std::string::npos) { + input_image_type = ImageEncoding::png; + transaction_convert_to_webp = true; + } } // Test to if in this transaction we might want to convert webp to jpeg bool transaction_convert_to_jpeg = false; - if (config_convert_to_jpeg == true && transaction_convert_to_wepb == false) { + if (config_convert_to_jpeg == true && transaction_convert_to_webp == false) { transaction_convert_to_jpeg = ctype.find("image/webp") != std::string::npos; + if (transaction_convert_to_jpeg) { + input_image_type = ImageEncoding::webp; + } } - TSDebug(TAG, "User-Agent: %s transaction_convert_to_wepb: %d transaction_convert_to_jpeg: %d", ctype.c_str(), - transaction_convert_to_wepb, transaction_convert_to_jpeg); + TSDebug(TAG, "User-Agent: %s transaction_convert_to_webp: %d transaction_convert_to_jpeg: %d", ctype.c_str(), + transaction_convert_to_webp, transaction_convert_to_jpeg); // If we might need to convert check to see if what the browser supports - if (transaction_convert_to_wepb == true || transaction_convert_to_jpeg == true) { + if (transaction_convert_to_webp == true || transaction_convert_to_jpeg == true) { std::string accept = transaction.getServerRequest().getHeaders().values("Accept"); bool webp_supported = accept.find("image/webp") != std::string::npos; TSDebug(TAG, "Accept: %s webp_suppported: %d", accept.c_str(), webp_supported); - if (webp_supported == true && transaction_convert_to_wepb == true) { + if (webp_supported == true && transaction_convert_to_webp == true) { TSDebug(TAG, "Content type is either jpeg or png. Converting to webp"); - transaction.addPlugin(new ImageTransform(transaction, TransformImageType::webp)); + transaction.addPlugin(new ImageTransform(transaction, input_image_type, ImageEncoding::webp)); } else if (webp_supported == false && transaction_convert_to_jpeg == true) { TSDebug(TAG, "Content type is webp. Converting to jpeg"); - transaction.addPlugin(new ImageTransform(transaction, TransformImageType::jpeg)); + transaction.addPlugin(new ImageTransform(transaction, input_image_type, ImageEncoding::jpeg)); } else { TSDebug(TAG, "Nothing to convert"); } @@ -172,7 +193,7 @@ TSPluginInit(int argc, const char *argv[]) if (argc >= 2) { std::string option(argv[1]); if (option.find("convert_to_webp") != std::string::npos) { - TSDebug(TAG, "Configured to convert to wepb"); + TSDebug(TAG, "Configured to convert to webp"); config_convert_to_webp = true; } if (option.find("convert_to_jpeg") != std::string::npos) {