package com.elibom.jogger.http.servlet; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.util.ArrayList; import java.util.Collections; import java.util.Enumeration; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.servlet.http.HttpServletRequest; import com.elibom.jogger.http.AbstractRequest; import com.elibom.jogger.http.Cookie; import com.elibom.jogger.http.FileItem; import com.elibom.jogger.http.HttpException; import com.elibom.jogger.http.Path; import com.elibom.jogger.http.servlet.multipart.Multipart; import com.elibom.jogger.http.servlet.multipart.MultipartException; import com.elibom.jogger.http.servlet.multipart.PartHandler; import com.elibom.jogger.middleware.router.Route; import com.elibom.jogger.util.Preconditions; /** * A {@link com.elibom.jogger.http.Request} implementation based on the Servlet API. * * @author German Escobar */ public class ServletRequest extends AbstractRequest { /** * The underlying Servlet Request. */ private HttpServletRequest request; private Map<String,String> multipartParams = new HashMap<String,String>(); private List<FileItem> files = new ArrayList<FileItem>(); /** * Constructor. * * @param request the Servlet request object. * * @throws MultipartException if there is a problem parsing the multipart/form-data. * @throws IOException if there is a problem parsing the multipart/form-data. */ public ServletRequest(HttpServletRequest request) throws MultipartException, IOException { Preconditions.notNull(request, "no servlet request provided."); this.request = request; init(); } /** * Initializes the path variables and the multipart content. * * @throws MultipartException if there is a problem parsing the multipart/form-data. * @throws IOException if there is a problem parsing the multipart/form-data. */ private ServletRequest init() throws MultipartException, IOException { // retrieve multipart/form-data parameters if (Multipart.isMultipartContent(request)) { Multipart multipart = new Multipart(); multipart.parse(request, new PartHandler() { @Override public void handleFormItem(String name, String value) { multipartParams.put( name, value ); } @Override public void handleFileItem(String name, FileItem fileItem) { files.add(fileItem); } }); } return this; } private String join(String[] arr) { String ret = ""; for (String item : arr) { ret += "," + item; } if (ret.length() > 0) { ret = ret.substring(1); } return ret; } @Override public String getHost() { return request.getServerName(); } @Override public String getUrl() { return request.getRequestURL().toString(); } @Override public String getPath() { return Path.fixPath(request.getRequestURI()); } @Override public String getQueryString() { return request.getQueryString(); } @Override public Map<String,String> getParameters() { Map<String,String> params = new HashMap<String,String>(); Map<String,String[]> requestParams = request.getParameterMap(); for (Map.Entry<String,String[]> entry : requestParams.entrySet()) { params.put( entry.getKey(), join(entry.getValue()) ); } params.putAll(multipartParams); return Collections.unmodifiableMap(params); } @Override public String getParameter(String name) { String[] param = request.getParameterValues(name); if (param != null) { return join(param); } return multipartParams.get(name); } @Override public String getMethod() { return request.getMethod(); } @Override public String getRemoteAddress() { return request.getRemoteAddr(); } @Override public String getContentType() { return request.getContentType(); } @Override public int getPort() { return request.getServerPort(); } @Override public boolean isSecure() { return request.isSecure(); } @Override public boolean isAjax() { if (request.getHeader("x-requested-with") == null) { return false; } return "XMLHttpRequest".equals(request.getHeader("x-requested-with")); } @Override public Map<String,Cookie> getCookies() { javax.servlet.http.Cookie[] servletCookies = request.getCookies(); Map<String,Cookie> cookies = new HashMap<String,Cookie>(); for (javax.servlet.http.Cookie c : servletCookies) { cookies.put( c.getName(), map(c) ); } return Collections.unmodifiableMap(cookies); } @Override public Cookie getCookie(String name) { javax.servlet.http.Cookie[] servletCookies = request.getCookies(); if (servletCookies == null) { return null; } for (javax.servlet.http.Cookie c : servletCookies) { if (c.getName().equals(name)) { return map(c); } } return null; } private Cookie map(javax.servlet.http.Cookie servletCookie) { Cookie cookie = new Cookie(servletCookie.getName(), servletCookie.getValue(), servletCookie.getMaxAge(), servletCookie.isHttpOnly()); cookie.setPath(servletCookie.getPath()); cookie.setDomain(servletCookie.getDomain()); cookie.setSecure(servletCookie.getSecure()); return cookie; } @Override public Map<String, String> getHeaders() { Enumeration<String> servletHeaders = request.getHeaderNames(); Map<String,String> headers = new HashMap<String,String>(); while(servletHeaders.hasMoreElements()) { String headerName = servletHeaders.nextElement(); headers.put(headerName, request.getHeader(headerName)); } return headers; } @Override public String getHeader(String name) { return request.getHeader(name); } @Override public FileItem[] getFiles() { FileItem[] fileParts = new FileItem[files.size()]; for (int i=0; i < files.size(); i++) { fileParts[i] = files.get(i); } return fileParts; } @Override public BodyParser getBody() throws HttpException { BodyParser bodyParser = new BodyParser() { @Override public String asString() throws HttpException { try { BufferedReader reader = new BufferedReader( new InputStreamReader(request.getInputStream()) ); StringBuilder sb = new StringBuilder(); String line = reader.readLine(); while (line != null) { sb.append(line + "\n"); line = reader.readLine(); } reader.close(); String data = sb.toString(); return data; } catch (IOException e) { throw new HttpException(e); } } @Override public InputStream asInputStream() throws HttpException { try { return request.getInputStream(); } catch (IOException e) { throw new HttpException(e); } } }; return bodyParser; } @Override public void setRoute(Route route) { Preconditions.notNull(route, "no route provided."); this.route = route; initPathVariables(route.getPath()); } }