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 - 2021 Smile CDR, Inc. 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 bufferEntity() throws IOException { 056 if (myEntityBuffered) { 057 return; 058 } 059 try (InputStream responseEntity = readEntity()) { 060 if (responseEntity != null) { 061 myEntityBuffered = true; 062 try { 063 myEntityBytes = IOUtils.toByteArray(responseEntity); 064 } catch (IllegalStateException e) { 065 throw new InternalErrorException(e); 066 } 067 } 068 } 069 } 070 071 @Override 072 public void close() { 073 myResponse.close(); 074 } 075 076 @Override 077 public Reader createReader() throws IOException { 078 if (!myEntityBuffered && myResponse.body() == null) { 079 return new StringReader(""); 080 } else { 081 return new InputStreamReader(readEntity()); 082 } 083 } 084 085 @Override 086 public Map<String, List<String>> getAllHeaders() { 087 return myResponse.headers().toMultimap(); 088 } 089 090 @Override 091 public List<String> getHeaders(String theName) { 092 return myResponse.headers(theName); 093 } 094 095 @Override 096 public String getMimeType() { 097 String contentType = myResponse.header(Constants.HEADER_CONTENT_TYPE); 098 MediaType mediaType = null; 099 if (contentType == null) { 100 if (myResponse.body() != null) { 101 mediaType = myResponse.body().contentType(); 102 } 103 } else { 104 mediaType = MediaType.parse(contentType); 105 } 106 107 if (mediaType == null) { 108 return null; 109 } 110 111 return typeAndSubtypeOnly(mediaType).toString(); 112 } 113 114 @Override 115 public Object getResponse() { 116 return myResponse; 117 } 118 119 @Override 120 public int getStatus() { 121 return myResponse.code(); 122 } 123 124 @Override 125 public String getStatusInfo() { 126 return myResponse.message(); 127 } 128 129 @Override 130 public InputStream readEntity() throws IOException { 131 if (this.myEntityBuffered) { 132 return new ByteArrayInputStream(myEntityBytes); 133 } else if (myResponse.body() != null) { 134 return myResponse.body().byteStream(); 135 } else { 136 return null; 137 } 138 } 139 140 private MediaType typeAndSubtypeOnly(MediaType input) { 141 return MediaType.parse(input.type() + "/" + input.subtype()); 142 } 143 144}