001/*- 002 * #%L 003 * HAPI FHIR - Client Framework 004 * %% 005 * Copyright (C) 2014 - 2024 Smile CDR, Inc. 006 * %% 007 * Licensed under the Apache License, Version 2.0 (the "License"); 008 * you may not use this file except in compliance with the License. 009 * You may obtain a copy of the License at 010 * 011 * http://www.apache.org/licenses/LICENSE-2.0 012 * 013 * Unless required by applicable law or agreed to in writing, software 014 * distributed under the License is distributed on an "AS IS" BASIS, 015 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 016 * See the License for the specific language governing permissions and 017 * limitations under the License. 018 * #L% 019 */ 020package ca.uhn.fhir.rest.client.interceptor; 021 022import ca.uhn.fhir.interceptor.api.Hook; 023import ca.uhn.fhir.interceptor.api.Pointcut; 024import ca.uhn.fhir.rest.client.api.IHttpRequest; 025 026import java.util.ArrayList; 027import java.util.HashMap; 028import java.util.List; 029import java.util.Map; 030import java.util.Objects; 031 032/** 033 * This interceptor adds arbitrary header values to requests made by the client. 034 * 035 * This is now also possible directly on the Fluent Client API by calling 036 * {@link ca.uhn.fhir.rest.gclient.IClientExecutable#withAdditionalHeader(String, String)} 037 */ 038public class AdditionalRequestHeadersInterceptor { 039 private final Map<String, List<String>> myAdditionalHttpHeaders; 040 041 /** 042 * Constructor 043 */ 044 public AdditionalRequestHeadersInterceptor() { 045 myAdditionalHttpHeaders = new HashMap<>(); 046 } 047 048 /** 049 * Constructor 050 * 051 * @param theHeaders The additional headers to add to every request 052 */ 053 public AdditionalRequestHeadersInterceptor(Map<String, List<String>> theHeaders) { 054 this(); 055 if (theHeaders != null) { 056 myAdditionalHttpHeaders.putAll(theHeaders); 057 } 058 } 059 060 /** 061 * Adds the given header value. 062 * Note that {@code headerName} and {@code headerValue} cannot be null. 063 * @param headerName the name of the header 064 * @param headerValue the value to add for the header 065 * @throws NullPointerException if either parameter is {@code null} 066 */ 067 public void addHeaderValue(String headerName, String headerValue) { 068 Objects.requireNonNull(headerName, "headerName cannot be null"); 069 Objects.requireNonNull(headerValue, "headerValue cannot be null"); 070 071 getHeaderValues(headerName).add(headerValue); 072 } 073 074 /** 075 * Adds the list of header values for the given header. 076 * Note that {@code headerName} and {@code headerValues} cannot be null. 077 * @param headerName the name of the header 078 * @param headerValues the list of values to add for the header 079 * @throws NullPointerException if either parameter is {@code null} 080 */ 081 public void addAllHeaderValues(String headerName, List<String> headerValues) { 082 Objects.requireNonNull(headerName, "headerName cannot be null"); 083 Objects.requireNonNull(headerValues, "headerValues cannot be null"); 084 085 getHeaderValues(headerName).addAll(headerValues); 086 } 087 088 /** 089 * Gets the header values list for a given header. 090 * If the header doesn't have any values, an empty list will be returned. 091 * @param headerName the name of the header 092 * @return the list of values for the header 093 */ 094 private List<String> getHeaderValues(String headerName) { 095 if (myAdditionalHttpHeaders.get(headerName) == null) { 096 myAdditionalHttpHeaders.put(headerName, new ArrayList<>()); 097 } 098 return myAdditionalHttpHeaders.get(headerName); 099 } 100 101 /** 102 * Adds the additional header values to the HTTP request. 103 * @param theRequest the HTTP request 104 */ 105 @Hook(Pointcut.CLIENT_REQUEST) 106 public void interceptRequest(IHttpRequest theRequest) { 107 for (Map.Entry<String, List<String>> header : myAdditionalHttpHeaders.entrySet()) { 108 for (String headerValue : header.getValue()) { 109 if (headerValue != null) { 110 theRequest.addHeader(header.getKey(), headerValue); 111 } 112 } 113 } 114 } 115}