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.apache.syncope.core.rest.cxf.batch;
20  
21  import java.io.ByteArrayInputStream;
22  import java.io.IOException;
23  import java.nio.charset.StandardCharsets;
24  import java.util.Collections;
25  import java.util.Enumeration;
26  import java.util.HashSet;
27  import java.util.List;
28  import java.util.Optional;
29  import java.util.Set;
30  import java.util.stream.Collectors;
31  import javax.servlet.ReadListener;
32  import javax.servlet.ServletInputStream;
33  import javax.servlet.http.HttpServletRequest;
34  import javax.servlet.http.HttpServletRequestWrapper;
35  import javax.ws.rs.core.HttpHeaders;
36  import org.apache.commons.lang3.StringUtils;
37  import org.apache.commons.lang3.math.NumberUtils;
38  import org.apache.syncope.common.rest.api.batch.BatchRequestItem;
39  import org.slf4j.Logger;
40  import org.slf4j.LoggerFactory;
41  import org.springframework.http.MediaType;
42  
43  public class BatchItemRequest extends HttpServletRequestWrapper {
44  
45      private static final Logger LOG = LoggerFactory.getLogger(BatchItemRequest.class);
46  
47      private final String basePath;
48  
49      private final BatchRequestItem batchItem;
50  
51      private final ServletInputStream inputStream;
52  
53      public BatchItemRequest(
54              final String basePath,
55              final HttpServletRequest request,
56              final BatchRequestItem batchItem) {
57  
58          super(request);
59          this.basePath = basePath;
60          this.batchItem = batchItem;
61          this.inputStream = new ServletInputStream() {
62  
63              private final ByteArrayInputStream bais = new ByteArrayInputStream(batchItem.getContent().getBytes());
64  
65              private boolean isFinished = false;
66  
67              private boolean isReady = true;
68  
69              @Override
70              public boolean isFinished() {
71                  return isFinished;
72              }
73  
74              @Override
75              public boolean isReady() {
76                  return isReady;
77              }
78  
79              @Override
80              public void setReadListener(final ReadListener readListener) {
81                  // nope
82              }
83  
84              @Override
85              public int read() {
86                  isFinished = true;
87                  isReady = false;
88                  return bais.read();
89              }
90          };
91      }
92  
93      @Override
94      public String getMethod() {
95          return batchItem.getMethod();
96      }
97  
98      @Override
99      public String getServerName() {
100         try {
101             return super.getServerName();
102         } catch (Exception e) {
103             LOG.debug("While delegating to wrapped request", e);
104             return Optional.ofNullable(getHeader(HttpHeaders.HOST)).
105                     map(host -> StringUtils.substringBefore(host, ":")).orElse(null);
106         }
107     }
108 
109     @Override
110     public int getServerPort() {
111         try {
112             return super.getServerPort();
113         } catch (Exception e) {
114             LOG.debug("While delegating to wrapped request", e);
115             return Optional.ofNullable(getHeader(HttpHeaders.HOST)).
116                     map(host -> NumberUtils.toInt(StringUtils.substringAfter(host, ":"))).orElse(0);
117         }
118     }
119 
120     @Override
121     public StringBuffer getRequestURL() {
122         return new StringBuffer(basePath).append(getRequestURI());
123     }
124 
125     @Override
126     public String getRequestURI() {
127         return batchItem.getRequestURI();
128     }
129 
130     @Override
131     public String getQueryString() {
132         return batchItem.getQueryString();
133     }
134 
135     @Override
136     public String getContentType() {
137         return batchItem.getHeaders().containsKey(HttpHeaders.CONTENT_TYPE)
138                 ? batchItem.getHeaders().get(HttpHeaders.CONTENT_TYPE).get(0).toString()
139                 : MediaType.ALL_VALUE;
140     }
141 
142     @Override
143     public int getContentLength() {
144         int contentLength = 0;
145         if (batchItem.getHeaders().containsKey(HttpHeaders.CONTENT_LENGTH)) {
146             try {
147                 contentLength = Integer.valueOf(
148                         batchItem.getHeaders().get(HttpHeaders.CONTENT_LENGTH).get(0).toString());
149             } catch (NumberFormatException e) {
150                 LOG.error("Invalid value found for {}: {}",
151                         HttpHeaders.CONTENT_LENGTH, batchItem.getHeaders().get(HttpHeaders.CONTENT_LENGTH), e);
152             }
153         }
154         return contentLength;
155     }
156 
157     @Override
158     public long getContentLengthLong() {
159         return getContentLength();
160     }
161 
162     @Override
163     public String getHeader(final String name) {
164         try {
165             return batchItem.getHeaders().containsKey(name)
166                     ? batchItem.getHeaders().get(name).get(0).toString()
167                     : HttpHeaders.CONTENT_TYPE.equals(name) || HttpHeaders.ACCEPT.equals(name)
168                     ? MediaType.ALL_VALUE
169                     : super.getHeader(name);
170         } catch (Exception e) {
171             LOG.debug("While delegating to wrapped request", e);
172             return null;
173         }
174     }
175 
176     @Override
177     public Enumeration<String> getHeaders(final String name) {
178         try {
179             return batchItem.getHeaders().containsKey(name)
180                     ? Collections.enumeration(batchItem.getHeaders().get(name).stream().
181                             map(Object::toString).collect(Collectors.toList()))
182                     : HttpHeaders.CONTENT_TYPE.equals(name) || HttpHeaders.ACCEPT.equals(name)
183                     ? Collections.enumeration(List.of(MediaType.ALL_VALUE))
184                     : super.getHeaders(name);
185         } catch (Exception e) {
186             LOG.debug("While delegating to wrapped request", e);
187             return Collections.emptyEnumeration();
188         }
189     }
190 
191     @Override
192     public Enumeration<String> getHeaderNames() {
193         try {
194             return super.getHeaderNames();
195         } catch (Exception e) {
196             LOG.debug("While delegating to wrapped request", e);
197 
198             Set<String> names = new HashSet<>(batchItem.getHeaders().keySet());
199             names.add(HttpHeaders.CONTENT_TYPE);
200             names.add(HttpHeaders.ACCEPT);
201             return Collections.enumeration(names);
202         }
203     }
204 
205     @Override
206     public Object getAttribute(final String name) {
207         try {
208             return super.getAttribute(name);
209         } catch (Exception e) {
210             LOG.debug("While delegating to wrapped request", e);
211             return null;
212         }
213     }
214 
215     @Override
216     public void setAttribute(final String name, final Object o) {
217         try {
218             super.setAttribute(name, o);
219         } catch (Exception e) {
220             LOG.debug("While delegating to wrapped request", e);
221         }
222     }
223 
224     @Override
225     public String getCharacterEncoding() {
226         try {
227             return super.getCharacterEncoding();
228         } catch (Exception e) {
229             LOG.debug("While delegating to wrapped request", e);
230             return StandardCharsets.UTF_8.name();
231         }
232     }
233 
234     @Override
235     public ServletInputStream getInputStream() throws IOException {
236         return inputStream;
237     }
238 }