001package ca.uhn.fhir.rest.client.apache;
002
003/*-
004 * #%L
005 * HAPI FHIR - Core Library
006 * %%
007 * Copyright (C) 2014 - 2017 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 java.util.List;
024import java.util.Map;
025
026import org.hl7.fhir.instance.model.api.IBaseBinary;
027
028import ca.uhn.fhir.context.FhirContext;
029import ca.uhn.fhir.rest.api.RequestTypeEnum;
030import ca.uhn.fhir.rest.client.BaseHttpClientInvocation;
031import ca.uhn.fhir.rest.client.api.*;
032import ca.uhn.fhir.rest.server.*;
033
034public abstract class BaseHttpClient implements IHttpClient {
035
036        private final List<Header> myHeaders;
037        private final Map<String, List<String>> myIfNoneExistParams;
038        private final String myIfNoneExistString;
039        protected final RequestTypeEnum myRequestType;
040        protected final StringBuilder myUrl;
041
042        /**
043         * Constructor
044         */
045        public BaseHttpClient(StringBuilder theUrl, Map<String, List<String>> theIfNoneExistParams, String theIfNoneExistString, RequestTypeEnum theRequestType, List<Header> theHeaders) {
046                this.myUrl = theUrl;
047                this.myIfNoneExistParams = theIfNoneExistParams;
048                this.myIfNoneExistString = theIfNoneExistString;
049                this.myRequestType = theRequestType;
050                this.myHeaders = theHeaders;
051        }
052
053        private void addHeaderIfNoneExist(IHttpRequest result) {
054                if (myIfNoneExistParams != null) {
055                        StringBuilder b = newHeaderBuilder(myUrl);
056                        BaseHttpClientInvocation.appendExtraParamsWithQuestionMark(myIfNoneExistParams, b, b.indexOf("?") == -1);
057                        result.addHeader(Constants.HEADER_IF_NONE_EXIST, b.toString());
058                }
059
060                if (myIfNoneExistString != null) {
061                        StringBuilder b = newHeaderBuilder(myUrl);
062                        b.append(b.indexOf("?") == -1 ? '?' : '&');
063                        b.append(myIfNoneExistString.substring(myIfNoneExistString.indexOf('?') + 1));
064                        result.addHeader(Constants.HEADER_IF_NONE_EXIST, b.toString());
065                }
066        }
067
068        public void addHeadersToRequest(IHttpRequest theHttpRequest, EncodingEnum theEncoding, FhirContext theContext) {
069                if (myHeaders != null) {
070                        for (Header next : myHeaders) {
071                                theHttpRequest.addHeader(next.getName(), next.getValue());
072                        }
073                }
074
075                theHttpRequest.addHeader("User-Agent", HttpClientUtil.createUserAgentString(theContext, "apache"));
076                theHttpRequest.addHeader("Accept-Charset", "utf-8");
077                theHttpRequest.addHeader("Accept-Encoding", "gzip");
078
079                addHeaderIfNoneExist(theHttpRequest);
080
081                RestfulServerUtils.addAcceptHeaderToRequest(theEncoding, theHttpRequest, theContext);
082        }
083
084        @Override
085        public IHttpRequest createBinaryRequest(FhirContext theContext, IBaseBinary theBinary) {
086                byte[] content = theBinary.getContent();
087                IHttpRequest retVal = createHttpRequest(content);
088                addHeadersToRequest(retVal, null, theContext);
089                retVal.addHeader(Constants.HEADER_CONTENT_TYPE, theBinary.getContentType());
090                return retVal;
091        }
092
093        @Override
094        public IHttpRequest createByteRequest(FhirContext theContext, String theContents, String theContentType, EncodingEnum theEncoding) {
095                IHttpRequest retVal = createHttpRequest(theContents);
096                addHeadersToRequest(retVal, theEncoding, theContext);
097                retVal.addHeader(Constants.HEADER_CONTENT_TYPE, theContentType + Constants.HEADER_SUFFIX_CT_UTF_8);
098                return retVal;
099        }
100
101        @Override
102        public IHttpRequest createGetRequest(FhirContext theContext, EncodingEnum theEncoding) {
103                IHttpRequest retVal = createHttpRequest();
104                addHeadersToRequest(retVal, theEncoding, theContext);
105                return retVal;
106        }
107
108        protected abstract IHttpRequest createHttpRequest();
109
110        protected abstract IHttpRequest createHttpRequest(byte[] theContent);
111
112        protected abstract IHttpRequest createHttpRequest(Map<String, List<String>> theParams);
113
114        protected abstract IHttpRequest createHttpRequest(String theContents);
115
116        @Override
117        public IHttpRequest createParamRequest(FhirContext theContext, Map<String, List<String>> theParams, EncodingEnum theEncoding) {
118                IHttpRequest retVal = createHttpRequest(theParams);
119                addHeadersToRequest(retVal, theEncoding, theContext);
120                return retVal;
121        }
122
123        private StringBuilder newHeaderBuilder(StringBuilder theUrlBase) {
124                StringBuilder b = new StringBuilder();
125                b.append(theUrlBase);
126                if (theUrlBase.length() > 0 && theUrlBase.charAt(theUrlBase.length() - 1) == '/') {
127                        b.deleteCharAt(b.length() - 1);
128                }
129                return b;
130        }
131}