]> git.basschouten.com Git - openhab-addons.git/blob
2dce99ff47d94bbaef12d083820a7ce89be25afd
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2023 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 Gson gson;
45     private final String prefix;
46
47     public RequestLogger(final String prefix, final Gson gson) {
48         this.gson = gson;
49         this.prefix = prefix;
50     }
51
52     private void dump(final Request request, String[] stringsToRemove) {
53         final long idV = nextId.getAndIncrement();
54         if (logger.isDebugEnabled()) {
55             final String id = prefix + "-" + idV;
56             final StringBuilder group = new StringBuilder();
57             request.onRequestBegin(theRequest -> group.append(
58                     String.format("Request %s%n%s > %s %s%n", id, id, theRequest.getMethod(), theRequest.getURI())));
59             request.onRequestHeaders(theRequest -> {
60                 for (final HttpField header : theRequest.getHeaders()) {
61                     group.append(String.format("%s > %s%n", id, header));
62                 }
63             });
64             final StringBuilder contentBuffer = new StringBuilder();
65             request.onRequestContent((theRequest, content) -> contentBuffer
66                     .append(getCharset(theRequest.getHeaders()).decode(content).toString()));
67             request.onRequestSuccess(theRequest -> {
68                 if (contentBuffer.length() > 0) {
69                     group.append("\n");
70                     group.append(reformatJson(contentBuffer.toString()));
71                 }
72                 String dataToLog = group.toString();
73                 scrambleAndLog(stringsToRemove, dataToLog);
74                 contentBuffer.delete(0, contentBuffer.length());
75                 group.delete(0, group.length());
76             });
77             request.onResponseBegin(theResponse -> {
78                 group.append(String.format("Response %s%n%s < %s %s", id, id, theResponse.getVersion(),
79                         theResponse.getStatus()));
80                 if (theResponse.getReason() != null) {
81                     group.append(" ");
82                     group.append(theResponse.getReason());
83                 }
84                 group.append("\n");
85             });
86             request.onResponseHeaders(theResponse -> {
87                 for (final HttpField header : theResponse.getHeaders()) {
88                     group.append(String.format("%s < %s%n", id, header));
89                 }
90             });
91             request.onResponseContent((theResponse, content) -> contentBuffer
92                     .append(getCharset(theResponse.getHeaders()).decode(content).toString()));
93             request.onResponseSuccess(theResponse -> {
94                 if (contentBuffer.length() > 0) {
95                     group.append("\n");
96                     group.append(reformatJson(contentBuffer.toString()));
97                 }
98
99                 String dataToLog = group.toString();
100                 scrambleAndLog(stringsToRemove, dataToLog);
101             });
102         }
103     }
104
105     private void scrambleAndLog(String[] stringsToRemove, String dataToLog) {
106         String modifiedData = dataToLog;
107         for (String stringToRemove : stringsToRemove) {
108             modifiedData = modifiedData.replace(stringToRemove, "<HIDDEN>");
109         }
110         logger.debug("{}", modifiedData);
111     }
112
113     private Charset getCharset(final HttpFields headers) {
114         final String contentType = headers.get(HttpHeader.CONTENT_TYPE);
115         if (contentType == null) {
116             return StandardCharsets.UTF_8;
117         }
118         final String[] tokens = contentType.toLowerCase(Locale.US).split("charset=");
119         if (tokens.length != 2) {
120             return StandardCharsets.UTF_8;
121         }
122
123         final String encoding = tokens[1].replaceAll("[;\"]", "");
124         return Charset.forName(encoding);
125     }
126
127     public Request listenTo(final Request request, String[] stringToRemove) {
128         dump(request, stringToRemove);
129         return request;
130     }
131
132     private String reformatJson(final String jsonString) {
133         try {
134             final JsonElement json = JsonParser.parseString(jsonString);
135             return gson.toJson(json);
136         } catch (final JsonSyntaxException e) {
137             logger.debug("Could not reformat malformed JSON due to '{}'", e.getMessage());
138             return jsonString;
139         }
140     }
141 }