View Javadoc
1   /*
2    * ====================================================================
3    * Licensed to the Apache Software Foundation (ASF) under one
4    * or more contributor license agreements.  See the NOTICE file
5    * distributed with this work for additional information
6    * regarding copyright ownership.  The ASF licenses this file
7    * to you under the Apache License, Version 2.0 (the
8    * "License"); you may not use this file except in compliance
9    * with the License.  You may obtain a copy of the License at
10   *
11   *   http://www.apache.org/licenses/LICENSE-2.0
12   *
13   * Unless required by applicable law or agreed to in writing,
14   * software distributed under the License is distributed on an
15   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16   * KIND, either express or implied.  See the License for the
17   * specific language governing permissions and limitations
18   * under the License.
19   * ====================================================================
20   *
21   * This software consists of voluntary contributions made by many
22   * individuals on behalf of the Apache Software Foundation.  For more
23   * information on the Apache Software Foundation, please see
24   * <http://www.apache.org/>.
25   *
26   */
27  
28  package org.apache.hc.core5.testing.classic;
29  
30  import java.io.IOException;
31  import java.net.Socket;
32  import java.nio.charset.CharsetDecoder;
33  import java.nio.charset.CharsetEncoder;
34  import java.util.concurrent.atomic.AtomicLong;
35  
36  import org.apache.hc.core5.http.ClassicHttpRequest;
37  import org.apache.hc.core5.http.ClassicHttpResponse;
38  import org.apache.hc.core5.http.ContentLengthStrategy;
39  import org.apache.hc.core5.http.Header;
40  import org.apache.hc.core5.http.config.Http1Config;
41  import org.apache.hc.core5.http.impl.io.DefaultBHttpServerConnection;
42  import org.apache.hc.core5.http.impl.io.SocketHolder;
43  import org.apache.hc.core5.http.io.HttpMessageParserFactory;
44  import org.apache.hc.core5.http.io.HttpMessageWriterFactory;
45  import org.apache.hc.core5.http.message.RequestLine;
46  import org.apache.hc.core5.http.message.StatusLine;
47  import org.apache.hc.core5.io.CloseMode;
48  import org.apache.hc.core5.util.Identifiable;
49  import org.slf4j.LoggerFactory;
50  import org.slf4j.Logger;
51  public class LoggingBHttpServerConnection extends DefaultBHttpServerConnection implements Identifiable {
52  
53      private static final AtomicLong COUNT = new AtomicLong();
54  
55      private final String id;
56      private final Logger log;
57      private final Logger headerLog;
58      private final Wire wire;
59  
60      public LoggingBHttpServerConnection(
61              final String scheme,
62              final Http1Config http1Config,
63              final CharsetDecoder charDecoder,
64              final CharsetEncoder charEncoder,
65              final ContentLengthStrategy incomingContentStrategy,
66              final ContentLengthStrategy outgoingContentStrategy,
67              final HttpMessageParserFactory<ClassicHttpRequest> requestParserFactory,
68              final HttpMessageWriterFactory<ClassicHttpResponse> responseWriterFactory) {
69          super(scheme, http1Config, charDecoder, charEncoder,
70                  incomingContentStrategy, outgoingContentStrategy,
71                  requestParserFactory, responseWriterFactory);
72          this.id = "http-incoming-" + COUNT.incrementAndGet();
73          this.log = LoggerFactory.getLogger(getClass());
74          this.headerLog = LoggerFactory.getLogger("org.apache.hc.core5.http.headers");
75          this.wire = new Wire(LoggerFactory.getLogger("org.apache.hc.core5.http.wire"), this.id);
76      }
77  
78      @Override
79      public String getId() {
80          return id;
81      }
82  
83      public LoggingBHttpServerConnection(final String scheme, final Http1Config http1Config) {
84          this(scheme, http1Config, null, null, null, null, null, null);
85      }
86  
87      @Override
88      public void close() throws IOException {
89          if (this.log.isDebugEnabled()) {
90              this.log.debug("{}: Close connection", this.id);
91          }
92          super.close();
93      }
94  
95      @Override
96      public void close(final CloseMode closeMode) {
97          if (this.log.isDebugEnabled()) {
98              this.log.debug("{}: Shutdown connection", this.id);
99          }
100         super.close(closeMode);
101     }
102 
103     @Override
104     public void bind(final Socket socket) throws IOException {
105         super.bind(this.wire.isEnabled() ? new LoggingSocketHolder(socket, wire) : new SocketHolder(socket));
106     }
107 
108     @Override
109     protected void onRequestReceived(final ClassicHttpRequest request) {
110         if (request != null && this.headerLog.isDebugEnabled()) {
111             this.headerLog.debug("{} >> {}", id, new RequestLine(request));
112             final Header[] headers = request.getHeaders();
113             for (final Header header : headers) {
114                 this.headerLog.debug("{} >> {}", this.id, header);
115             }
116         }
117     }
118 
119     @Override
120     protected void onResponseSubmitted(final ClassicHttpResponse response) {
121         if (response != null && this.headerLog.isDebugEnabled()) {
122             this.headerLog.debug("{} << {}", this.id, new StatusLine(response));
123             final Header[] headers = response.getHeaders();
124             for (final Header header : headers) {
125                 this.headerLog.debug("{} << {}", this.id, header);
126             }
127         }
128     }
129 
130 }