1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.syncope.sra.filters;
20
21 import java.io.IOException;
22 import java.io.InputStream;
23 import java.nio.charset.Charset;
24 import java.nio.charset.StandardCharsets;
25 import org.apache.commons.lang3.BooleanUtils;
26 import org.apache.commons.lang3.StringUtils;
27 import org.jsoup.Jsoup;
28 import org.jsoup.nodes.Document;
29 import org.springframework.http.server.reactive.ServerHttpResponseDecorator;
30 import org.springframework.web.server.ServerWebExchange;
31
32 public class LinkRewriteGatewayFilterFactory extends ModifyResponseGatewayFilterFactory {
33
34 @Override
35 protected boolean skipCond(final ServerHttpResponseDecorator decorator) {
36 return decorator.getHeaders().getContentType() == null
37 || !StringUtils.containsIgnoreCase(decorator.getHeaders().getContentType().toString(), "html");
38 }
39
40 private Charset getCharset(final ServerHttpResponseDecorator decorator) {
41 return decorator.getHeaders().getContentType() != null
42 && decorator.getHeaders().getContentType().getCharset() != null
43 ? decorator.getHeaders().getContentType().getCharset()
44 : StandardCharsets.UTF_8;
45 }
46
47 private void replace(final Document doc, final String element, final String attr, final String prefix) {
48 doc.select(element).forEach(link -> {
49 String attrValue = link.attributes().get(attr);
50 if (attrValue.startsWith("/") && !attrValue.startsWith("//")) {
51 link.attr(attr, attrValue.replace(attrValue, prefix + attrValue));
52 }
53 });
54 }
55
56 @Override
57 protected byte[] modifyResponse(
58 final InputStream responseBody,
59 final Config config,
60 final ServerHttpResponseDecorator decorator,
61 final ServerWebExchange exchange)
62 throws IOException {
63
64 String[] keyValue = config.getData().split(",");
65
66 String oldBase = StringUtils.appendIfMissing(keyValue[0], "/");
67 String newBase = StringUtils.appendIfMissing(keyValue[1], "/");
68 String newBaseAsPrefix = StringUtils.removeEnd(keyValue[1], "/");
69
70 boolean rewriterRootAttrs = true;
71 if (keyValue.length == 3) {
72 rewriterRootAttrs = BooleanUtils.toBoolean(keyValue[2]);
73 }
74
75 Document doc = Jsoup.parse(
76 responseBody, getCharset(decorator).name(), exchange.getRequest().getURI().toASCIIString());
77
78 if (rewriterRootAttrs) {
79 replace(doc, "a", "href", newBaseAsPrefix);
80 replace(doc, "link", "href", newBaseAsPrefix);
81 replace(doc, "img", "src", newBaseAsPrefix);
82 replace(doc, "script", "src", newBaseAsPrefix);
83 replace(doc, "object", "data", newBaseAsPrefix);
84 }
85
86 return doc.toString().replace(oldBase, newBase).getBytes();
87 }
88 }