]> git.basschouten.com Git - openhab-addons.git/blob
70cdb8f1b742ee67a6e03c5ef4ba165900237015
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2021 Contributors to the openHAB project
3  *
4  * See the NOTICE file(s) distributed with this work for additional
5  * information.
6  *
7  * This program and the accompanying materials are made available under the
8  * terms of the Eclipse Public License 2.0 which is available at
9  * http://www.eclipse.org/legal/epl-2.0
10  *
11  * SPDX-License-Identifier: EPL-2.0
12  */
13 package org.openhab.binding.sensibo.internal.client;
14
15 import java.nio.charset.Charset;
16 import java.nio.charset.StandardCharsets;
17 import java.util.Locale;
18 import java.util.concurrent.atomic.AtomicLong;
19
20 import org.eclipse.jdt.annotation.NonNullByDefault;
21 import org.eclipse.jetty.client.api.Request;
22 import org.eclipse.jetty.http.HttpField;
23 import org.eclipse.jetty.http.HttpFields;
24 import org.eclipse.jetty.http.HttpHeader;
25 import org.slf4j.Logger;
26 import org.slf4j.LoggerFactory;
27
28 import com.google.gson.Gson;
29 import com.google.gson.JsonElement;
30 import com.google.gson.JsonParser;
31 import com.google.gson.JsonSyntaxException;
32
33 /**
34  * Logs HttpClient request/response traffic.
35  *
36  * @author Gili Tzabari - Initial contribution https://stackoverflow.com/users/14731/gili
37  *         https://stackoverflow.com/questions/50318736/how-to-log-httpclient-requests-response-including-body
38  * @author Arne Seime - adapted for openHAB binding
39  */
40 @NonNullByDefault
41 public final class RequestLogger {
42     private final Logger logger = LoggerFactory.getLogger(RequestLogger.class);
43     private final AtomicLong nextId = new AtomicLong();
44     private final JsonParser parser;
45     private final Gson gson;
46     private final String prefix;
47
48     public RequestLogger(final String prefix, final Gson gson) {
49         parser = new JsonParser();
50         this.gson = gson;
51         this.prefix = prefix;
52     }
53
54     private void dump(final Request request, String[] stringsToRemove) {
55         final long idV = nextId.getAndIncrement();
56         if (logger.isDebugEnabled()) {
57             final String id = prefix + "-" + idV;
58             final StringBuilder group = new StringBuilder();
59             request.onRequestBegin(theRequest -> group.append(
60                     String.format("Request %s%n%s > %s %s%n", id, id, theRequest.getMethod(), theRequest.getURI())));
61             request.onRequestHeaders(theRequest -> {
62                 for (final HttpField header : theRequest.getHeaders()) {
63                     group.append(String.format("%s > %s%n", id, header));
64                 }
65             });
66             final StringBuilder contentBuffer = new StringBuilder();
67             request.onRequestContent((theRequest, content) -> contentBuffer
68                     .append(getCharset(theRequest.getHeaders()).decode(content).toString()));
69             request.onRequestSuccess(theRequest -> {
70                 if (contentBuffer.length() > 0) {
71                     group.append("\n");
72                     group.append(reformatJson(contentBuffer.toString()));
73                 }
74                 String dataToLog = group.toString();
75                 scrambleAndLog(stringsToRemove, dataToLog);
76                 contentBuffer.delete(0, contentBuffer.length());
77                 group.delete(0, group.length());
78             });
79             request.onResponseBegin(theResponse -> {
80                 group.append(String.format("Response %s%n%s < %s %s", id, id, theResponse.getVersion(),
81                         theResponse.getStatus()));
82                 if (theResponse.getReason() != null) {
83                     group.append(" ");
84                     group.append(theResponse.getReason());
85                 }
86                 group.append("\n");
87             });
88             request.onResponseHeaders(theResponse -> {
89                 for (final HttpField header : theResponse.getHeaders()) {
90                     group.append(String.format("%s < %s%n", id, header));
91                 }
92             });
93             request.onResponseContent((theResponse, content) -> contentBuffer
94                     .append(getCharset(theResponse.getHeaders()).decode(content).toString()));
95             request.onResponseSuccess(theResponse -> {
96                 if (contentBuffer.length() > 0) {
97                     group.append("\n");
98                     group.append(reformatJson(contentBuffer.toString()));
99                 }
100
101                 String dataToLog = group.toString();
102                 scrambleAndLog(stringsToRemove, dataToLog);
103             });
104         }
105     }
106
107     private void scrambleAndLog(String[] stringsToRemove, String dataToLog) {
108         String modifiedData = dataToLog;
109         for (String stringToRemove : stringsToRemove) {
110             modifiedData = modifiedData.replace(stringToRemove, "<HIDDEN>");
111         }
112         logger.debug("{}", modifiedData);
113     }
114
115     private Charset getCharset(final HttpFields headers) {
116         final String contentType = headers.get(HttpHeader.CONTENT_TYPE);
117         if (contentType == null) {
118             return StandardCharsets.UTF_8;
119         }
120         final String[] tokens = contentType.toLowerCase(Locale.US).split("charset=");
121         if (tokens.length != 2) {
122             return StandardCharsets.UTF_8;
123         }
124
125         final String encoding = tokens[1].replaceAll("[;\"]", "");
126         return Charset.forName(encoding);
127     }
128
129     public Request listenTo(final Request request, String[] stringToRemove) {
130         dump(request, stringToRemove);
131         return request;
132     }
133
134     private String reformatJson(final String jsonString) {
135         try {
136             final JsonElement json = parser.parse(jsonString);
137             return gson.toJson(json);
138         } catch (final JsonSyntaxException e) {
139             logger.debug("Could not reformat malformed JSON due to '{}'", e.getMessage());
140             return jsonString;
141         }
142     }
143 }