Java tutorial
/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you 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 org.apache.click.servlet; import java.io.BufferedReader; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.CharArrayReader; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.OutputStream; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; import java.security.Principal; import java.text.DateFormat; import java.text.ParseException; import java.util.ArrayList; import java.util.Collections; import java.util.Enumeration; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Random; import javax.servlet.RequestDispatcher; import javax.servlet.ServletContext; import javax.servlet.ServletInputStream; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; import org.apache.click.util.ClickUtils; import org.apache.commons.fileupload.FileUploadBase; import org.apache.commons.io.IOUtils; import org.apache.commons.lang.StringUtils; /** * Mock implementation of {@link javax.servlet.http.HttpServletRequest}. * <p/> * Implements all of the methods from the standard HttpServletRequest class * plus helper methods to aid setting up a request. * <p/> * This class was adapted from <a href="http://wicket.apache.org">Apache Wicket</a>. */ public class MockRequest implements HttpServletRequest { // -------------------------------------------------------- Constants /** Newline indicator. */ private static final String CRLF = "\r\n"; /** File attachment boundary indicator. */ private static final String BOUNDARY = "--abcdefgABCDEFG"; /** The REMOTE_USER header. */ public static final String REMOTE_USER = "REMOTE_USER"; // -------------------------------------------------------- Variables /** The request default locale. */ private Locale locale = Locale.getDefault(); /** The request attributes map. */ private final Map<String, Object> attributes = new HashMap<String, Object>(); /** The request authentication type (BASIC, FORM, DIGEST, CLIENT_CERT). */ private String authType; /** The request character encoding. */ private String characterEncoding; /** The request servlet context. */ private ServletContext servletContext; /** The request list of cookies. */ private final List<Cookie> cookies = new ArrayList<Cookie>(); /** The request headers map. */ private final Map<String, List<String>> headers = new HashMap<String, List<String>>(); /** The name of the HTTP method with which this request was made. */ private String method = "POST"; /** The request parameter map. */ private final Map<String, Object> parameters = new HashMap<String, Object>(); /** The request HTTP session. */ private HttpSession session; /** * Map of uploaded files, where the fieldname is the key and uploaded file * is the value. */ private Map<String, UploadedFile> uploadedFiles = new HashMap<String, UploadedFile>(); /** * Indicates if this request is multipart (contains binary attachment) or * not, false by default. */ private boolean useMultiPartContentType; /** The url that was forwarded to. */ private String forward; /** The list of server side included url's. */ private List<String> includes = new ArrayList<String>(); /** The scheme used to make this request, defaults to "http". */ private String scheme = "http"; /** The request context path, defaults to {@link MockServletContext#DEFAULT_CONTEXT_PATH}. */ private String contextPath = MockServletContext.DEFAULT_CONTEXT_PATH; /** The request servlet path, defaults to an empty String "". */ private String servletPath = ""; /** The request path info, defaults to an empty String "". */ private String pathInfo = ""; /** The host name to which the request was sent, defaults to "localhost". */ private String serverName = "localhost"; /** The port number to which the request was sent, defaults to 8080. */ private int serverPort = 8080; /** A random number generator to create unique session id's. */ private Random random = new Random(); /** The user principal. */ private Principal userPrincipal; /** * Create new MockRequest. */ public MockRequest() { initialize(); } /** * Create new MockRequest for the specified local. * * @param locale locale for this request */ public MockRequest(final Locale locale) { this(locale, null); } /** * Create a new MockRequest for the specified context. * * @param servletContext the servletContext for this request */ public MockRequest(final ServletContext servletContext) { this(null, servletContext); } /** * Create a new MockRequest for the specified locale and servletContext. * * @param locale locale for this request * @param servletContext the servletContext for this request */ public MockRequest(final Locale locale, final ServletContext servletContext) { this(locale, servletContext, null); } /** * Create a new MockRequest for the specified arguments. * * @param locale The request locale, or null to use the default locale * @param session The session object * @param servletContext The current servlet context */ public MockRequest(final Locale locale, final ServletContext servletContext, final HttpSession session) { this(locale, MockServletContext.DEFAULT_CONTEXT_PATH, "", servletContext, session); } /** * Create a new MockRequest for the specified arguments. * * @param locale The request locale, or null to use the default locale * @param contextPath the request context path * @param servletPath the request servlet path * @param servletContext The current servlet context * @param session the request session */ public MockRequest(Locale locale, String contextPath, String servletPath, final ServletContext servletContext, final HttpSession session) { if (locale != null) { this.locale = locale; } this.contextPath = contextPath; this.servletPath = servletPath; this.session = session; this.servletContext = servletContext; initialize(); } // -------------------------------------------------------- Mock intialization methods /** * Set the request's servletContext instance. * * @param servletContext the new ServletContext instance */ public void setServletContext(ServletContext servletContext) { this.servletContext = servletContext; } /** * Set the request's session instance. * * @param session the new HttpSession instance */ public void setHttpSession(HttpSession session) { this.session = session; } /** * Add a new cookie. * * @param cookie The cookie */ public void addCookie(final Cookie cookie) { cookies.add(cookie); } /** * Add an uploaded file to the request. Use this to simulate a file that * has been uploaded to a field. * * @param fieldName The fieldname of the upload field. * @param file The file to upload. * @param contentType The content type of the file. Must be a correct * mimetype. */ public void addFile(String fieldName, File file, String contentType) { if (file == null) { throw new IllegalArgumentException("File must not be null"); } if (file.exists() == false) { throw new IllegalArgumentException( "File does not exist. You must provide an existing file: " + file.getAbsolutePath()); } if (file.isFile() == false) { throw new IllegalArgumentException( "You can only add a File, which is not a directory. Only files " + "can be uploaded."); } if (uploadedFiles == null) { uploadedFiles = new HashMap<String, UploadedFile>(); } UploadedFile uf = new UploadedFile(fieldName, file, contentType); uploadedFiles.put(fieldName, uf); setUseMultiPartContentType(true); } /** * Add a header to the request. * * @param name the name of the header to add * @param value the value */ public void addHeader(String name, String value) { List<String> list = headers.get(name); if (list == null) { list = new ArrayList<String>(1); headers.put(name, list); } list.add(value); } /** * Set request header value. The existing header value will be replaced. * * @param name the name of the header to set * @param value the header value */ public void setHeader(String name, String value) { setHeader(name, new String[] { value }); } /** * Set request header values. The existing header values will be replaced. * * @param name the name of the header to set * @param values the header values */ public void setHeader(String name, String... values) { List<String> list = new ArrayList<String>(values.length); headers.put(name, list); for (String value : values) { list.add(value); } } /** * Get an attribute. * * @param name The attribute name * @return The value, or null */ public Object getAttribute(final String name) { return attributes.get(name); } /** * Get the names of all of the values. * * @return The names */ public Enumeration<String> getAttributeNames() { return Collections.enumeration(attributes.keySet()); } // -------------------------------------------------------- HttpServletRequest methods /** * Get the auth type. * * @return The auth type */ public String getAuthType() { return authType; } /** * Get the current character encoding. * * @return The character encoding */ public String getCharacterEncoding() { return characterEncoding; } /** * True will force Request to generate multiPart ContentType and ContentLength. * * @param useMultiPartContentType true if the request is multi-part, false * otherwise */ public void setUseMultiPartContentType(boolean useMultiPartContentType) { this.useMultiPartContentType = useMultiPartContentType; } /** * Return the length of the content. This is always -1 except if * useMultiPartContentType set as true. Then the length will be the length * of the generated request. * * @return -1 if useMultiPartContentType is false. Else the length of the * generated request. */ public int getContentLength() { if (useMultiPartContentType) { byte[] request = buildRequest(); return request.length; } return -1; } /** * If useMultiPartContentType set as true return the correct content-type. * * @return The correct multipart content-type if useMultiPartContentType * is true. Else null. */ public String getContentType() { if (useMultiPartContentType) { return FileUploadBase.MULTIPART_FORM_DATA + "; boundary=abcdefgABCDEFG"; } return null; } /** * Get all of the cookies for this request. * * @return The cookies */ public Cookie[] getCookies() { if (cookies.size() == 0) { return null; } Cookie[] result = new Cookie[cookies.size()]; return cookies.toArray(result); } /** * Get the given header as a date. * * @param name The header name * @return The date, or -1 if header not found * @throws IllegalArgumentException If the header cannot be converted */ public long getDateHeader(final String name) throws IllegalArgumentException { String value = getHeader(name); if (value == null) { return -1; } DateFormat df = DateFormat.getDateInstance(DateFormat.FULL); try { return df.parse(value).getTime(); } catch (ParseException e) { throw new IllegalArgumentException("Can't convert header to date " + name + ": " + value); } } /** * Get the given header value. * * @param name The header name * @return The header value or null */ public String getHeader(final String name) { final List<String> l = headers.get(name); if (l == null || l.size() < 1) { return null; } else { return l.get(0); } } /** * Get the names of all of the headers. * * @return The header names */ public Enumeration<String> getHeaderNames() { return Collections.enumeration(headers.keySet()); } /** * Get enumeration of all header values with the given name. * * @param name The name * @return The header values */ public Enumeration<String> getHeaders(final String name) { List<String> list = headers.get(name); if (list == null) { list = new ArrayList<String>(); } return Collections.enumeration(list); } /** * Return the map of headers for this request. * * @return the map of headers for this request */ public Map<String, List<String>> getHeaders() { return headers; } /** * Returns an input stream if there has been added some uploaded files. Use * {@link #addFile(String, File, String)} to add some uploaded files. * * @return The input stream * @throws IOException If an I/O related problem occurs */ public ServletInputStream getInputStream() throws IOException { if (uploadedFiles != null && uploadedFiles.size() > 0) { byte[] request = buildRequest(); // Ok lets make an input stream to return final ByteArrayInputStream bais = new ByteArrayInputStream(request); return new ServletInputStream() { @Override public int read() { return bais.read(); } }; } else { return new ServletInputStream() { @Override public int read() { return -1; } }; } } /** * Get the given header as an int. * * @param name The header name * @return The header value or -1 if header not found * @throws NumberFormatException If the header is not formatted correctly */ public int getIntHeader(final String name) { String value = getHeader(name); if (value == null) { return -1; } return Integer.valueOf(value).intValue(); } /** * Get the locale of the request. Attempts to decode the Accept-Language * header and if not found returns the default locale of the JVM. * * @return The locale */ public Locale getLocale() { final String header = getHeader("Accept-Language"); if (header == null) { return Locale.getDefault(); } final String[] firstLocale = header.split(","); if (firstLocale.length < 1) { return Locale.getDefault(); } final String[] bits = firstLocale[0].split("-"); if (bits.length < 1) { return Locale.getDefault(); } final String language = bits[0].toLowerCase(); if (bits.length > 1) { final String country = bits[1].toUpperCase(); return new Locale(language, country); } else { return new Locale(language); } } /** * Return all the accepted locales. This implementation always returns just * one. * * @return The locales */ public Enumeration<Locale> getLocales() { List<Locale> list = new ArrayList<Locale>(1); list.add(getLocale()); return Collections.enumeration(list); } /** * Get the method. * <p/> * The returned string will be in upper case eg. <tt>POST</tt>. * * @return The method */ public String getMethod() { return StringUtils.upperCase(method); } /** * Get the request parameter with the given name. * * @param name The parameter name * @return The parameter value, or null */ public String getParameter(final String name) { Object value = parameters.get(name); if (value instanceof String[]) { return ((String[]) value)[0]; } else { return (String) value; } } /** * Get the map of all of the parameters. * * @return The parameters */ public Map<String, Object> getParameterMap() { return parameters; } /** * Get the names of all of the parameters. * * @return The parameter names */ public Enumeration<String> getParameterNames() { return Collections.enumeration(parameters.keySet()); } /** * Get the values for the given parameter. * * @param name The name of the parameter * @return The return values */ public String[] getParameterValues(final String name) { Object value = parameters.get(name); if (value == null) { return new String[0]; } if (value instanceof String[]) { return (String[]) value; } else { String[] result = new String[1]; result[0] = value.toString(); return result; } } /** * Get the path info. * * @return The path info */ public String getPathInfo() { return pathInfo; } /** * Always returns null. * * @return null */ public String getPathTranslated() { return null; } /** * Get the protocol. * * @return Always HTTP/1.1 */ public String getProtocol() { return "HTTP/1.1"; } /** * Get the query string part of the request. * * @return The query string */ public String getQueryString() { if (parameters.size() == 0) { return null; } else { final StringBuffer buf = new StringBuffer(); try { for (Iterator<String> iterator = parameters.keySet().iterator(); iterator.hasNext();) { final String name = iterator.next(); final Object value = parameters.get(name); if (value instanceof String[]) { String[] aValue = (String[]) value; for (int i = 0; i < aValue.length; i++) { buf.append(URLEncoder.encode(name, "UTF-8")); buf.append('='); buf.append(URLEncoder.encode(aValue[i], "UTF-8")); if (i < aValue.length) { buf.append("&"); } } } else { buf.append(URLEncoder.encode(name, "UTF-8")); buf.append('='); buf.append(URLEncoder.encode((String) value, "UTF-8")); } if (iterator.hasNext()) { buf.append("&"); } } } catch (UnsupportedEncodingException e) { // Should never happen! } return buf.toString(); } } /** * This feature is not implemented at this time as we are not supporting * binary servlet input. This functionality may be added in the future. * * @return The reader * @throws IOException If an I/O related problem occurs */ public BufferedReader getReader() throws IOException { return new BufferedReader(new CharArrayReader(new char[0])); } /** * Deprecated method - should not be used. * * @param name The name * * @return The path * * @deprecated Use ServletContext.getRealPath(String) instead. */ public String getRealPath(String name) { return servletContext.getRealPath(name); } /** * Get the remote address of the client. * * @return Always 127.0.0.1 */ public String getRemoteAddr() { return "127.0.0.1"; } /** * Get the remote host. * * @return Always localhost */ public String getRemoteHost() { return "localhost"; } /** * Return the name of the {@link #userPrincipal} if set, otherwise * the value of the {@value #REMOTE_USER} header. * <p/> * To set the remote user, create an instance of a {@link MockPrincipal} * and set it on the request through the method * {@link #setUserPrincipal(java.security.Principal)}. * * @return the name of the remote user */ public String getRemoteUser() { if (userPrincipal != null) { return userPrincipal.getName(); } return getHeader(REMOTE_USER); } /** * Return the local address, <em>"127.0.0.1"</em>. * * @return "127.0.0.1" as the local address */ public String getLocalAddr() { return "127.0.0.1"; } /** * Return the local name, <em>"127.0.0.1"</em>. * * @return "127.0.0.1" as the local name */ public String getLocalName() { return "127.0.0.1"; } /** * Return the local port, <em>80</em>. * * @return 80 as the local port */ public int getLocalPort() { return 80; } /** * Return the remote port, <em>80</em>. * * @return 80 as the remote port */ public int getRemotePort() { return 80; } /** * Returns a RequestDispatcher for the specified path. The dispatcher * will not dispatch to the resource. It only records the specified path * so that one can test if the correct path was dispatched to. * * @param path a String specifying the pathname to the resource * @return a dispatcher for the specified path */ public RequestDispatcher getRequestDispatcher(String path) { return servletContext.getRequestDispatcher(path); } /** * Get the requested session id. Always returns the id of the current * session. * * @return The session id */ public String getRequestedSessionId() { return session.getId(); } /** * Returns context path and servlet path concatenated, typically * <tt>/applicationClassName/applicationClassName</tt>. * * @return The path value * @see javax.servlet.http.HttpServletRequest#getRequestURI() */ public String getRequestURI() { return getContextPath() + getServletPath(); } /** * Returns (an attempt at) a reconstructed URL based on it's constituent * parts. * * @return a StringBuffer object containing the reconstructed URL */ public StringBuffer getRequestURL() { StringBuffer buffer = new StringBuffer().append(getScheme()); buffer.append("://"); buffer.append(this.getServerName()); buffer.append(":"); buffer.append(this.getServerPort()); buffer.append(this.contextPath); buffer.append(this.servletPath); if (getPathInfo() != null) { buffer.append(getPathInfo()); } if (!isPost()) { final String query = getQueryString(); if (query != null) { buffer.append('?'); buffer.append(query); } } return buffer; } /** * Return whether the request is a post or not. * * @return true if the request is a post, false otherwise */ public boolean isPost() { return getMethod().equalsIgnoreCase("post"); } /** * Get the scheme http, https, or ftp. * * @return the scheme used by this request */ public String getScheme() { return scheme; } /** * Set the request's scheme, for example http, https, or ftp. * * @param scheme the request's scheme */ public void setScheme(String scheme) { this.scheme = scheme; } /** * Get the host server name to which the request was sent. * * @return always the host server name */ public String getServerName() { return serverName; } /** * Sets the host server name to which the request was sent. * * @param serverName the server name the request was sent to */ public void setServerName(String serverName) { this.serverName = serverName; } /** * Returns the port number to which the request was sent. * * @return the server port to which the request was sent */ public int getServerPort() { return serverPort; } /** * Set the port number to which the request was sent. * * @param serverPort the port number to which the request was sent */ public void setServerPort(int serverPort) { this.serverPort = serverPort; } /** * Returns the portion of the request URI that indicates the context of the * request. * * @return the portion of the request URI that indicates the context of * the request. */ public String getContextPath() { // If request's contextPath was set manually (eg user set // servletContext's contextPath), return that value. if (!MockServletContext.DEFAULT_CONTEXT_PATH.equals(contextPath)) { return contextPath; } // If servletContext path was set manually (eg user set servletContext's // contextPath) then use that value in preference to the request default // contextPath. if (servletContext instanceof MockServletContext) { MockServletContext mockServletContext = (MockServletContext) servletContext; if (!MockServletContext.DEFAULT_CONTEXT_PATH.equals(mockServletContext.getContextPath())) { return mockServletContext.getContextPath(); } } // Lastly fallback to the default contextPath. return contextPath; } /** * Set the portion of the request URI that indicates the context of the * request. * * @param contextPath the portion of the request URI that indicates the * context of the request. */ public void setContextPath(String contextPath) { this.contextPath = contextPath; } /** * Return a String containing the name or path of the servlet being called. * * @return The servlet path */ public String getServletPath() { return servletPath; } /** * Set the string containing the name or path of the servlet being called. * * @param servletPath a String containing the name or path of the servlet * being called */ public void setServletPath(String servletPath) { this.servletPath = servletPath; } /** * Returns the current HttpSession associated with this request. * * @return the session associated with this request */ public HttpSession getSession() { return getSession(true); } /** * Set the current HttpSession associated with this request. * * @param session the HttpSession to associate with this request */ public void setSession(HttpSession session) { this.session = session; } /** * Returns the current HttpSession associated with this request. * * @param create if true creates a new session if one does not exist * @return the current HttpSession associated with this request. */ public HttpSession getSession(boolean create) { if (session != null) { return session; } if (create) { String sessionId = createSessionId(); session = new MockSession(sessionId, servletContext); } return session; } /** * Get the user principal. If no user principal was set this method will * create a user principal for the {@link #getRemoteUser()}. * * @return the user principal */ public Principal getUserPrincipal() { if (userPrincipal == null) { final String user = getRemoteUser(); if (user == null) { return null; } else { userPrincipal = new MockPrincipal() { @Override public String getName() { return user; } }; } } return userPrincipal; } /** * Set the user principal. * * @param userPrincipal the user principal */ public void setUserPrincipal(Principal userPrincipal) { this.userPrincipal = userPrincipal; } /** * @return True if there has been added files to this request using * {@link #addFile(String, File, String)}. */ public boolean hasUploadedFiles() { return uploadedFiles != null; } /** * Reset the request back to a default state. */ public final void initialize() { authType = null; method = "post"; cookies.clear(); setDefaultHeaders(); pathInfo = null; characterEncoding = "UTF-8"; parameters.clear(); attributes.clear(); } /** * Delegate to initialize method. */ public void reset() { initialize(); } /** * Check whether session id is from a cookie. Always returns true. * * @return Always true */ public boolean isRequestedSessionIdFromCookie() { return true; } /** * Check whether session id is from a url rewrite. Always returns false. * * @return Always false */ public boolean isRequestedSessionIdFromUrl() { return false; } /** * Check whether session id is from a url rewrite. Always returns false. * * @return Always false */ public boolean isRequestedSessionIdFromURL() { return false; } /** * Check whether the session id is valid. * * @return Always true */ public boolean isRequestedSessionIdValid() { return true; } /** * Always returns false. * * @return Always false */ public boolean isSecure() { return this.scheme.equalsIgnoreCase("https"); } /** * Returns true if the {@link #getUserPrincipal() authenticated user} is * included in the given role, false otherwise. * <p/> * To mock up roles for a user, create a {@link MockPrincipal user principal} * and set the necessary roles. See {@link MockPrincipal} for an example. * * @param role the role name * @return true if the user is included in the specified role, false * otherwise */ public boolean isUserInRole(String role) { Principal principal = getUserPrincipal(); if (principal instanceof MockPrincipal) { return ((MockPrincipal) principal).getRoles().contains(role); } return false; } /** * Remove the given attribute. * * @param name The name of the attribute */ public void removeAttribute(final String name) { attributes.remove(name); } /** * Set the given attribute. * * @param name The attribute name * @param o The value to set */ public void setAttribute(final String name, final Object o) { attributes.put(name, o); } /** * Set the auth type. * * @param authType The auth type */ public void setAuthType(final String authType) { this.authType = authType; } /** * Set the character encoding. * * @param encoding The character encoding * @throws UnsupportedEncodingException If encoding not supported */ public void setCharacterEncoding(final String encoding) throws UnsupportedEncodingException { characterEncoding = encoding; } /** * Set the cookies. * * @param theCookies The cookies */ public void setCookies(final Cookie[] theCookies) { cookies.clear(); for (int i = 0; i < theCookies.length; i++) { cookies.add(theCookies[i]); } } /** * Set the method. * * @param method The method */ public void setMethod(final String method) { this.method = method; } /** * Set a parameter. * * @param name The name * @param value The value */ public void setParameter(final String name, final String value) { parameters.put(name, value); } /** * Set the specified parameter name to the array of strings. * * @param name name of the parameter * @param values the parameter values */ public void setParameter(final String name, final String[] values) { parameters.put(name, values); } /** * Remove the specified parameter. * * @param name the parameter name to remove */ public void removeParameter(final String name) { parameters.remove(name); } /** * Sets a map of parameters. * * @param parameters the parameters to set */ public void setParameters(final Map<String, Object> parameters) { this.parameters.putAll(parameters); } /** * Set the path that this request is supposed to be serving. The path is * relative to the web application root and should start with a / character * * @param path specifies the request path to serve */ public void setPathInfo(final String path) { this.pathInfo = path; } /** * Returns the url that was forwarded to, otherwise return null. * * @see org.apache.click.servlet.MockRequestDispatcher#forward(javax.servlet.ServletRequest, * javax.servlet.ServletResponse) * * @return url that was forwarded to */ public String getForward() { return this.forward; } /** * Returns the list of server side included url's. * * @see org.apache.click.servlet.MockRequestDispatcher#include(javax.servlet.ServletRequest, * javax.servlet.ServletResponse) * * @return list of urls that were included */ public List<String> getIncludes() { return this.includes; } /** * Returns the String representation of the mock request. * * @return string representation of the mock request */ @Override public String toString() { return getRequestURL().toString(); } // ------------------------------------------------ package methods /** * MockRequestDispatcher adds server side included url's to the request. * * @param url the url to include */ void addInclude(String url) { this.includes.add(url); } /** * MockRequestDispatcher sets the forward url on the request. * * @param url the url to forward to */ void setForward(String url) { this.forward = url; } // -------------------------------------------------------- Private methods /** * Helper method to create some default headers for the request. */ private void setDefaultHeaders() { headers.clear(); addHeader("Accept", "text/xml,application/xml,application/xhtml+xml," + "text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5"); addHeader("Accept-Charset", "ISO-8859-1,utf-8;q=0.7,*;q=0.7"); Locale l = locale; addHeader("Accept-Language", l.getLanguage().toLowerCase() + "-" + l.getCountry().toLowerCase() + "," + l.getLanguage().toLowerCase() + ";q=0.5"); addHeader("User-Agent", "Mozilla/5.0 (Windows; U; Windows NT 5.0; en-US; rv:1.7) Gecko/20040707 Firefox/0.9.2"); } /** * Helper method to create new attachment. * * @param out the output stream to add attachment to * @throws java.io.IOException if an I/O error occurs */ private void newAttachment(OutputStream out) throws IOException { out.write(BOUNDARY.getBytes()); out.write(CRLF.getBytes()); out.write("Content-Disposition: form-data".getBytes()); } /** * Build the request based on the uploaded files and the parameters. * * @return The request as a string. */ private byte[] buildRequest() { try { // Build up the input stream based on the files and parameters ByteArrayOutputStream out = new ByteArrayOutputStream(); // Add parameters for (String name : parameters.keySet()) { newAttachment(out); out.write("; name=\"".getBytes()); out.write(name.getBytes()); out.write("\"".getBytes()); out.write(CRLF.getBytes()); out.write(CRLF.getBytes()); out.write(parameters.get(name).toString().getBytes()); out.write(CRLF.getBytes()); } // Add files if (uploadedFiles != null) { for (String fieldName : uploadedFiles.keySet()) { UploadedFile uf = uploadedFiles.get(fieldName); newAttachment(out); out.write("; name=\"".getBytes()); out.write(fieldName.getBytes()); out.write("\"; filename=\"".getBytes()); out.write(uf.getFile().getName().getBytes()); out.write("\"".getBytes()); out.write(CRLF.getBytes()); out.write("Content-Type: ".getBytes()); out.write(uf.getContentType().getBytes()); out.write(CRLF.getBytes()); out.write(CRLF.getBytes()); // Load the file and put it into the the inputstream FileInputStream fis = new FileInputStream(uf.getFile()); IOUtils.copy(fis, out); fis.close(); out.write(CRLF.getBytes()); } } out.write(BOUNDARY.getBytes()); out.write("--".getBytes()); out.write(CRLF.getBytes()); return out.toByteArray(); } catch (IOException e) { throw new RuntimeException(e); } } /** * Create and return a new session id. * * @return new session id */ private String createSessionId() { String mockId = getRemoteAddr().replaceAll("\\.", "") + "_" + System.currentTimeMillis() + "_" + Math.abs(random.nextLong()); try { //make it look secure ;-) mockId = ClickUtils.toMD5Hash(mockId); } catch (Exception e) { //ignore } return mockId; } /** * A holder class for an uploaded file. * * @author Frank Bille (billen) */ private static class UploadedFile { /** Name of the file field. */ private String fieldName; /** The uploaded file. */ private File file; /** The uploaded file content type. */ private String contentType; /** * Construct. * * @param fieldName name of the file field * @param file the uploaded file * @param contentType the uploaded file content type */ public UploadedFile(String fieldName, File file, String contentType) { this.fieldName = fieldName; this.file = file; this.contentType = contentType; } /** * Return the uploaded file content type. * * @return The content type of the file. Mime type. */ public String getContentType() { return contentType; } /** * Set the uploaded file content type. * * @param contentType The content type. */ @SuppressWarnings("unused") public void setContentType(String contentType) { this.contentType = contentType; } /** * Return the file field name. * * @return The field name. */ @SuppressWarnings("unused") public String getFieldName() { return fieldName; } /** * Set the file field name. * * @param fieldName the name of the file field */ @SuppressWarnings("unused") public void setFieldName(String fieldName) { this.fieldName = fieldName; } /** * Return the uploaded file. * * @return The uploaded file. */ public File getFile() { return file; } /** * Set the uploaded file. * * @param file the uploaded file */ @SuppressWarnings("unused") public void setFile(File file) { this.file = file; } } }