001package ca.uhn.fhir.okhttp.client;
002
003import java.io.*;
004import java.util.List;
005import java.util.Map;
006
007import ca.uhn.fhir.rest.client.impl.BaseHttpResponse;
008import ca.uhn.fhir.util.StopWatch;
009import org.apache.commons.io.IOUtils;
010
011import ca.uhn.fhir.rest.api.Constants;
012
013/*
014 * #%L
015 * HAPI FHIR OkHttp Client
016 * %%
017 * Copyright (C) 2014 - 2018 University Health Network
018 * %%
019 * Licensed under the Apache License, Version 2.0 (the "License");
020 * you may not use this file except in compliance with the License.
021 * You may obtain a copy of the License at
022 * 
023 * http://www.apache.org/licenses/LICENSE-2.0
024 * 
025 * Unless required by applicable law or agreed to in writing, software
026 * distributed under the License is distributed on an "AS IS" BASIS,
027 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
028 * See the License for the specific language governing permissions and
029 * limitations under the License.
030 * #L%
031 */
032
033import ca.uhn.fhir.rest.client.api.IHttpResponse;
034import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
035import okhttp3.MediaType;
036import okhttp3.Response;
037
038/**
039 * Wraps an OkHttp {@link Response}
040 *
041 * @author Matthew Clarke | matthew.clarke@orionhealth.com | Orion Health
042 */
043public class OkHttpRestfulResponse extends BaseHttpResponse implements IHttpResponse {
044
045        private boolean myEntityBuffered = false;
046        private byte[] myEntityBytes;
047        private Response myResponse;
048
049        public OkHttpRestfulResponse(Response theResponse, StopWatch theResponseStopWatch) {
050                super(theResponseStopWatch);
051                this.myResponse = theResponse;
052        }
053
054        @Override
055        public void bufferEntitity() throws IOException {
056                bufferEntity();
057        }
058
059        @Override
060        public void bufferEntity() throws IOException {
061                if (myEntityBuffered) {
062                        return;
063                }
064                InputStream responseEntity = readEntity();
065                if (responseEntity != null) {
066                        myEntityBuffered = true;
067                        try {
068                                myEntityBytes = IOUtils.toByteArray(responseEntity);
069                        } catch (IllegalStateException e) {
070                                throw new InternalErrorException(e);
071                        }
072                }
073        }
074
075        @Override
076        public void close() {
077                myResponse.close();
078        }
079
080        @Override
081        public Reader createReader() throws IOException {
082                if (!myEntityBuffered && myResponse.body() == null) {
083                        return new StringReader("");
084                } else {
085                        return new InputStreamReader(readEntity());
086                }
087        }
088
089        @Override
090        public Map<String, List<String>> getAllHeaders() {
091                return myResponse.headers().toMultimap();
092        }
093
094        @Override
095        public List<String> getHeaders(String theName) {
096                return myResponse.headers(theName);
097        }
098
099        @Override
100        public String getMimeType() {
101                String contentType = myResponse.header(Constants.HEADER_CONTENT_TYPE);
102                MediaType mediaType = null;
103                if (contentType == null) {
104                        if (myResponse.body() != null) {
105                                mediaType = myResponse.body().contentType();
106                        }
107                } else {
108                        mediaType = MediaType.parse(contentType);
109                }
110
111                if (mediaType == null) {
112                        return null;
113                }
114
115                return typeAndSubtypeOnly(mediaType).toString();
116        }
117
118        @Override
119        public Object getResponse() {
120                return myResponse;
121        }
122
123        @Override
124        public int getStatus() {
125                return myResponse.code();
126        }
127
128        @Override
129        public String getStatusInfo() {
130                return myResponse.message();
131        }
132
133        @Override
134        public InputStream readEntity() throws IOException {
135                if (this.myEntityBuffered) {
136                        return new ByteArrayInputStream(myEntityBytes);
137                } else if (myResponse.body() != null) {
138                        return myResponse.body().byteStream();
139                } else {
140                        return null;
141                }
142        }
143
144        private MediaType typeAndSubtypeOnly(MediaType input) {
145                return MediaType.parse(input.type() + "/" + input.subtype());
146        }
147
148}