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}