1 /* 2 * Copyright (C) 2011 The Guava Authors 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.google.common.net; 18 19 import com.google.common.base.Ascii; 20 import com.google.common.base.Joiner; 21 import com.google.common.base.Splitter; 22 import com.google.common.collect.ImmutableBiMap; 23 import com.google.common.collect.ImmutableSet; 24 import com.google.common.collect.Lists; 25 import java.lang.reflect.Field; 26 import java.util.List; 27 import junit.framework.TestCase; 28 29 /** 30 * Tests for the HttpHeaders class. 31 * 32 * @author Kurt Alfred Kluever 33 */ 34 public class HttpHeadersTest extends TestCase { 35 testConstantNameMatchesString()36 public void testConstantNameMatchesString() throws Exception { 37 // Special case some of the weird HTTP Header names... 38 ImmutableBiMap<String, String> specialCases = 39 ImmutableBiMap.<String, String>builder() 40 .put("CDN_LOOP", "CDN-Loop") 41 .put("ETAG", "ETag") 42 .put("SOURCE_MAP", "SourceMap") 43 .put("SEC_WEBSOCKET_ACCEPT", "Sec-WebSocket-Accept") 44 .put("SEC_WEBSOCKET_EXTENSIONS", "Sec-WebSocket-Extensions") 45 .put("SEC_WEBSOCKET_KEY", "Sec-WebSocket-Key") 46 .put("SEC_WEBSOCKET_PROTOCOL", "Sec-WebSocket-Protocol") 47 .put("SEC_WEBSOCKET_VERSION", "Sec-WebSocket-Version") 48 .put("X_WEBKIT_CSP", "X-WebKit-CSP") 49 .put("X_WEBKIT_CSP_REPORT_ONLY", "X-WebKit-CSP-Report-Only") 50 .build(); 51 ImmutableSet<String> uppercaseAcronyms = 52 ImmutableSet.of( 53 "CH", "ID", "DNT", "DNS", "HTTP2", "IP", "MD5", "P3P", "TE", "UA", "UID", "URL", "WWW", 54 "XSS"); 55 assertConstantNameMatchesString(HttpHeaders.class, specialCases, uppercaseAcronyms); 56 } 57 58 // Visible for other tests to use assertConstantNameMatchesString( Class<?> clazz, ImmutableBiMap<String, String> specialCases, ImmutableSet<String> uppercaseAcronyms)59 static void assertConstantNameMatchesString( 60 Class<?> clazz, 61 ImmutableBiMap<String, String> specialCases, 62 ImmutableSet<String> uppercaseAcronyms) 63 throws IllegalAccessException { 64 for (Field field : relevantFields(clazz)) { 65 assertEquals( 66 upperToHttpHeaderName(field.getName(), specialCases, uppercaseAcronyms), field.get(null)); 67 } 68 } 69 70 // Visible for other tests to use relevantFields(Class<?> cls)71 static ImmutableSet<Field> relevantFields(Class<?> cls) { 72 ImmutableSet.Builder<Field> builder = ImmutableSet.builder(); 73 for (Field field : cls.getDeclaredFields()) { 74 /* 75 * Coverage mode generates synthetic fields. If we ever add private 76 * fields, they will cause similar problems, and we may want to switch 77 * this check to isAccessible(). 78 */ 79 if (!field.isSynthetic() && field.getType() == String.class) { 80 builder.add(field); 81 } 82 } 83 return builder.build(); 84 } 85 86 private static final Splitter SPLITTER = Splitter.on('_'); 87 private static final Joiner JOINER = Joiner.on('-'); 88 upperToHttpHeaderName( String constantName, ImmutableBiMap<String, String> specialCases, ImmutableSet<String> uppercaseAcronyms)89 private static String upperToHttpHeaderName( 90 String constantName, 91 ImmutableBiMap<String, String> specialCases, 92 ImmutableSet<String> uppercaseAcronyms) { 93 if (specialCases.containsKey(constantName)) { 94 return specialCases.get(constantName); 95 } 96 List<String> parts = Lists.newArrayList(); 97 for (String part : SPLITTER.split(constantName)) { 98 if (!uppercaseAcronyms.contains(part)) { 99 part = part.charAt(0) + Ascii.toLowerCase(part.substring(1)); 100 } 101 parts.add(part); 102 } 103 return JOINER.join(parts); 104 } 105 } 106