001package ca.uhn.fhir.rest.server.servlet; 002 003/* 004 * #%L 005 * HAPI FHIR - Server Framework 006 * %% 007 * Copyright (C) 2014 - 2022 Smile CDR, Inc. 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.i18n.Msg; 024import ca.uhn.fhir.context.FhirContext; 025import ca.uhn.fhir.interceptor.api.IInterceptorBroadcaster; 026import ca.uhn.fhir.rest.api.Constants; 027import ca.uhn.fhir.rest.api.server.RequestDetails; 028import ca.uhn.fhir.rest.server.RestfulServer; 029import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; 030import org.apache.commons.io.IOUtils; 031import org.apache.commons.lang3.Validate; 032 033import javax.servlet.http.HttpServletRequest; 034import javax.servlet.http.HttpServletResponse; 035import java.io.ByteArrayInputStream; 036import java.io.IOException; 037import java.io.InputStream; 038import java.io.Reader; 039import java.nio.charset.Charset; 040import java.util.*; 041import java.util.zip.GZIPInputStream; 042 043import static org.apache.commons.lang3.StringUtils.isNotBlank; 044 045public class ServletRequestDetails extends RequestDetails { 046 047 private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ServletRequestDetails.class); 048 049 private RestfulServer myServer; 050 private HttpServletRequest myServletRequest; 051 private HttpServletResponse myServletResponse; 052 053 /** 054 * Constructor for testing only 055 */ 056 public ServletRequestDetails() { 057 this((IInterceptorBroadcaster)null); 058 } 059 060 /** 061 * Constructor 062 */ 063 public ServletRequestDetails(IInterceptorBroadcaster theInterceptorBroadcaster) { 064 super(theInterceptorBroadcaster); 065 setResponse(new ServletRestfulResponse(this)); 066 } 067 068 /** 069 * Copy constructor 070 */ 071 public ServletRequestDetails(ServletRequestDetails theRequestDetails) { 072 super(theRequestDetails); 073 074 myServer = theRequestDetails.getServer(); 075 myServletRequest = theRequestDetails.getServletRequest(); 076 myServletResponse = theRequestDetails.getServletResponse(); 077 } 078 079 @Override 080 protected byte[] getByteStreamRequestContents() { 081 try { 082 InputStream inputStream = getInputStream(); 083 byte[] requestContents = IOUtils.toByteArray(inputStream); 084 085 if (myServer.isUncompressIncomingContents()) { 086 String contentEncoding = myServletRequest.getHeader(Constants.HEADER_CONTENT_ENCODING); 087 if ("gzip".equals(contentEncoding)) { 088 ourLog.debug("Uncompressing (GZip) incoming content"); 089 if (requestContents.length > 0) { 090 GZIPInputStream gis = new GZIPInputStream(new ByteArrayInputStream(requestContents)); 091 requestContents = IOUtils.toByteArray(gis); 092 } 093 } 094 } 095 return requestContents; 096 } catch (IOException e) { 097 ourLog.error("Could not load request resource", e); 098 throw new InvalidRequestException(Msg.code(308) + String.format("Could not load request resource: %s", e.getMessage())); 099 } 100 } 101 102 @Override 103 public Charset getCharset() { 104 Charset charset = null; 105 106 String charsetString = myServletRequest.getCharacterEncoding(); 107 if (isNotBlank(charsetString)) { 108 charset = Charset.forName(charsetString); 109 } 110 111 return charset; 112 } 113 114 @Override 115 public FhirContext getFhirContext() { 116 return getServer().getFhirContext(); 117 } 118 119 @Override 120 public String getHeader(String name) { 121 return getServletRequest().getHeader(name); 122 } 123 124 @Override 125 public List<String> getHeaders(String name) { 126 Enumeration<String> headers = getServletRequest().getHeaders(name); 127 return headers == null ? Collections.emptyList() : Collections.list(getServletRequest().getHeaders(name)); 128 } 129 130 @Override 131 public Object getAttribute(String theAttributeName) { 132 Validate.notBlank(theAttributeName, "theAttributeName must not be null or blank"); 133 return getServletRequest().getAttribute(theAttributeName); 134 } 135 136 @Override 137 public void setAttribute(String theAttributeName, Object theAttributeValue) { 138 Validate.notBlank(theAttributeName, "theAttributeName must not be null or blank"); 139 getServletRequest().setAttribute(theAttributeName, theAttributeValue); 140 } 141 142 @Override 143 public InputStream getInputStream() throws IOException { 144 return getServletRequest().getInputStream(); 145 } 146 147 @Override 148 public Reader getReader() throws IOException { 149 return getServletRequest().getReader(); 150 } 151 152 @Override 153 public RestfulServer getServer() { 154 return myServer; 155 } 156 157 @Override 158 public String getServerBaseForRequest() { 159 return getServer().getServerBaseForRequest(this); 160 } 161 162 public HttpServletRequest getServletRequest() { 163 return myServletRequest; 164 } 165 166 public HttpServletResponse getServletResponse() { 167 return myServletResponse; 168 } 169 170 public void setServer(RestfulServer theServer) { 171 this.myServer = theServer; 172 } 173 174 public ServletRequestDetails setServletRequest(HttpServletRequest myServletRequest) { 175 this.myServletRequest = myServletRequest; 176 return this; 177 } 178 179 public void setServletResponse(HttpServletResponse myServletResponse) { 180 this.myServletResponse = myServletResponse; 181 } 182 183 public Map<String,List<String>> getHeaders() { 184 Map<String, List<String>> retVal = new HashMap<>(); 185 Enumeration<String> names = myServletRequest.getHeaderNames(); 186 while (names.hasMoreElements()) { 187 String nextName = names.nextElement(); 188 ArrayList<String> headerValues = new ArrayList<>(); 189 retVal.put(nextName, headerValues); 190 Enumeration<String> valuesEnum = myServletRequest.getHeaders(nextName); 191 while (valuesEnum.hasMoreElements()) { 192 headerValues.add(valuesEnum.nextElement()); 193 } 194 } 195 return Collections.unmodifiableMap(retVal); 196 } 197}