// // ======================================================================== // Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd. // ------------------------------------------------------------------------ // All rights reserved. This program and the accompanying materials // are made available under the terms of the Eclipse Public License v1.0 // and Apache License v2.0 which accompanies this distribution. // // The Eclipse Public License is available at // http://www.eclipse.org/legal/epl-v10.html // // The Apache License v2.0 is available at // http://www.opensource.org/licenses/apache2.0.php // // You may elect to redistribute this code under either of these licenses. // ======================================================================== // package org.eclipse.jetty.http; import java.util.Enumeration; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.MissingResourceException; import java.util.ResourceBundle; import org.eclipse.jetty.io.Buffer; import org.eclipse.jetty.io.BufferCache; import org.eclipse.jetty.io.BufferCache.CachedBuffer; import org.eclipse.jetty.util.StringUtil; import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; /* ------------------------------------------------------------ */ /** * */ public class MimeTypes { private static final Logger LOG = Log.getLogger(MimeTypes.class); public final static String FORM_ENCODED="application/x-www-form-urlencoded", MESSAGE_HTTP="message/http", MULTIPART_BYTERANGES="multipart/byteranges", TEXT_HTML="text/html", TEXT_PLAIN="text/plain", TEXT_XML="text/xml", TEXT_JSON="text/json", TEXT_HTML_8859_1="text/html;charset=ISO-8859-1", TEXT_PLAIN_8859_1="text/plain;charset=ISO-8859-1", TEXT_XML_8859_1="text/xml;charset=ISO-8859-1", TEXT_HTML_UTF_8="text/html;charset=UTF-8", TEXT_PLAIN_UTF_8="text/plain;charset=UTF-8", TEXT_XML_UTF_8="text/xml;charset=UTF-8", TEXT_JSON_UTF_8="text/json;charset=UTF-8"; private final static String TEXT_HTML__8859_1="text/html; charset=ISO-8859-1", TEXT_PLAIN__8859_1="text/plain; charset=ISO-8859-1", TEXT_XML__8859_1="text/xml; charset=ISO-8859-1", TEXT_HTML__UTF_8="text/html; charset=UTF-8", TEXT_PLAIN__UTF_8="text/plain; charset=UTF-8", TEXT_XML__UTF_8="text/xml; charset=UTF-8", TEXT_JSON__UTF_8="text/json; charset=UTF-8"; private final static int FORM_ENCODED_ORDINAL=1, MESSAGE_HTTP_ORDINAL=2, MULTIPART_BYTERANGES_ORDINAL=3, TEXT_HTML_ORDINAL=4, TEXT_PLAIN_ORDINAL=5, TEXT_XML_ORDINAL=6, TEXT_JSON_ORDINAL=7, TEXT_HTML_8859_1_ORDINAL=8, TEXT_PLAIN_8859_1_ORDINAL=9, TEXT_XML_8859_1_ORDINAL=10, TEXT_HTML_UTF_8_ORDINAL=11, TEXT_PLAIN_UTF_8_ORDINAL=12, TEXT_XML_UTF_8_ORDINAL=13, TEXT_JSON_UTF_8_ORDINAL=14; private static int __index=15; public final static BufferCache CACHE = new BufferCache(); public final static CachedBuffer FORM_ENCODED_BUFFER=CACHE.add(FORM_ENCODED,FORM_ENCODED_ORDINAL), MESSAGE_HTTP_BUFFER=CACHE.add(MESSAGE_HTTP, MESSAGE_HTTP_ORDINAL), MULTIPART_BYTERANGES_BUFFER=CACHE.add(MULTIPART_BYTERANGES,MULTIPART_BYTERANGES_ORDINAL), TEXT_HTML_BUFFER=CACHE.add(TEXT_HTML,TEXT_HTML_ORDINAL), TEXT_PLAIN_BUFFER=CACHE.add(TEXT_PLAIN,TEXT_PLAIN_ORDINAL), TEXT_XML_BUFFER=CACHE.add(TEXT_XML,TEXT_XML_ORDINAL), TEXT_JSON_BUFFER=CACHE.add(TEXT_JSON,TEXT_JSON_ORDINAL), TEXT_HTML_8859_1_BUFFER=CACHE.add(TEXT_HTML_8859_1,TEXT_HTML_8859_1_ORDINAL), TEXT_PLAIN_8859_1_BUFFER=CACHE.add(TEXT_PLAIN_8859_1,TEXT_PLAIN_8859_1_ORDINAL), TEXT_XML_8859_1_BUFFER=CACHE.add(TEXT_XML_8859_1,TEXT_XML_8859_1_ORDINAL), TEXT_HTML_UTF_8_BUFFER=CACHE.add(TEXT_HTML_UTF_8,TEXT_HTML_UTF_8_ORDINAL), TEXT_PLAIN_UTF_8_BUFFER=CACHE.add(TEXT_PLAIN_UTF_8,TEXT_PLAIN_UTF_8_ORDINAL), TEXT_XML_UTF_8_BUFFER=CACHE.add(TEXT_XML_UTF_8,TEXT_XML_UTF_8_ORDINAL), TEXT_JSON_UTF_8_BUFFER=CACHE.add(TEXT_JSON_UTF_8,TEXT_JSON_UTF_8_ORDINAL), TEXT_HTML__8859_1_BUFFER=CACHE.add(TEXT_HTML__8859_1,TEXT_HTML_8859_1_ORDINAL), TEXT_PLAIN__8859_1_BUFFER=CACHE.add(TEXT_PLAIN__8859_1,TEXT_PLAIN_8859_1_ORDINAL), TEXT_XML__8859_1_BUFFER=CACHE.add(TEXT_XML__8859_1,TEXT_XML_8859_1_ORDINAL), TEXT_HTML__UTF_8_BUFFER=CACHE.add(TEXT_HTML__UTF_8,TEXT_HTML_UTF_8_ORDINAL), TEXT_PLAIN__UTF_8_BUFFER=CACHE.add(TEXT_PLAIN__UTF_8,TEXT_PLAIN_UTF_8_ORDINAL), TEXT_XML__UTF_8_BUFFER=CACHE.add(TEXT_XML__UTF_8,TEXT_XML_UTF_8_ORDINAL), TEXT_JSON__UTF_8_BUFFER=CACHE.add(TEXT_JSON__UTF_8,TEXT_JSON_UTF_8_ORDINAL); /* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */ private final static Map __dftMimeMap = new HashMap(); private final static Map __encodings = new HashMap(); static { try { ResourceBundle mime = ResourceBundle.getBundle("org/eclipse/jetty/http/mime"); Enumeration i = mime.getKeys(); while(i.hasMoreElements()) { String ext = (String)i.nextElement(); String m = mime.getString(ext); __dftMimeMap.put(StringUtil.asciiToLowerCase(ext),normalizeMimeType(m)); } } catch(MissingResourceException e) { LOG.warn(e.toString()); LOG.debug(e); } try { ResourceBundle encoding = ResourceBundle.getBundle("org/eclipse/jetty/http/encoding"); Enumeration i = encoding.getKeys(); while(i.hasMoreElements()) { Buffer type = normalizeMimeType((String)i.nextElement()); __encodings.put(type,encoding.getString(type.toString())); } } catch(MissingResourceException e) { LOG.warn(e.toString()); LOG.debug(e); } TEXT_HTML_BUFFER.setAssociate("ISO-8859-1",TEXT_HTML_8859_1_BUFFER); TEXT_HTML_BUFFER.setAssociate("ISO_8859_1",TEXT_HTML_8859_1_BUFFER); TEXT_HTML_BUFFER.setAssociate("iso-8859-1",TEXT_HTML_8859_1_BUFFER); TEXT_PLAIN_BUFFER.setAssociate("ISO-8859-1",TEXT_PLAIN_8859_1_BUFFER); TEXT_PLAIN_BUFFER.setAssociate("ISO_8859_1",TEXT_PLAIN_8859_1_BUFFER); TEXT_PLAIN_BUFFER.setAssociate("iso-8859-1",TEXT_PLAIN_8859_1_BUFFER); TEXT_XML_BUFFER.setAssociate("ISO-8859-1",TEXT_XML_8859_1_BUFFER); TEXT_XML_BUFFER.setAssociate("ISO_8859_1",TEXT_XML_8859_1_BUFFER); TEXT_XML_BUFFER.setAssociate("iso-8859-1",TEXT_XML_8859_1_BUFFER); TEXT_HTML_BUFFER.setAssociate("UTF-8",TEXT_HTML_UTF_8_BUFFER); TEXT_HTML_BUFFER.setAssociate("UTF8",TEXT_HTML_UTF_8_BUFFER); TEXT_HTML_BUFFER.setAssociate("utf8",TEXT_HTML_UTF_8_BUFFER); TEXT_HTML_BUFFER.setAssociate("utf-8",TEXT_HTML_UTF_8_BUFFER); TEXT_PLAIN_BUFFER.setAssociate("UTF-8",TEXT_PLAIN_UTF_8_BUFFER); TEXT_PLAIN_BUFFER.setAssociate("UTF8",TEXT_PLAIN_UTF_8_BUFFER); TEXT_PLAIN_BUFFER.setAssociate("utf8",TEXT_PLAIN_UTF_8_BUFFER); TEXT_PLAIN_BUFFER.setAssociate("utf-8",TEXT_PLAIN_UTF_8_BUFFER); TEXT_XML_BUFFER.setAssociate("UTF-8",TEXT_XML_UTF_8_BUFFER); TEXT_XML_BUFFER.setAssociate("UTF8",TEXT_XML_UTF_8_BUFFER); TEXT_XML_BUFFER.setAssociate("utf8",TEXT_XML_UTF_8_BUFFER); TEXT_XML_BUFFER.setAssociate("utf-8",TEXT_XML_UTF_8_BUFFER); TEXT_JSON_BUFFER.setAssociate("UTF-8",TEXT_JSON_UTF_8_BUFFER); TEXT_JSON_BUFFER.setAssociate("UTF8",TEXT_JSON_UTF_8_BUFFER); TEXT_JSON_BUFFER.setAssociate("utf8",TEXT_JSON_UTF_8_BUFFER); TEXT_JSON_BUFFER.setAssociate("utf-8",TEXT_JSON_UTF_8_BUFFER); } /* ------------------------------------------------------------ */ private Map _mimeMap; /* ------------------------------------------------------------ */ /** Constructor. */ public MimeTypes() { } /* ------------------------------------------------------------ */ public synchronized Map getMimeMap() { return _mimeMap; } /* ------------------------------------------------------------ */ /** * @param mimeMap A Map of file extension to mime-type. */ public void setMimeMap(Map mimeMap) { if (mimeMap==null) { _mimeMap=null; return; } Map m=new HashMap(); Iterator i=mimeMap.entrySet().iterator(); while (i.hasNext()) { Map.Entry entry = (Map.Entry)i.next(); m.put(entry.getKey(),normalizeMimeType(entry.getValue().toString())); } _mimeMap=m; } /* ------------------------------------------------------------ */ /** Get the MIME type by filename extension. * @param filename A file name * @return MIME type matching the longest dot extension of the * file name. */ public Buffer getMimeByExtension(String filename) { Buffer type=null; if (filename!=null) { int i=-1; while(type==null) { i=filename.indexOf(".",i+1); if (i<0 || i>=filename.length()) break; String ext=StringUtil.asciiToLowerCase(filename.substring(i+1)); if (_mimeMap!=null) type = (Buffer)_mimeMap.get(ext); if (type==null) type=(Buffer)__dftMimeMap.get(ext); } } if (type==null) { if (_mimeMap!=null) type=(Buffer)_mimeMap.get("*"); if (type==null) type=(Buffer)__dftMimeMap.get("*"); } return type; } /* ------------------------------------------------------------ */ /** Set a mime mapping * @param extension * @param type */ public void addMimeMapping(String extension,String type) { if (_mimeMap==null) _mimeMap=new HashMap(); _mimeMap.put(StringUtil.asciiToLowerCase(extension),normalizeMimeType(type)); } /* ------------------------------------------------------------ */ private static synchronized Buffer normalizeMimeType(String type) { Buffer b =CACHE.get(type); if (b==null) b=CACHE.add(type,__index++); return b; } /* ------------------------------------------------------------ */ public static String getCharsetFromContentType(Buffer value) { if (value instanceof CachedBuffer) { switch(((CachedBuffer)value).getOrdinal()) { case TEXT_HTML_8859_1_ORDINAL: case TEXT_PLAIN_8859_1_ORDINAL: case TEXT_XML_8859_1_ORDINAL: return StringUtil.__ISO_8859_1; case TEXT_HTML_UTF_8_ORDINAL: case TEXT_PLAIN_UTF_8_ORDINAL: case TEXT_XML_UTF_8_ORDINAL: case TEXT_JSON_UTF_8_ORDINAL: return StringUtil.__UTF8; } } int i=value.getIndex(); int end=value.putIndex(); int state=0; int start=0; boolean quote=false; for (;i