
001package ca.uhn.fhir.rest.client.interceptor; 002 003/*- 004 * #%L 005 * HAPI FHIR - Client Framework 006 * %% 007 * Copyright (C) 2014 - 2023 Smile CDR, Inc. 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 ca.uhn.fhir.interceptor.api.Hook; 024import ca.uhn.fhir.interceptor.api.Pointcut; 025import ca.uhn.fhir.rest.client.api.IHttpRequest; 026 027import java.util.ArrayList; 028import java.util.HashMap; 029import java.util.List; 030import java.util.Map; 031import java.util.Objects; 032 033/** 034 * This interceptor adds arbitrary header values to requests made by the client. 035 * 036 * This is now also possible directly on the Fluent Client API by calling 037 * {@link ca.uhn.fhir.rest.gclient.IClientExecutable#withAdditionalHeader(String, String)} 038 */ 039public class AdditionalRequestHeadersInterceptor { 040 private final Map<String, List<String>> myAdditionalHttpHeaders; 041 042 /** 043 * Constructor 044 */ 045 public AdditionalRequestHeadersInterceptor() { 046 myAdditionalHttpHeaders = new HashMap<>(); 047 } 048 049 /** 050 * Constructor 051 * 052 * @param theHeaders The additional headers to add to every request 053 */ 054 public AdditionalRequestHeadersInterceptor(Map<String, List<String>> theHeaders) { 055 this(); 056 if (theHeaders != null) { 057 myAdditionalHttpHeaders.putAll(theHeaders); 058 } 059 } 060 061 /** 062 * Adds the given header value. 063 * Note that {@code headerName} and {@code headerValue} cannot be null. 064 * @param headerName the name of the header 065 * @param headerValue the value to add for the header 066 * @throws NullPointerException if either parameter is {@code null} 067 */ 068 public void addHeaderValue(String headerName, String headerValue) { 069 Objects.requireNonNull(headerName, "headerName cannot be null"); 070 Objects.requireNonNull(headerValue, "headerValue cannot be null"); 071 072 getHeaderValues(headerName).add(headerValue); 073 } 074 075 /** 076 * Adds the list of header values for the given header. 077 * Note that {@code headerName} and {@code headerValues} cannot be null. 078 * @param headerName the name of the header 079 * @param headerValues the list of values to add for the header 080 * @throws NullPointerException if either parameter is {@code null} 081 */ 082 public void addAllHeaderValues(String headerName, List<String> headerValues) { 083 Objects.requireNonNull(headerName, "headerName cannot be null"); 084 Objects.requireNonNull(headerValues, "headerValues cannot be null"); 085 086 getHeaderValues(headerName).addAll(headerValues); 087 } 088 089 /** 090 * Gets the header values list for a given header. 091 * If the header doesn't have any values, an empty list will be returned. 092 * @param headerName the name of the header 093 * @return the list of values for the header 094 */ 095 private List<String> getHeaderValues(String headerName) { 096 if (myAdditionalHttpHeaders.get(headerName) == null) { 097 myAdditionalHttpHeaders.put(headerName, new ArrayList<>()); 098 } 099 return myAdditionalHttpHeaders.get(headerName); 100 } 101 102 /** 103 * Adds the additional header values to the HTTP request. 104 * @param theRequest the HTTP request 105 */ 106 @Hook(Pointcut.CLIENT_REQUEST) 107 public void interceptRequest(IHttpRequest theRequest) { 108 for (Map.Entry<String, List<String>> header : myAdditionalHttpHeaders.entrySet()) { 109 for (String headerValue : header.getValue()) { 110 if (headerValue != null) { 111 theRequest.addHeader(header.getKey(), headerValue); 112 } 113 } 114 } 115 } 116 117}