View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.eclipse.aether.transport.http.RFC9457;
20  
21  import java.io.IOException;
22  import java.nio.charset.StandardCharsets;
23  
24  import org.apache.http.Header;
25  import org.apache.http.HttpHeaders;
26  import org.apache.http.client.methods.CloseableHttpResponse;
27  import org.apache.http.util.EntityUtils;
28  
29  public class RFC9457Reporter {
30      public static final RFC9457Reporter INSTANCE = new RFC9457Reporter();
31  
32      public boolean isRFC9457Message(CloseableHttpResponse response) {
33          Header[] headers = response.getHeaders(HttpHeaders.CONTENT_TYPE);
34          if (headers.length > 0) {
35              String contentType = headers[0].getValue();
36              return hasRFC9457ContentType(contentType);
37          }
38          return false;
39      }
40  
41      public void generateException(CloseableHttpResponse response) throws HttpRFC9457Exception {
42          int statusCode = getStatusCode(response);
43          String reasonPhrase = getReasonPhrase(response);
44  
45          String body;
46          try {
47              body = getBody(response);
48          } catch (IOException ignore) {
49              // No body found but it is representing a RFC 9457 message due to the content type.
50              throw new HttpRFC9457Exception(statusCode, reasonPhrase, RFC9457Payload.INSTANCE);
51          }
52  
53          if (body != null && !body.isEmpty()) {
54              RFC9457Payload rfc9457Payload = RFC9457Parser.parse(body);
55              throw new HttpRFC9457Exception(statusCode, reasonPhrase, rfc9457Payload);
56          }
57          throw new HttpRFC9457Exception(statusCode, reasonPhrase, RFC9457Payload.INSTANCE);
58      }
59  
60      private String getBody(final CloseableHttpResponse response) throws IOException {
61          return EntityUtils.toString(response.getEntity(), StandardCharsets.UTF_8);
62      }
63  
64      private int getStatusCode(final CloseableHttpResponse response) {
65          return response.getStatusLine().getStatusCode();
66      }
67  
68      private String getReasonPhrase(final CloseableHttpResponse response) {
69          String reasonPhrase = response.getStatusLine().getReasonPhrase();
70          if (reasonPhrase == null || reasonPhrase.isEmpty()) {
71              return "";
72          }
73          int statusCode = getStatusCode(response);
74          return reasonPhrase + " (" + statusCode + ")";
75      }
76  
77      private boolean hasRFC9457ContentType(String contentType) {
78          return "application/problem+json".equals(contentType);
79      }
80  }