org.apache.wicket.protocol.http.mock.MockHttpServletRequest.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.wicket.protocol.http.mock.MockHttpServletRequest.java

Source

/*
 * 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.wicket.protocol.http.mock;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
import java.security.Principal;
import java.text.DateFormat;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import javax.servlet.AsyncContext;
import javax.servlet.DispatcherType;
import javax.servlet.ReadListener;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletInputStream;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpUpgradeHandler;
import javax.servlet.http.Part;

import org.apache.commons.fileupload.FileUploadBase;
import org.apache.wicket.Application;
import org.apache.wicket.WicketRuntimeException;
import org.apache.wicket.mock.MockRequestParameters;
import org.apache.wicket.request.Url;
import org.apache.wicket.request.Url.QueryParameter;
import org.apache.wicket.util.encoding.UrlDecoder;
import org.apache.wicket.util.encoding.UrlEncoder;
import org.apache.wicket.util.file.File;
import org.apache.wicket.util.io.IOUtils;
import org.apache.wicket.util.string.StringValue;
import org.apache.wicket.util.string.Strings;
import org.apache.wicket.util.value.ValueMap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Mock servlet request. Implements all of the methods from the standard HttpServletRequest class
 * plus helper methods to aid setting up a request.
 * 
 * @author Chris Turner
 */
public class MockHttpServletRequest implements HttpServletRequest {
    /**
     * A holder class for an uploaded file.
     * 
     * @author Frank Bille (billen)
     */
    private static class UploadedFile {
        private String fieldName;
        private File file;
        private String contentType;

        /**
         * Construct.
         * 
         * @param fieldName
         * @param file
         * @param contentType
         */
        public UploadedFile(String fieldName, File file, String contentType) {
            this.fieldName = fieldName;
            this.file = file;
            this.contentType = contentType;
        }

        /**
         * @return The content type of the file. Mime type.
         */
        public String getContentType() {
            return contentType;
        }

        /**
         * @param contentType
         *            The content type.
         */
        public void setContentType(String contentType) {
            this.contentType = contentType;
        }

        /**
         * @return The field name.
         */
        public String getFieldName() {
            return fieldName;
        }

        /**
         * @param fieldName
         */
        public void setFieldName(String fieldName) {
            this.fieldName = fieldName;
        }

        /**
         * @return The uploaded file.
         */
        public File getFile() {
            return file;
        }

        /**
         * @param file
         */
        public void setFile(File file) {
            this.file = file;
        }
    }

    /** Logging object */
    private static final Logger log = LoggerFactory.getLogger(MockHttpServletRequest.class);

    /** The application */
    private final Application application;

    private final ValueMap attributes = new ValueMap();

    private String authType;

    private String characterEncoding = "UTF-8";

    private final ServletContext context;

    private final Map<Cookies.Key, Cookie> cookies = new LinkedHashMap<>();

    private final ValueMap headers = new ValueMap();

    private String method;

    private final LinkedHashMap<String, String[]> parameters = new LinkedHashMap<>();

    private final LinkedHashMap<String, Part> parts = new LinkedHashMap<>();

    private String path;

    private final HttpSession session;

    private String url;

    private Map<String, List<UploadedFile>> uploadedFiles;

    private boolean useMultiPartContentType;

    private boolean secure = false;

    private String remoteAddr = "127.0.0.1";

    private String scheme = "http";

    private String serverName = "localhost";

    private int serverPort = 80;

    /**
     * Create the request using the supplied session object. Note that in order for temporary
     * sessions to work, the supplied session must be an instance of {@link MockHttpSession}
     * 
     * @param application
     *            The application that this request is for
     * @param session
     *            The session object
     * @param context
     *            The current servlet context
     * @param locale
     *            The current locale            
     */
    public MockHttpServletRequest(final Application application, final HttpSession session,
            final ServletContext context, Locale locale) {
        this.application = application;
        this.session = session;
        this.context = context;
        initialize(locale);
    }

    public MockHttpServletRequest(final Application application, final HttpSession session,
            final ServletContext context) {
        this(application, session, context, Locale.getDefault());
    }

    /**
     * Add a new cookie.
     * 
     * @param cookie
     *            The cookie
     */
    public void addCookie(final Cookie cookie) {
        cookies.put(Cookies.keyOf(cookie), cookie);
    }

    /**
     * @param cookies
     */
    public void addCookies(Iterable<Cookie> cookies) {
        for (Cookie cookie : cookies) {
            addCookie(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) {
            if (file.exists() == false) {
                throw new IllegalArgumentException(
                        "File does not exists. 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<>();
        }

        UploadedFile uf = new UploadedFile(fieldName, file, contentType);

        List<UploadedFile> filesPerField = uploadedFiles.get(fieldName);
        if (filesPerField == null) {
            filesPerField = new ArrayList<>();
            uploadedFiles.put(fieldName, filesPerField);
        }

        filesPerField.add(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) {
        @SuppressWarnings("unchecked")
        List<String> list = (List<String>) headers.get(name);
        if (list == null) {
            list = new ArrayList<>(1);
            headers.put(name, list);
        }
        list.add(value);
    }

    /**
     * Sets a header to the request. Overrides any previous value of this header.
     * 
     * @param name
     *            The name of the header to add
     * @param value
     *            The value
     * @see #addHeader(String, String)
     */
    public void setHeader(String name, String value) {
        @SuppressWarnings("unchecked")
        List<String> list = (List<String>) headers.get(name);
        if (list == null) {
            list = new ArrayList<>(1);
            headers.put(name, list);
        }
        list.clear();
        list.add(value);
    }

    /**
     * @param name
     * @param date
     */
    public void addDateHeader(String name, long date) {
        DateFormat df = DateFormat.getDateInstance(DateFormat.FULL);
        String dateString = df.format(new Date(date));
        addHeader(name, dateString);
    }

    /**
     * Get an attribute.
     * 
     * @param name
     *            The attribute name
     * @return The value, or null
     */
    @Override
    public Object getAttribute(final String name) {
        return attributes.get(name);
    }

    /**
     * Get the names of all of the values.
     * 
     * @return The names
     */
    @Override
    public Enumeration<String> getAttributeNames() {
        return Collections.enumeration(attributes.keySet());
    }

    // HttpServletRequest methods

    /**
     * Get the auth type.
     * 
     * @return The auth type
     */
    @Override
    public String getAuthType() {
        return authType;
    }

    /**
     * Get the current character encoding.
     * 
     * @return The character encoding
     */
    @Override
    public String getCharacterEncoding() {
        return characterEncoding;
    }

    /**
     * Get the current character set.
     * 
     * @return The character set
     */
    public Charset getCharset() {
        return Charset.forName(characterEncoding);
    }

    /**
     * true will force Request generate multiPart ContentType and ContentLength
     * 
     * @param useMultiPartContentType
     */
    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.
     */
    @Override
    public int getContentLength() {
        if (useMultiPartContentType) {
            byte[] request = buildRequest();
            return request.length;
        }

        return -1;
    }

    @Override
    public long getContentLengthLong() {
        return getContentLength();
    }

    /**
     * If useMultiPartContentType set as true return the correct content-type.
     * 
     * @return The correct multipart content-type if useMultiPartContentType is true. Else null.
     */
    @Override
    public String getContentType() {
        if (useMultiPartContentType) {
            return FileUploadBase.MULTIPART_FORM_DATA + "; boundary=abcdefgABCDEFG";
        }

        return null;
    }

    /**
     * Get the context path. For this mock implementation the name of the application is always
     * returned.
     * 
     * @return The context path
     */
    @Override
    public String getContextPath() {
        // return "/" + application.getName();
        return "/context";
    }

    /**
     * @param name
     * @return Cookie
     */
    public Cookie getCookie(String name) {
        Cookie[] cookies = getCookies();
        if (cookies == null) {
            return null;
        }
        for (Cookie cookie : cookies) {
            if (cookie.getName().equals(name)) {
                return Cookies.copyOf(cookie);
            }
        }
        return null;
    }

    /**
     * Get all of the cookies for this request.
     * 
     * @return The cookies
     */
    @Override
    public Cookie[] getCookies() {
        if (cookies.isEmpty()) {
            return null;
        }
        List<Cookie> cookieValues = new ArrayList<Cookie>();
        cookieValues.addAll(cookies.values());
        return cookieValues.toArray(new Cookie[cookieValues.size()]);
    }

    /**
     * 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
     */
    @Override
    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
     */
    @Override
    public String getHeader(final String name) {
        @SuppressWarnings("unchecked")
        final List<String> l = (List<String>) 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
     */
    @Override
    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
     */
    @Override
    public Enumeration<String> getHeaders(final String name) {
        @SuppressWarnings("unchecked")
        List<String> list = (List<String>) headers.get(name);
        if (list == null) {
            list = new ArrayList<String>();
        }
        return Collections.enumeration(list);
    }

    /**
     * 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
     */
    @Override
    public ServletInputStream getInputStream() throws IOException {
        byte[] request = buildRequest();

        // Ok lets make an input stream to return
        final ByteArrayInputStream bais = new ByteArrayInputStream(request);

        return new ServletInputStream() {
            private boolean isFinished = false;
            private boolean isReady = true;

            @Override
            public boolean isFinished() {
                return isFinished;
            }

            @Override
            public boolean isReady() {
                return isReady;
            }

            @Override
            public void setReadListener(ReadListener readListener) {
            }

            @Override
            public int read() {
                isFinished = true;
                isReady = false;
                return bais.read();
            }
        };
    }

    /**
     * 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
     */
    @Override
    public int getIntHeader(final String name) {
        String value = getHeader(name);
        if (value == null) {
            return -1;
        }
        return Integer.valueOf(value);
    }

    /**
     * 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
     */
    @Override
    public Locale getLocale() {
        return getLocales().nextElement();
    }

    public void setLocale(Locale locale) {
        setHeader("Accept-Language", locale.getLanguage() + '-' + locale.getCountry());
    }

    /**
     * 
     * @param value
     * @return locale
     */
    private Locale getLocale(final String value) {
        final String[] bits = Strings.split(value, '-');
        if (bits.length < 1) {
            return null;
        }

        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
     */
    @Override
    public Enumeration<Locale> getLocales() {
        List<Locale> list = new ArrayList<>();
        String header = getHeader("Accept-Language");
        if (header != null) {
            int idxOfSemicolon = header.indexOf(';');
            if (idxOfSemicolon > -1) {
                header = header.substring(0, idxOfSemicolon);
            }
            final String[] locales = Strings.split(header, ',');
            for (String value : locales) {
                Locale locale = getLocale(value);
                if (locale != null) {
                    list.add(locale);
                }
            }
        }

        if (list.size() == 0) {
            list.add(Locale.getDefault());
        }

        return Collections.enumeration(list);
    }

    /**
     * Get the method.
     * 
     * @return The method
     */
    @Override
    public String getMethod() {
        return method;
    }

    /**
     * Get the request parameter with the given name.
     * 
     * @param name
     *            The parameter name
     * @return The parameter value, or null
     */
    @Override
    public String getParameter(final String name) {
        String[] param = getParameterMap().get(name);
        if (param == null) {
            return null;
        } else {
            return param[0];
        }
    }

    /**
     * Get the map of all of the parameters.
     * 
     * @return The parameters
     */
    @Override
    public Map<String, String[]> getParameterMap() {
        Map<String, String[]> params = new HashMap<>(parameters);

        for (String name : post.getParameterNames()) {
            List<StringValue> values = post.getParameterValues(name);
            for (StringValue value : values) {
                String[] present = params.get(name);
                if (present == null) {
                    params.put(name, new String[] { value.toString() });
                } else {
                    String[] newval = new String[present.length + 1];
                    System.arraycopy(present, 0, newval, 0, present.length);
                    newval[newval.length - 1] = value.toString();
                    params.put(name, newval);
                }
            }
        }

        return params;
    }

    /**
     * Get the names of all of the parameters.
     * 
     * @return The parameter names
     */
    @Override
    public Enumeration<String> getParameterNames() {
        return Collections.enumeration(getParameterMap().keySet());
    }

    /**
     * Get the values for the given parameter.
     * 
     * @param name
     *            The name of the parameter
     * @return The return values
     */
    @Override
    public String[] getParameterValues(final String name) {
        Object value = getParameterMap().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
     */
    @Override
    public String getPathInfo() {
        return path;
    }

    /**
     * Always returns null.
     * 
     * @return null
     */
    @Override
    public String getPathTranslated() {
        return null;
    }

    /**
     * Get the protocol.
     * 
     * @return Always HTTP/1.1
     */
    @Override
    public String getProtocol() {
        return "HTTP/1.1";
    }

    /**
     * Get the query string part of the request.
     * 
     * @return The query string
     */
    @Override
    public String getQueryString() {
        if (parameters.size() == 0) {
            return null;
        } else {
            final StringBuilder buf = new StringBuilder();
            for (Iterator<String> iterator = parameters.keySet().iterator(); iterator.hasNext();) {
                final String name = iterator.next();
                final String[] values = getParameterValues(name);
                for (int i = 0; i < values.length; i++) {
                    if (name != null) {
                        buf.append(UrlEncoder.QUERY_INSTANCE.encode(name, getCharset()));
                    }
                    buf.append('=');
                    if (values[i] != null) {
                        buf.append(UrlEncoder.QUERY_INSTANCE.encode(values[i], getCharset()));
                    }
                    if (i + 1 < values.length) {
                        buf.append('&');
                    }
                }
                if (iterator.hasNext()) {
                    buf.append('&');
                }
            }
            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
     */
    @Override
    public BufferedReader getReader() throws IOException {
        return new BufferedReader(new InputStreamReader(getInputStream()));
    }

    /**
     * Deprecated method - should not be used.
     * 
     * @param name
     *            The name
     * @return The path
     * @deprecated Use ServletContext.getRealPath(String) instead.
     */
    @Override
    @Deprecated
    public String getRealPath(String name) {
        return context.getRealPath(name);
    }

    /**
     * @return the remote address of the client
     */
    @Override
    public String getRemoteAddr() {
        return remoteAddr;
    }

    /**
     * 
     * @param addr
     *            Format: "aaa.bbb.ccc.ddd"
     */
    public void setRemoteAddr(String addr) {
        remoteAddr = addr;
    }

    /**
     * Get the remote host.
     * 
     * @return Return 'localhost' by default
     */
    @Override
    public String getRemoteHost() {
        return "localhost";
    }

    /**
     * Get the name of the remote user from the REMOTE_USER header.
     * 
     * @return The name of the remote user
     */
    @Override
    public String getRemoteUser() {
        return getHeader("REMOTE_USER");
    }

    /**
     * Return a dummy dispatcher that just records that dispatch has occurred without actually doing
     * anything.
     * 
     * @param name
     *            The name to dispatch to
     * @return The dispatcher
     */
    @Override
    public RequestDispatcher getRequestDispatcher(String name) {
        return context.getRequestDispatcher(name);
    }

    /**
     * Get the requested session id. Always returns the id of the current session.
     * 
     * @return The session id
     */
    @Override
    public String getRequestedSessionId() {
        if (session instanceof MockHttpSession && ((MockHttpSession) session).isTemporary()) {
            return null;
        }
        return session.getId();
    }

    /**
     * Returns context path and servlet path concatenated, typically
     * /applicationClassName/applicationClassName
     * 
     * @return The path value
     * @see javax.servlet.http.HttpServletRequest#getRequestURI()
     */
    @Override
    public String getRequestURI() {
        if (url == null) {
            return getContextPath() + getServletPath();
        } else {
            int index = url.indexOf("?");
            if (index != -1) {
                return url.substring(0, index);
            }
        }
        return url;
    }

    /**
     * Try to build a rough URL.
     * 
     * @return The url
     * @see javax.servlet.http.HttpServletRequest#getRequestURL()
     */
    @Override
    public StringBuffer getRequestURL() {
        StringBuffer buf = new StringBuffer();
        buf.append("http://localhost");
        buf.append(getContextPath());
        if (getPathInfo() != null) {
            buf.append(getPathInfo());
        }

        // No query parameter. See
        // http://download.oracle.com/javaee/5/api/javax/servlet/http/HttpServletRequest.html#getRequestURL()
        return buf;
    }

    /**
     * Get the scheme.
     * 
     * @return the scheme of this request
     */
    @Override
    public String getScheme() {
        return scheme;
    }

    /**
     * Sets the scheme of this request
     * <p/>
     * set the <code>secure</code> flag accordingly (<code>true</code> for 'https',
     * <code>false</code> otherwise)
     * 
     * @param scheme
     *            protocol scheme (e.g. https, http, ftp)
     * 
     * @see #isSecure()
     */
    public void setScheme(String scheme) {
        this.scheme = scheme;
        secure = "https".equalsIgnoreCase(scheme);
    }

    /**
     * Get the server name.
     * 
     * @return by default returns 'localhost'
     */
    @Override
    public String getServerName() {
        return serverName;
    }

    /**
     * Set the server name.
     * 
     * @param serverName
     *            content of 'Host' header
     */
    public void setServerName(final String serverName) {
        this.serverName = serverName;
    }

    /**
     * @return the server port of this request
     */
    @Override
    public int getServerPort() {
        return serverPort;
    }

    /**
     * Sets the server port for this request
     * 
     * @param port
     */
    public void setServerPort(int port) {
        serverPort = port;
    }

    /**
     * The servlet path may either be the application name or /. For test purposes we always return
     * the servlet name.
     * 
     * @return The servlet path
     */
    @Override
    public String getServletPath() {
        return "/servlet";
    }

    /**
     * Get the sessions.
     * 
     * @return The session
     */
    @Override
    public HttpSession getSession() {
        return getSession(true);
    }

    @Override
    public String changeSessionId() {
        final HttpSession oldSession = getSession(false);
        if (oldSession == null) {
            throw new IllegalStateException("There is no active session associated with the current request");
        }
        oldSession.invalidate();

        final HttpSession newSession = getSession(true);

        return newSession.getId();
    }

    /**
     * Get the session.
     * 
     * @param b
     *            Ignored, there is always a session
     * @return The session
     */
    @Override
    public HttpSession getSession(boolean b) {
        HttpSession sess = null;
        if (session instanceof MockHttpSession) {
            MockHttpSession mockHttpSession = (MockHttpSession) session;
            if (b) {
                mockHttpSession.setTemporary(false);
            }

            if (mockHttpSession.isTemporary() == false) {
                sess = session;
            }
        }
        return sess;
    }

    /**
     * Get the user principal.
     * 
     * @return A user principal
     */
    @Override
    public Principal getUserPrincipal() {
        final String user = getRemoteUser();
        if (user == null) {
            return null;
        } else {
            return new Principal() {
                @Override
                public String getName() {
                    return user;
                }
            };
        }
    }

    /**
     * @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.
     * @param locale 
     */
    public void initialize(Locale locale) {
        authType = null;
        method = "post";
        cookies.clear();
        setDefaultHeaders(locale);
        path = null;
        url = null;
        characterEncoding = "UTF-8";
        parameters.clear();
        attributes.clear();
        post.reset();
    }

    /**
     * Check whether session id is from a cookie. Always returns true.
     * 
     * @return Always true
     */
    @Override
    public boolean isRequestedSessionIdFromCookie() {
        return true;
    }

    /**
     * Check whether session id is from a url rewrite. Always returns false.
     * 
     * @return Always false
     */
    @Override
    public boolean isRequestedSessionIdFromUrl() {
        return false;
    }

    @Override
    public boolean authenticate(HttpServletResponse response) throws IOException, ServletException {
        return false;
    }

    @Override
    public void login(String username, String password) throws ServletException {
    }

    @Override
    public void logout() throws ServletException {
    }

    @Override
    public Collection<Part> getParts() throws IOException, ServletException {
        return parts.values();
    }

    @Override
    public Part getPart(String name) throws IOException, ServletException {
        return parts.get(name);
    }

    @Override
    public <T extends HttpUpgradeHandler> T upgrade(Class<T> aClass) throws IOException, ServletException {
        return null;
    }

    public MockHttpServletRequest setPart(String name, Part part) {
        parts.put(name, part);
        return this;
    }

    /**
     * Check whether session id is from a url rewrite. Always returns false.
     * 
     * @return Always false
     */
    @Override
    public boolean isRequestedSessionIdFromURL() {
        return false;
    }

    /**
     * Check whether the session id is valid.
     * 
     * @return Always true
     */
    @Override
    public boolean isRequestedSessionIdValid() {
        return true;
    }

    /**
     * @return <code>true</code> if this request's scheme is 'https', <code>false</code> - otherwise
     */
    @Override
    public boolean isSecure() {
        return secure;
    }

    /**
     * 
     * @param secure
     */
    public void setSecure(boolean secure) {
        this.secure = secure;
    }

    /**
     * NOT IMPLEMENTED.
     * 
     * @param name
     *            The role name
     * @return Always false
     */
    @Override
    public boolean isUserInRole(String name) {
        return false;
    }

    /**
     * Remove the given attribute.
     * 
     * @param name
     *            The name of the attribute
     */
    @Override
    public void removeAttribute(final String name) {
        attributes.remove(name);
    }

    /**
     * Set the given attribute.
     * 
     * @param name
     *            The attribute name
     * @param o
     *            The value to set
     */
    @Override
    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
     */
    @Override
    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();
        addCookies(Arrays.asList(theCookies));
    }

    /**
     * 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) {
        if (value == null) {
            parameters.remove(name);
        } else {
            parameters.put(name, new String[] { value });
        }
    }

    /**
     * @param name
     * @param value
     */
    public void addParameter(final String name, final String value) {
        if (value == null) {
            return;
        }
        String[] val = parameters.get(name);
        if (val == null) {
            parameters.put(name, new String[] { value });
        } else {
            String[] newval = new String[val.length + 1];
            System.arraycopy(val, 0, newval, 0, val.length);
            newval[val.length] = value;
            parameters.put(name, newval);
        }
    }

    /**
     * Sets a map of parameters.
     * 
     * @param parameters
     *            the parameters to set
     */
    public void setParameters(final Map<String, String[]> 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
     */
    public void setPath(final String path) {
        this.path = UrlDecoder.PATH_INSTANCE.decode(path, getCharset());
    }

    /**
     * Set the complete url for this request. The url will be analyzed.
     * 
     * @param url
     */
    public void setURL(String url) {
        setUrl(Url.parse(url));
    }

    /**
     * Helper method to create some default headers for the request
     * @param l 
     */
    private void setDefaultHeaders(Locale l) {
        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");
        addHeader("Accept-Language", l.getLanguage().toLowerCase() + "-" + l.getCountry().toLowerCase() + ","
                + l.getLanguage().toLowerCase() + ";q=0.5");
        addHeader("User-Agent", "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:41.0) Gecko/20100101 Firefox/41.0");
    }

    private static final String crlf = "\r\n";
    private static final String boundary = "--abcdefgABCDEFG";

    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() {
        if (uploadedFiles == null && useMultiPartContentType == false) {
            if (post.getParameterNames().size() == 0) {
                return "".getBytes();
            }
            Url url = new Url();
            for (final String parameterName : post.getParameterNames()) {
                List<StringValue> values = post.getParameterValues(parameterName);
                for (StringValue value : values) {
                    url.addQueryParameter(parameterName, value.toString());
                }
            }
            String body = url.toString().substring(1);
            return body.getBytes();
        }

        try {
            // Build up the input stream based on the files and parameters
            ByteArrayOutputStream out = new ByteArrayOutputStream();

            // Add parameters
            for (final String parameterName : post.getParameterNames()) {
                List<StringValue> values = post.getParameterValues(parameterName);
                for (StringValue value : values) {
                    newAttachment(out);
                    out.write("; name=\"".getBytes());
                    out.write(parameterName.getBytes());
                    out.write("\"".getBytes());
                    out.write(crlf.getBytes());
                    out.write(crlf.getBytes());
                    out.write(value.toString().getBytes());
                    out.write(crlf.getBytes());
                }
            }

            // Add files
            if (uploadedFiles != null) {
                for (Map.Entry<String, List<UploadedFile>> entry : uploadedFiles.entrySet()) {
                    String fieldName = entry.getKey();
                    List<UploadedFile> files = entry.getValue();

                    for (UploadedFile uf : files) {
                        newAttachment(out);
                        out.write("; name=\"".getBytes());
                        out.write(fieldName.getBytes());
                        out.write("\"; filename=\"".getBytes());
                        if (uf.getFile() != null) {
                            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());

                        if (uf.getFile() != null) {
                            // Load the file and put it into the the inputstream
                            FileInputStream fis = new FileInputStream(uf.getFile());

                            try {
                                IOUtils.copy(fis, out);
                            } finally {
                                fis.close();
                            }
                        }
                        out.write(crlf.getBytes());
                    }
                }
            }

            out.write(boundary.getBytes());
            out.write("--".getBytes());
            out.write(crlf.getBytes());
            return out.toByteArray();
        } catch (IOException e) {
            // NOTE: IllegalStateException(Throwable) only exists since Java 1.5
            throw new WicketRuntimeException(e);
        }
    }

    /**
     * @return local address
     */
    @Override
    public String getLocalAddr() {
        return "127.0.0.1";
    }

    /**
     * @return local host name
     */
    @Override
    public String getLocalName() {
        return "127.0.0.1";
    }

    /**
     * @return local port
     */
    @Override
    public int getLocalPort() {
        return 80;
    }

    /**
     * @return remote port
     */
    @Override
    public int getRemotePort() {
        return 80;
    }

    /**
     * @param url
     */
    public void setUrl(Url url) {
        if (url.getProtocol() != null) {
            setScheme(url.getProtocol());
        }
        if (url.getHost() != null) {
            serverName = url.getHost();
        }
        if (url.getPort() != null) {
            serverPort = url.getPort();
        }
        String path = url.getPath(getCharset());

        if (path.startsWith("/") == false) {
            path = getContextPath() + getServletPath() + '/' + path;
        }
        this.url = path;

        if (path.startsWith(getContextPath())) {
            path = path.substring(getContextPath().length());
        }
        if (path.startsWith(getServletPath())) {
            path = path.substring(getServletPath().length());
        }

        setPath(path);

        //
        // We can't clear the parameters here because users may have set custom
        // parameters in request. An better place to clear they is when tester
        // setups the next request cycle
        //
        // parameters.clear();

        for (QueryParameter parameter : url.getQueryParameters()) {
            addParameter(parameter.getName(), parameter.getValue());
        }
    }

    /**
     * @return request url
     */
    public Url getUrl() {
        final String urlString;
        final String queryString = getQueryString();

        if (Strings.isEmpty(queryString)) {
            urlString = getRequestURI();
        } else {
            urlString = getRequestURI() + '?' + queryString;
        }

        final Url url = Url.parse(urlString, getCharset());
        url.setProtocol(scheme);
        url.setHost(serverName);
        url.setPort(serverPort);
        return url;
    }

    /**
     * @return post parameters
     */
    public MockRequestParameters getPostParameters() {
        return post;
    }

    /**
     * @return filter prefix
     */
    public String getFilterPrefix() {
        return getServletPath().substring(1);
    }

    private final MockRequestParameters post = new MockRequestParameters();

    /**
     * @return ServletContext
     */
    public ServletContext getServletContext() {
        return context;
    }

    @Override
    public AsyncContext startAsync() throws IllegalStateException {
        return null;
    }

    @Override
    public AsyncContext startAsync(ServletRequest servletRequest, ServletResponse servletResponse)
            throws IllegalStateException {
        return null;
    }

    @Override
    public boolean isAsyncStarted() {
        return false;
    }

    @Override
    public boolean isAsyncSupported() {
        return false;
    }

    @Override
    public AsyncContext getAsyncContext() {
        return null;
    }

    @Override
    public DispatcherType getDispatcherType() {
        return null;
    }

}