// --------------------------------------------------------------------------- // jWebSocket - RequestHeader Object // Copyright (c) 2010 Alexander Schulze, Innotrade GmbH // --------------------------------------------------------------------------- // This program is free software; you can redistribute it and/or modify it // under the terms of the GNU Lesser General Public License as published by the // Free Software Foundation; either version 3 of the License, or (at your // option) any later version. // This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or // FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for // more details. // You should have received a copy of the GNU Lesser General Public License along // with this program; if not, see <http://www.gnu.org/licenses/lgpl.html>. // --------------------------------------------------------------------------- package org.jwebsocket.kit; import java.util.Map; import javolution.util.FastMap; import org.jwebsocket.config.JWebSocketCommonConstants; /** * Holds the header of the initial WebSocket request from the client * to the server. The RequestHeader internally maintains a FastMap to store * key/values pairs. * @author aschulze * @author jang * @version $Id: RequestHeader.java 596 2010-06-22 17:09:54Z fivefeetfurther $ */ public final class RequestHeader { private Map<String, Object> mFields = new FastMap<String, Object>(); public static final String WS_PROTOCOL = "subprot"; public static final String WS_DRAFT = "draft"; public static final String WS_ORIGIN = "origin"; public static final String WS_LOCATION = "location"; public static final String WS_PATH = "path"; public static final String WS_SEARCHSTRING = "searchString"; public static final String WS_HOST = "host"; public static final String WS_SECKEY1 = "secKey1"; public static final String WS_SECKEY2 = "secKey2"; public static final String URL_ARGS = "args"; public static final String TIMEOUT = "timeout"; /** * Puts a new object value to the request header. * @param aKey * @param aValue */ public void put(String aKey, Object aValue) { mFields.put(aKey, aValue); } /** * Returns the object value for the given key or {@code null} if the * key does not exist in the header. * @param aKey * @return object value for the given key or {@code null}. */ public Object get(String aKey) { return mFields.get(aKey); } /** * Returns the string value for the given key or {@code null} if the * key does not exist in the header. * @param aKey * @return String value for the given key or {@code null}. */ public String getString(String aKey) { return (String) mFields.get(aKey); } /** * Returns a Map of the optional URL arguments passed by the client. * @return Map of the optional URL arguments. */ public Map getArgs() { return (Map) mFields.get(URL_ARGS); } /** * Returns the sub protocol passed by the client or a default value * if no sub protocol has been passed either in the header or in the * URL arguments. * @return Sub protocol passed by the client or default value. */ public String getSubProtocol() { return resolveSubprotocol()[0]; } /** * Returns the subprotocol format in which messages are exchanged between client and server. * @return subprotocol format passed by the client or default value */ public String getFormat() { return resolveSubprotocol()[1]; } /** * Tries to resolve correct subprotocol & format regardless of * client version (old, new, hixie, hybi, browser, java). * TODO: deprecate this method once majority of clients switch to new 'subprotocol/format' scheme * @return array with two members: protocol and format */ private String[] resolveSubprotocol() { String lSubProt = (String) mFields.get(WS_PROTOCOL); if (lSubProt == null) { return new String[] { JWebSocketCommonConstants.WS_SUBPROTOCOL_DEFAULT, JWebSocketCommonConstants.WS_FORMAT_DEFAULT}; } else { if(lSubProt.indexOf('/') != -1) { // expecting 'subprotocol/format' scheme return lSubProt.split("/"); } else { String format = JWebSocketCommonConstants.WS_FORMAT_DEFAULT; if(JWebSocketCommonConstants.WS_SUBPROT_JSON.equals(lSubProt) || JWebSocketCommonConstants.SUB_PROT_JSON.equals(lSubProt)) { format = JWebSocketCommonConstants.WS_FORMAT_JSON; } else if(JWebSocketCommonConstants.WS_SUBPROT_XML.equals(lSubProt) || JWebSocketCommonConstants.SUB_PROT_XML.equals(lSubProt)) { format = JWebSocketCommonConstants.WS_FORMAT_XML; } else if(JWebSocketCommonConstants.WS_SUBPROT_CSV.equals(lSubProt) || JWebSocketCommonConstants.SUB_PROT_CSV.equals(lSubProt)) { format = JWebSocketCommonConstants.WS_FORMAT_CSV; } else if(JWebSocketCommonConstants.WS_SUBPROT_CUSTOM.equals(lSubProt) || JWebSocketCommonConstants.SUB_PROT_CUSTOM.equals(lSubProt)) { format = JWebSocketCommonConstants.WS_FORMAT_CUSTOM; } return new String[] { lSubProt, format }; } } } /** * Returns the session timeout passed by the client or a default value * if no session timeout has been passed either in the header or in the * URL arguments. * @param aDefault * @return Session timeout passed by the client or default value. */ public Integer getTimeout(Integer aDefault) { Map lArgs = getArgs(); Integer lTimeout = null; if (lArgs != null) { try { lTimeout = Integer.parseInt((String) (lArgs.get(TIMEOUT))); } catch (Exception lEx) { } } return (lTimeout != null ? lTimeout : aDefault); } public String getDraft() { return (String) mFields.get(WS_DRAFT); } }