/* * jBrowserDriver (TM) * Copyright (C) 2014-2016 Machine Publishers, LLC and the jBrowserDriver contributors * https://github.com/MachinePublishers/jBrowserDriver * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.machinepublishers.jbrowserdriver; import java.io.Serializable; import java.util.Collection; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.Map; /** * Customizes headers sent on each request. * This can be used to mimic behavior of particular browsers * or potentially set up more customized caching and authentication * settings. * * @see UserAgent */ public class RequestHeaders implements Serializable { private final LinkedHashMap<String, String> headersHttp; private final Map<String, String> headersHttpCasing; private final LinkedHashMap<String, String> headersHttps; private final Map<String, String> headersHttpsCasing; /** * Use this as a header value to force the header to be dropped from the request. For instance, * JavaFX WebKit will always add the Cookie header but adding the header map entry * <"Cookie", RequestHeaders.DROP_HEADER> will force the header to not be sent. */ public static final String DROP_HEADER = "drop_header"; /** * Use this as a header value to force the header to be replaced by a value generated at runtime * by the browser engine. For instance, JavaFX WebKit will always add Host header. Adding the * header map entry <"Host", RequestHeaders.DYNAMIC_HEADER> will preserve its ordering in * the headers map you specify, but its value will be decided at runtime for each request. */ public static final String DYNAMIC_HEADER = "dynamic_header"; /** * Tor Browser request headers * * @see UserAgent#TOR */ public static final RequestHeaders TOR; static { LinkedHashMap<String, String> headersTmp = new LinkedHashMap<String, String>(); headersTmp.put("Host", DYNAMIC_HEADER); headersTmp.put("User-Agent", DYNAMIC_HEADER); headersTmp.put("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"); headersTmp.put("Accept-Language", "en-us,en;q=0.5"); headersTmp.put("Accept-Encoding", "gzip, deflate"); headersTmp.put("Cookie", DYNAMIC_HEADER); headersTmp.put("DNT", "1"); headersTmp.put("Referer", DYNAMIC_HEADER); headersTmp.put("Connection", "keep-alive"); TOR = new RequestHeaders(headersTmp); } /** * Chrome browser request headers * * @see UserAgent#CHROME */ public static final RequestHeaders CHROME; static { LinkedHashMap<String, String> headersTmp = new LinkedHashMap<String, String>(); headersTmp.put("Host", DYNAMIC_HEADER); headersTmp.put("Connection", "keep-alive"); headersTmp.put("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8"); headersTmp.put("Upgrade-Insecure-Requests", "1"); headersTmp.put("User-Agent", DYNAMIC_HEADER); headersTmp.put("Referer", DYNAMIC_HEADER); headersTmp.put("Accept-Encoding", "gzip, deflate, sdch"); headersTmp.put("Accept-Language", "en-US,en;q=0.8"); headersTmp.put("Cookie", DYNAMIC_HEADER); CHROME = new RequestHeaders(headersTmp); } /** * Specify the ordered headers to be sent on each request. * * @see RequestHeaders#DROP_HEADER * @see RequestHeaders#DYNAMIC_HEADER */ public RequestHeaders(LinkedHashMap<String, String> headers) { this(headers, headers); } /** * Specify the ordered headers to be sent on each request. * Allows different sets of headers for HTTP and HTTPS. * * @see RequestHeaders#DROP_HEADER * @see RequestHeaders#DYNAMIC_HEADER */ public RequestHeaders(LinkedHashMap<String, String> headersHttp, LinkedHashMap<String, String> headersHttps) { LinkedHashMap<String, String> headersHttpTmp = new LinkedHashMap<String, String>(); Map<String, String> headersHttpCasingTmp = new HashMap<String, String>(); LinkedHashMap<String, String> headersHttpsTmp = new LinkedHashMap<String, String>(); Map<String, String> headersHttpsCasingTmp = new HashMap<String, String>(); createHeaders(headersHttp, headersHttpTmp, headersHttpCasingTmp); createHeaders(headersHttps, headersHttpsTmp, headersHttpsCasingTmp); this.headersHttp = headersHttpTmp; this.headersHttpCasing = headersHttpCasingTmp; this.headersHttps = headersHttpsTmp; this.headersHttpsCasing = headersHttpsCasingTmp; } private static void createHeaders( LinkedHashMap<String, String> headersIn, LinkedHashMap<String, String> headersOut, Map<String, String> headersCasing) { for (Map.Entry<String, String> cur : headersIn.entrySet()) { headersOut.put(cur.getKey().toLowerCase(), cur.getValue()); headersCasing.put(cur.getKey().toLowerCase(), cur.getKey()); } if (!headersOut.containsKey("accept-charset")) { headersOut.put("accept-charset", DROP_HEADER); headersCasing.put("accept-charset", "Accept-Charset"); } if (!headersOut.containsKey("pragma")) { headersOut.put("pragma", DROP_HEADER); headersCasing.put("pragma", "Pragma"); } } String nameFromLowercase(String headerNameLowercase, boolean https) { return https ? headersHttpsCasing.get(headerNameLowercase) : headersHttpCasing.get(headerNameLowercase); } Collection<String> headerNames(boolean https) { return https ? headersHttps.keySet() : headersHttp.keySet(); } String headerValue(String name, boolean https) { return https ? headersHttps.get(name) : headersHttp.get(name); } }