All Downloads are FREE. Search and download functionalities are using the official Maven repository.

ca.uhn.fhir.rest.server.servlet.ServletRequestDetails Maven / Gradle / Ivy

There is a newer version: 7.6.1
Show newest version
package ca.uhn.fhir.rest.server.servlet;

/*
 * #%L
 * HAPI FHIR - Core Library
 * %%
 * Copyright (C) 2014 - 2016 University Health Network
 * %%
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * #L%
 */
import static org.apache.commons.lang3.StringUtils.isNotBlank;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import java.nio.charset.Charset;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.zip.GZIPInputStream;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.io.IOUtils;
import org.apache.http.entity.ContentType;

import ca.uhn.fhir.context.ConfigurationException;
import ca.uhn.fhir.rest.api.RequestTypeEnum;
import ca.uhn.fhir.rest.method.BaseMethodBinding;
import ca.uhn.fhir.rest.method.BaseMethodBinding.IRequestReader;
import ca.uhn.fhir.rest.method.RequestDetails;
import ca.uhn.fhir.rest.server.Constants;
import ca.uhn.fhir.rest.server.RestfulServer;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;

public class ServletRequestDetails extends RequestDetails {

	private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ServletRequestDetails.class);
	/**
	 * @see BaseMethodBinding#loadRequestContents(RequestDetails)
	 */
	private static volatile IRequestReader ourRequestReader;
	private RestfulServer myServer;
	private HttpServletRequest myServletRequest;
	private HttpServletResponse myServletResponse;
	private byte[] requestContents;

	public ServletRequestDetails() {
		super();
		setResponse(new ServletRestfulResponse(this));
	}

	@Override
	protected byte[] getByteStreamRequestContents() {
		/*
		 * This is weird, but this class is used both in clients and in servers, and we want to avoid needing to depend on
		 * servlet-api in clients since there is no point. So we dynamically load a class that does the servlet processing
		 * in servers. Down the road it may make sense to just split the method binding classes into server and client
		 * versions, but this isn't actually a huge deal I don't think.
		 */
		IRequestReader reader = ourRequestReader;
		if (reader == null) {
			try {
				Class.forName("javax.servlet.ServletInputStream");
				String className = BaseMethodBinding.class.getName() + "$" + "ActiveRequestReader";
				try {
					reader = (IRequestReader) Class.forName(className).newInstance();
				} catch (Exception e1) {
					throw new ConfigurationException("Failed to instantiate class " + className, e1);
				}
			} catch (ClassNotFoundException e) {
				String className = BaseMethodBinding.class.getName() + "$" + "InactiveRequestReader";
				try {
					reader = (IRequestReader) Class.forName(className).newInstance();
				} catch (Exception e1) {
					throw new ConfigurationException("Failed to instantiate class " + className, e1);
				}
			}
			ourRequestReader = reader;
		}

		try {
			InputStream inputStream = reader.getInputStream(this);
			requestContents = IOUtils.toByteArray(inputStream);
			
			if (myServer.isUncompressIncomingContents()) {
				String contentEncoding = myServletRequest.getHeader(Constants.HEADER_CONTENT_ENCODING);
				if ("gzip".equals(contentEncoding)) {
					ourLog.debug("Uncompressing (GZip) incoming content");
					if (requestContents.length > 0) {
						GZIPInputStream gis = new GZIPInputStream(new ByteArrayInputStream(requestContents));
						requestContents = IOUtils.toByteArray(gis);
					}
				}
			}
			
			return requestContents;
		} catch (IOException e) {
			ourLog.error("Could not load request resource", e);
			throw new InvalidRequestException(String.format("Could not load request resource: %s", e.getMessage()));
		}
	}

	@Override
	public String getHeader(String name) {
		return getServletRequest().getHeader(name);
	}

	@Override
	public List getHeaders(String name) {
		Enumeration headers = getServletRequest().getHeaders(name);
		return headers == null ? Collections. emptyList() : Collections.list(getServletRequest().getHeaders(name));
	}

	@Override
	public InputStream getInputStream() throws IOException {
		return getServletRequest().getInputStream();
	}

	@Override
	public Reader getReader() throws IOException {
		return getServletRequest().getReader();
	}

	@Override
	public RestfulServer getServer() {
		return myServer;
	}

	@Override
	public String getServerBaseForRequest() {
		return getServer().getServerBaseForRequest(getServletRequest());
	}

	public HttpServletRequest getServletRequest() {
		return myServletRequest;
	}

	public HttpServletResponse getServletResponse() {
		return myServletResponse;
	}

	public void setServer(RestfulServer theServer) {
		this.myServer = theServer;
	}

	public void setServletRequest(HttpServletRequest myServletRequest) {
		this.myServletRequest = myServletRequest;
	}

	public void setServletResponse(HttpServletResponse myServletResponse) {
		this.myServletResponse = myServletResponse;
	}

	public static RequestDetails withResourceAndParams(String theResourceName, RequestTypeEnum theRequestType, Set theParamNames) {
		RequestDetails retVal = new ServletRequestDetails();
		retVal.setResourceName(theResourceName);
		retVal.setRequestType(theRequestType);
		Map paramNames = new HashMap();
		for (String next : theParamNames) {
			paramNames.put(next, new String[0]);
		}
		retVal.setParameters(paramNames);
		return retVal;
	}

	@Override
	public Charset getCharset() {
		String ct = getHeader(Constants.HEADER_CONTENT_TYPE);

		Charset charset = null;
		if (isNotBlank(ct)) {
			ContentType parsedCt = ContentType.parse(ct);
			charset = parsedCt.getCharset();
		}
		return charset;
	}

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy