1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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
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 }