001package ca.uhn.fhir.rest.server.servlet;
002
003/*
004 * #%L
005 * HAPI FHIR - Server Framework
006 * %%
007 * Copyright (C) 2014 - 2019 University Health Network
008 * %%
009 * Licensed under the Apache License, Version 2.0 (the "License");
010 * you may not use this file except in compliance with the License.
011 * You may obtain a copy of the License at
012 *
013 * http://www.apache.org/licenses/LICENSE-2.0
014 *
015 * Unless required by applicable law or agreed to in writing, software
016 * distributed under the License is distributed on an "AS IS" BASIS,
017 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
018 * See the License for the specific language governing permissions and
019 * limitations under the License.
020 * #L%
021 */
022
023import ca.uhn.fhir.context.FhirContext;
024import ca.uhn.fhir.interceptor.api.IInterceptorBroadcaster;
025import ca.uhn.fhir.rest.api.Constants;
026import ca.uhn.fhir.rest.api.server.RequestDetails;
027import ca.uhn.fhir.rest.server.RestfulServer;
028import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
029import org.apache.commons.io.IOUtils;
030import org.apache.commons.lang3.Validate;
031
032import javax.servlet.http.HttpServletRequest;
033import javax.servlet.http.HttpServletResponse;
034import java.io.ByteArrayInputStream;
035import java.io.IOException;
036import java.io.InputStream;
037import java.io.Reader;
038import java.nio.charset.Charset;
039import java.util.*;
040import java.util.zip.GZIPInputStream;
041
042import static org.apache.commons.lang3.StringUtils.isNotBlank;
043
044public class ServletRequestDetails extends RequestDetails {
045
046        private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ServletRequestDetails.class);
047
048        private RestfulServer myServer;
049        private HttpServletRequest myServletRequest;
050        private HttpServletResponse myServletResponse;
051
052        public ServletRequestDetails(IInterceptorBroadcaster theInterceptorBroadcaster) {
053                super(theInterceptorBroadcaster);
054                setResponse(new ServletRestfulResponse(this));
055        }
056
057        @Override
058        protected byte[] getByteStreamRequestContents() {
059                try {
060                        InputStream inputStream = getInputStream();
061                        byte[] requestContents = IOUtils.toByteArray(inputStream);
062
063                        if (myServer.isUncompressIncomingContents()) {
064                                String contentEncoding = myServletRequest.getHeader(Constants.HEADER_CONTENT_ENCODING);
065                                if ("gzip".equals(contentEncoding)) {
066                                        ourLog.debug("Uncompressing (GZip) incoming content");
067                                        if (requestContents.length > 0) {
068                                                GZIPInputStream gis = new GZIPInputStream(new ByteArrayInputStream(requestContents));
069                                                requestContents = IOUtils.toByteArray(gis);
070                                        }
071                                }
072                        }
073                        return requestContents;
074                } catch (IOException e) {
075                        ourLog.error("Could not load request resource", e);
076                        throw new InvalidRequestException(String.format("Could not load request resource: %s", e.getMessage()));
077                }
078        }
079
080        @Override
081        public Charset getCharset() {
082                Charset charset = null;
083
084                String charsetString = myServletRequest.getCharacterEncoding();
085                if (isNotBlank(charsetString)) {
086                        charset = Charset.forName(charsetString);
087                }
088
089                return charset;
090        }
091
092        @Override
093        public FhirContext getFhirContext() {
094                return getServer().getFhirContext();
095        }
096
097        @Override
098        public String getHeader(String name) {
099                return getServletRequest().getHeader(name);
100        }
101
102        @Override
103        public List<String> getHeaders(String name) {
104                Enumeration<String> headers = getServletRequest().getHeaders(name);
105                return headers == null ? Collections.emptyList() : Collections.list(getServletRequest().getHeaders(name));
106        }
107
108        @Override
109        public Object getAttribute(String theAttributeName) {
110                Validate.notBlank(theAttributeName, "theAttributeName must not be null or blank");
111                return getServletRequest().getAttribute(theAttributeName);
112        }
113
114        @Override
115        public void setAttribute(String theAttributeName, Object theAttributeValue) {
116                Validate.notBlank(theAttributeName, "theAttributeName must not be null or blank");
117                getServletRequest().setAttribute(theAttributeName, theAttributeValue);
118        }
119
120        @Override
121        public InputStream getInputStream() throws IOException {
122                return getServletRequest().getInputStream();
123        }
124
125        @Override
126        public Reader getReader() throws IOException {
127                return getServletRequest().getReader();
128        }
129
130        @Override
131        public RestfulServer getServer() {
132                return myServer;
133        }
134
135        @Override
136        public String getServerBaseForRequest() {
137                return getServer().getServerBaseForRequest(this);
138        }
139
140        public HttpServletRequest getServletRequest() {
141                return myServletRequest;
142        }
143
144        public HttpServletResponse getServletResponse() {
145                return myServletResponse;
146        }
147
148        public void setServer(RestfulServer theServer) {
149                this.myServer = theServer;
150        }
151
152        public void setServletRequest(HttpServletRequest myServletRequest) {
153                this.myServletRequest = myServletRequest;
154        }
155
156        public void setServletResponse(HttpServletResponse myServletResponse) {
157                this.myServletResponse = myServletResponse;
158        }
159
160        public Map<String,List<String>> getHeaders() {
161                Map<String, List<String>> retVal = new HashMap<>();
162                Enumeration<String> names = myServletRequest.getHeaderNames();
163                while (names.hasMoreElements()) {
164                        String nextName = names.nextElement();
165                        ArrayList<String> headerValues = new ArrayList<>();
166                        retVal.put(nextName, headerValues);
167                        Enumeration<String> valuesEnum = myServletRequest.getHeaders(nextName);
168                        while (valuesEnum.hasMoreElements()) {
169                                headerValues.add(valuesEnum.nextElement());
170                        }
171                }
172                return Collections.unmodifiableMap(retVal);
173        }
174}