package org.smartly.packages.http.impl.util; import org.eclipse.jetty.http.HttpFields; import org.eclipse.jetty.http.HttpHeader; import org.eclipse.jetty.http.HttpStatus; import org.eclipse.jetty.io.WriterOutputStream; import org.eclipse.jetty.server.Dispatcher; import org.eclipse.jetty.server.HttpOutput; import org.eclipse.jetty.server.Response; import org.eclipse.jetty.server.handler.ContextHandler; import org.eclipse.jetty.util.URIUtil; import org.eclipse.jetty.util.resource.Resource; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import org.smartly.Smartly; import org.smartly.commons.io.FileMeta; import org.smartly.commons.io.FileMetaArray; import org.smartly.commons.util.ByteUtils; import org.smartly.commons.util.FileUtils; import org.smartly.commons.util.JsonWrapper; import org.smartly.commons.util.StringUtils; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.Part; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.MalformedURLException; import java.net.URLDecoder; import java.util.*; /** * */ public class ServletUtils { private static final String DEF_PART_NAME = "file"; private static final String REQ_PARAM_SEP = "&"; private ServletUtils() { } /** * Extract file info from a MultipartRequest * @param request Servlet Request * @return List of file wrappers * @throws IOException * @throws ServletException */ public static FileMetaArray getFiles(final HttpServletRequest request) throws IOException, ServletException { final FileMetaArray files = new FileMetaArray(); FileMeta temp = null; try { // Get all parts and creates meta wrappers final Collection<Part> parts = request.getParts(); for (final Part part : parts) { // if part is multiparts "file" if (part.getContentType() != null) { final FileMeta meta = getFileMeta(part); if(null!=meta){ files.add(getFileMeta(part)); } } } } catch (Throwable ignored) { final Part part = request.getPart(DEF_PART_NAME); if (null!=part && part.getContentType() != null) { final FileMeta meta = getFileMeta(part); if(null!=meta){ files.add(getFileMeta(part)); } } } return files; } private static FileMeta getFileMeta(final Part part) throws IOException { final String filename = getFilename(part); if(StringUtils.hasText(filename)){ final FileMeta meta = new FileMeta(); meta.setName(getFilename(part)); meta.setSize(part.getSize()); meta.setType(part.getContentType()); meta.setContent(part.getInputStream()); // attributes final Collection<String> names = part.getHeaderNames(); for(final String name:names){ meta.addAttribute(name, part.getHeader(name)); } return meta; } return null; } public static JSONObject getParameters(final HttpServletRequest request) { final JSONObject result = new JSONObject(); //-- GET METHOD --// try { final Map<String, String[]> map = request.getParameterMap(); if (map.size() > 0) { final Set<String> keys = map.keySet(); for (final String key : keys) { if (null != key) { addParam(result, key, map.get(key)); } } } } catch (Throwable ignored) { } //-- POST METHOD --// try { final InputStream is = request.getInputStream(); final byte[] bytes = ByteUtils.getBytes(is); if (null != bytes && bytes.length > 0) { final String data = new String(bytes, Smartly.getCharset()); if (StringUtils.hasLength(data)) { final String[] queryTokens = StringUtils.split(data, REQ_PARAM_SEP); for (final String qt : queryTokens) { final String[] keyValue = StringUtils.split(qt, "="); if (keyValue.length == 2) { JsonWrapper.put(result, keyValue[0], decode(keyValue[1])); } else { JsonWrapper.put(result, keyValue[0], ""); } } } } is.close(); } catch (Throwable ignored) { } return result; } public static JSONObject getAttributes(final ServletRequest request) { final JSONObject result = new JSONObject(); try { final Enumeration<String> names = request.getAttributeNames(); while (names.hasMoreElements()) { final String name = names.nextElement(); result.putOpt(name, request.getAttribute(name)); } } catch (Throwable ignored) { } return result; } public static Map<String, Object> getAttributesMap(final ServletRequest request) { final Map<String, Object> result = new HashMap<String, Object>(); try { final Enumeration<String> names = request.getAttributeNames(); while (names.hasMoreElements()) { final String name = names.nextElement(); result.put(name, request.getAttribute(name)); } } catch (Throwable ignored) { } return result; } public static void notFound404(final HttpServletResponse response) throws IOException { response.sendError(HttpStatus.NOT_FOUND_404); } public static void writeResponse(final HttpServletResponse response, final Long lastModified, final String mimeType, final byte[] content) throws IOException { doResponseHeaders(response, content.length, mimeType); final InputStream is = new ByteArrayInputStream(content); writeResponse(response, lastModified, is); } public static void writeResponse(final HttpServletResponse response, final Long lastModified, final Object content) throws IOException { if (null != lastModified) { response.setDateHeader(HttpHeader.LAST_MODIFIED.asString(), lastModified); } // Send the content OutputStream out = null; try { out = response.getOutputStream(); } catch (IllegalStateException e) { out = new WriterOutputStream(response.getWriter()); } // See if a short direct method can be used? if (out instanceof HttpOutput) { ((HttpOutput) out).sendContent(content); } else if (out instanceof WriterOutputStream) { // Write content normally FileUtils.copy((InputStream) content, out); } } public static void doResponseHeaders(final HttpServletResponse response, final Resource resource, final String mimeType) { final long length = resource.length(); doResponseHeaders(response, null, length, mimeType); } public static void doResponseHeaders(final HttpServletResponse response, final long length, final String mimeType) { doResponseHeaders(response, null, length, mimeType); } public static void doResponseHeaders(final HttpServletResponse response, final String cacheControl, final long length, final String mimeType) { if (mimeType != null) response.setContentType(mimeType); if (response instanceof Response) { final HttpFields fields = ((Response) response).getHttpFields(); if (length > 0) fields.putLongField(HttpHeader.CONTENT_LENGTH.asString(), length); if (cacheControl != null) fields.put(HttpHeader.CACHE_CONTROL.asString(), cacheControl); } else { if (length > 0) response.setHeader(HttpHeader.CONTENT_LENGTH.asString(), Long.toString(length)); if (cacheControl != null) response.setHeader(HttpHeader.CACHE_CONTROL.asString(), cacheControl); } } public static Map<String, String> getUrlParams(final HttpServletRequest request) throws MalformedURLException { final Map<String, String> params = new HashMap<String, String>(); getUrlParams(params, request); return params; } public static void getUrlParams(final Map<String, String> params, final HttpServletRequest request) throws MalformedURLException { final Map<String, String[]> paramsMap = request.getParameterMap(); final Set<String> names = paramsMap.keySet(); for (final String name : names) { final String[] value = paramsMap.get(name); if (null != value && value.length > 0) { if (value.length == 1) { params.put(name, value[0]); } else { final JSONArray array = new JSONArray(); for (final String v : value) { array.put(v); } params.put(name, array.toString()); } } } } public static String getResourcePath(final HttpServletRequest request) throws MalformedURLException { String servletPath; String pathInfo; Boolean included = request.getAttribute(Dispatcher.INCLUDE_REQUEST_URI) != null; if (included != null && included.booleanValue()) { servletPath = (String) request.getAttribute(Dispatcher.INCLUDE_SERVLET_PATH); pathInfo = (String) request.getAttribute(Dispatcher.INCLUDE_PATH_INFO); if (servletPath == null && pathInfo == null) { servletPath = request.getServletPath(); pathInfo = request.getPathInfo(); } } else { servletPath = request.getServletPath(); pathInfo = request.getPathInfo(); } return URIUtil.addPaths(servletPath, pathInfo); } public static String getResourcePath(final ServletRequest request) throws MalformedURLException { String servletPath = ""; String pathInfo = ""; Boolean included = request.getAttribute(Dispatcher.INCLUDE_REQUEST_URI) != null; if (included != null && included.booleanValue()) { servletPath = (String) request.getAttribute(Dispatcher.INCLUDE_SERVLET_PATH); pathInfo = (String) request.getAttribute(Dispatcher.INCLUDE_PATH_INFO); if (servletPath == null && pathInfo == null) { //servletPath = request.getServletPath(); //pathInfo = request.getPathInfo(); } } else { //servletPath = request.getServletPath(); //pathInfo = request.getPathInfo(); } return URIUtil.addPaths(servletPath, pathInfo); } public static Resource getResource(final Resource baseResource, final ContextHandler context, final String path) throws MalformedURLException { if (path == null || !path.startsWith("/")) throw new MalformedURLException(path); Resource base = baseResource; if (base == null) { if (context == null) return null; base = context.getBaseResource(); if (base == null) return null; } try { return base.addPath(URIUtil.canonicalPath(path)); } catch (Exception ignore) { } return null; } // -------------------------------------------------------------------- // p r i v a t e // -------------------------------------------------------------------- private static String decode(final String value) { try { return URLDecoder.decode(value, Smartly.getCharset()); } catch (Exception ex) { return value; } } /** * @param params container * @param key key. i.e. name[obj1][obj2].. * @param values array of values */ private static void addParam(final JSONObject params, final String key, final String[] values) throws JSONException { final Object jsonValue = toJsonValue(values); final String path = toJsonPath(key); JsonWrapper.put(params, path, jsonValue, true); } private static Object toJsonValue(final String[] values) throws JSONException { if (values.length == 0) { return ""; } else if (values.length == 1) { return values[0]; } else { return new JSONArray(values); } } /** * @param key i.e. "name[obj1][obj2]..." * @return "name.obj1.obj2" */ private static String toJsonPath(final String key) { final String result = key.replaceAll("\\[", ".").replaceAll("]", ""); if (result.endsWith(".")) { return result.substring(0, result.length() - 1); } return result; } private static String getFilename(final Part part) { final String partHeader = part.getHeader("content-disposition"); for (String content : part.getHeader("content-disposition").split(";")) { if (content.trim().startsWith("filename")) { final String filename = content.substring(content.indexOf('=') + 1).trim().replace("\"", ""); return filename.substring(filename.lastIndexOf('/') + 1).substring(filename.lastIndexOf('\\') + 1); // MSIE fix. } } return null; } }