0

I am trying to modify some inline css style of one of the micro-services' response (for some reasons, it's difficult to modify the micro-service itself). The original response from the micro-service is a html document. Please note that except the html document itself, the client will send several more requests to server for the script files and image.

<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta content="width=device-width, initial-scale=1" name="viewport">
  <meta content="sample" name="sample">
  <title>sample</title>
  <script src="/webjars/jquery/3.6.0/jquery.min.js"></script>
 </head>
 <body style="padding-top: 142px;">
  <header>...</header>
  <main>
    <img src="/img/logo.png" class="img-fluid rounded" alt="LOGO">
  </main>
  <footer>...</footer>
 </body>
</html>

Let's say I'd like to remove the body style style="padding-top: 142px;" when I get the response. At first, I tried the following method.

@Bean
    public RouteLocator routes(RouteLocatorBuilder builder, ValidUARoutePredicateFactory factory) {
        return builder.routes()
                .route("normal_request_route", r ->
                        r.path("/**")
                                .filters(f -> f.modifyResponseBody(String.class, String.class, ((exchange, content) -> {
                                    List<String> contentTypes = exchange.getResponse()
                                        .getHeaders().getOrDefault(HttpHeaders.CONTENT_TYPE, Collections.emptyList());
                                    boolean modify = false;
                                    for(String contentType: contentTypes){
                                        if(contentType.startsWith(MediaType.TEXT_HTML_VALUE)){
                                            modify = true;
                                        }
                                    }
                                    if(modify){
                                        //parse html document and remove the css
                                        return Mono.just(doc);
                                    }else{
                                        return Mono.just(content);
                                    }
                                })))
                                .uri("https://www.baidu.com/"))
                .build();
    }

I can remove the inline css as expected. However, the image is corrupted. I think it's because the micro-service return byte data of image, the above code convert it to string and then some thing wrong happened. Therefore I change the filter part as following.

.filters(f -> f.modifyResponseBody(byte[].class, byte[].class, ((exchange, content) -> {
                                    List<String> contentTypes = exchange.getResponse()
                                            .getHeaders().getOrDefault(HttpHeaders.CONTENT_TYPE, Collections.emptyList());
                                    boolean modify = false;
                                    for(String contentType: contentTypes){
                                        if(contentType.startsWith(MediaType.TEXT_HTML_VALUE)){
                                            modify = true;
                                        }
                                    }
                                    if(modify){
                                        String original = new String(content, StandardCharsets.UTF_8) 
                                        //parse html document and remove the css, original -> doc
                                        Mono.just(doc.getBytes(StandardCharsets.UTF_8));
                                    }else{
                                        return Mono.just(content);
                                    }
                                })))

It seems I can get the image normally, but the html document String original = new String(content, StandardCharsets.UTF_8) is corrupted. The string original is like which cannot be parsed at all:

c5Cfo"H7��:�����M�xB(�3�0�G�{�q ����ph�5:�* t�a��u�� ������/mH���Ʊ��Jv���.��\kV�[ ZR�eCl�t�ٺ���ۯ�z�A���3�J�� ��&,Ŷ:�eq�:���A��@[,���Xi��Y�p��dG�����Doh��a��k��;�A���D!��VD;K�$��4w�7&{��K�Kv�cm4Va��P��гQk)���♮�Í��u����&6F1�`Bo=/ؙ��@�DG ��b/�m���5��Z���!�;�)��+'l�s�b�k#��g 7��n1�������M0��`FU���~���حb��CM�oD�N�9M��W�UeТ͜��36�RM%�Q>N�����Ks\Dz.6ׯ�xK��n��nh�zQ�$J�[[�O��n4��B��pgx����/�efU����n����F܃�E`�ZUYYYY�.�k {�� .M��Bk�2;�e��h�x<+n�!%�m����?0Zo��hn/{�S��!ˢ�8i$R��B�{�� �o�]�����T�'�Ws��^�o#&�R:����3◽�1R���LC]v{������}\(�9��.q40?��.chbZ�\���,<� �2x*�3��DV~�_�'�@������V���n�C�=�r�XA !��d'�7�Ӂ2�0a�<�rN��v%=�qlx� ��!ii:�f���8�Z F�H�V3�(��r� v����k� �v*w(j���>�)���!�v���3�If�������d��F�S�,&�#�d���,e�wd�Y�Bg�G?~�% iM�.�)'s)��{$�3=�d5�c�r&`��c �>�/d�Z��x?Y�j���5��c��6��6�7��S �]��|�F:�e�t��=�A0�ʙ��=I�0����|�������µxo)�k����]�}�_QNk�Z$�$2�o�.�����d��݀���.$٩f� ��r�Ӥ;/�۔%��d[�q,���� !��������<���|~�B��t�NU?���ͥ���c9�ۢM��q�������z���9G�M�8�x�f�FpZ�1* g�v����&� ����io���A���������;����7��n�Ѩ�7��{�j��l�{2`0�[���7��G�~i��і��;�h��T��z�MU�-9����ؿ�7�t��^��Ұ���XmL ���N��<� *r`f�c��u�L�^EË�I�@Y�� l�2���ˆVz"���b��~�YMOʴ��2���L+v�����M����I<�B����o艏n#J������p ��3��@� ղ+bz�3�Fz>��5Tg�-=?�$�����?)i�g%����M<�71����IO�4�s��֣ni*VOY���]ۼ��^o�Ө3z�Ӊ��r�>̜�E�m�־��r�3H��֖�X?�<ͼ�$NU���!s�a�
<�T�j�Ӻ}J�E���yZ�X1��i���`-��m�6�h�N��le��Rz��vn ��x�vv DT'�%�[���~��'u�K��Ҵ���/m�KG�K<�YIʫHp�?��ŜȊ������d%�%���5Y��lJ�'��u�l�E����#��e�aGd�f ��H����A�GF
...

Why did this happen and how to solve it? I tried to write my own filter referring to the method here, but I got similar result. The SCG version is <spring-cloud-gateway.version>3.1.4</spring-cloud-gateway.version>

sincosmos
  • 370
  • 2
  • 7
  • 15
  • I studied the source code of `ModifyResponseBodyGatewayFilterFactory`, it seems the corrupted string is caused by `String original = new String(content, StandardCharsets.UTF_8) `. The content is gzipped, so I need to decode it firstly. – sincosmos Feb 08 '23 at 07:19

0 Answers0