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}