/*
 *  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.coyote;

import java.io.IOException;
import java.io.StringReader;
import java.time.Instant;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.AtomicReference;

import jakarta.servlet.ReadListener;
import jakarta.servlet.ServletConnection;

import org.apache.tomcat.util.buf.CharsetHolder;
import org.apache.tomcat.util.buf.MessageBytes;
import org.apache.tomcat.util.buf.UDecoder;
import org.apache.tomcat.util.http.Method;
import org.apache.tomcat.util.http.MimeHeaders;
import org.apache.tomcat.util.http.Parameters;
import org.apache.tomcat.util.http.ServerCookies;
import org.apache.tomcat.util.http.parser.MediaType;
import org.apache.tomcat.util.net.ApplicationBufferHandler;
import org.apache.tomcat.util.res.StringManager;

/**
 * This is a low-level, efficient representation of a server request. Most fields are GC-free, expensive operations are
 * delayed until the user code needs the information. Processing is delegated to modules, using a hook mechanism. This
 * class is not intended for user code - it is used internally by tomcat for processing the request in the most
 * efficient way. Users ( servlets ) can access the information using a facade, which provides the high-level view of
 * the request. Tomcat defines a number of attributes:
 * <ul>
 * <li>"org.apache.tomcat.request" - allows access to the low-level request object in trusted applications
 * </ul>
 */
public final class Request {

    private static final StringManager sm = StringManager.getManager(Request.class);

    // Expected maximum typical number of cookies per request.
    private static final int INITIAL_COOKIE_SIZE = 4;

    /*
     * At 100,000 requests a second there are enough IDs here for ~3,000,000 years before it overflows (and then we have
     * another 3,000,000 years before it gets back to zero).
     *
     * Local testing shows that 5, 10, 50, 500 or 1000 threads can obtain 60,000,000+ IDs a second from a single
     * AtomicLong. That is about 17ns per request. It does not appear that the introduction of this counter will cause a
     * bottleneck for request processing.
     */
    private static final AtomicLong requestIdGenerator = new AtomicLong(0);

    // public static final int NOTE_ADAPTER = 1; // Defined in CoyoteAdapter
    /**
     * Note key for bad request.
     */
    public static final int NOTE_BAD_REQUEST = 2;


    // ----------------------------------------------------------- Constructors

    /**
     * Default constructor.
     */
    public Request() {
        parameters.setQuery(queryMB);
        parameters.setURLDecoder(urlDecoder);
    }


    // ----------------------------------------------------- Instance Variables

    private int serverPort = -1;
    private final MessageBytes serverNameMB = MessageBytes.newInstance();

    private int remotePort;
    private int localPort;

    private final MessageBytes schemeMB = MessageBytes.newInstance();

    private String method;
    private final MessageBytes uriMB = MessageBytes.newInstance();
    private final MessageBytes decodedUriMB = MessageBytes.newInstance();
    private final MessageBytes queryMB = MessageBytes.newInstance();
    private final MessageBytes protoMB = MessageBytes.newInstance();

    private volatile String requestId = Long.toString(requestIdGenerator.getAndIncrement());

    // remote address/host
    private final MessageBytes remoteAddrMB = MessageBytes.newInstance();
    private final MessageBytes peerAddrMB = MessageBytes.newInstance();
    private final MessageBytes localNameMB = MessageBytes.newInstance();
    private final MessageBytes remoteHostMB = MessageBytes.newInstance();
    private final MessageBytes localAddrMB = MessageBytes.newInstance();

    private final MimeHeaders headers = new MimeHeaders();
    private final MimeHeaders trailerFields = new MimeHeaders();

    /**
     * Path parameters
     */
    private final Map<String,String> pathParameters = new HashMap<>();

    /**
     * Notes.
     */
    private final Object[] notes = new Object[Constants.MAX_NOTES];


    /**
     * Associated input buffer.
     */
    private InputBuffer inputBuffer = null;


    /**
     * URL decoder.
     */
    private final UDecoder urlDecoder = new UDecoder();


    /**
     * HTTP specific fields. (remove them ?)
     */
    private long contentLength = -1;
    private MessageBytes contentTypeMB = null;
    private CharsetHolder charsetHolder = null;

    /**
     * Is there an expectation ?
     */
    private boolean expectation = false;

    private final ServerCookies serverCookies = new ServerCookies(INITIAL_COOKIE_SIZE);
    private final Parameters parameters = new Parameters();

    private final MessageBytes remoteUser = MessageBytes.newInstance();
    private boolean remoteUserNeedsAuthorization = false;
    private final MessageBytes authType = MessageBytes.newInstance();
    private final HashMap<String,Object> attributes = new HashMap<>();

    private Response response;
    private volatile ActionHook hook;

    private long bytesRead = 0;
    // Time of the request - useful to avoid repeated calls to System.currentTime
    private long startTimeNanos = -1;
    private Instant startInstant = null;
    private long threadId = 0;
    private int available = 0;

    private final RequestInfo reqProcessorMX = new RequestInfo(this);

    private boolean sendfile = true;

    /**
     * Holds request body reading error exception.
     */
    private Exception errorException = null;

    /*
     * State for non-blocking output is maintained here as it is the one point easily reachable from the
     * CoyoteInputStream and the CoyoteAdapter which both need access to state.
     */
    volatile ReadListener listener;
    // Ensures listener is only fired after a call is isReady()
    private boolean fireListener = false;
    // Tracks read registration to prevent duplicate registrations
    private boolean registeredForRead = false;
    // Lock used to manage concurrent access to above flags
    private final Object nonBlockingStateLock = new Object();

    /**
     * Return the read listener.
     *
     * @return the read listener
     */
    public ReadListener getReadListener() {
        return listener;
    }

    /**
     * Set the read listener for non-blocking reads.
     *
     * @param listener the read listener
     */
    public void setReadListener(ReadListener listener) {
        if (listener == null) {
            throw new NullPointerException(sm.getString("request.nullReadListener"));
        }
        if (getReadListener() != null) {
            throw new IllegalStateException(sm.getString("request.readListenerSet"));
        }
        // Note: This class is not used for HTTP upgrade so only need to test
        // for async
        AtomicBoolean result = new AtomicBoolean(false);
        action(ActionCode.ASYNC_IS_ASYNC, result);
        if (!result.get()) {
            throw new IllegalStateException(sm.getString("request.notAsync"));
        }

        this.listener = listener;

        // The container is responsible for the first call to
        // listener.onDataAvailable(). If isReady() returns true, the container
        // needs to call listener.onDataAvailable() from a new thread. If
        // isReady() returns false, the socket will be registered for read and
        // the container will call listener.onDataAvailable() once data arrives.
        // Must call isFinished() first as a call to isReady() if the request
        // has been finished will register the socket for read interest and that
        // is not required.
        if (!isFinished() && isReady()) {
            synchronized (nonBlockingStateLock) {
                // Ensure we don't get multiple read registrations
                registeredForRead = true;
                // Need to set the fireListener flag otherwise when the
                // container tries to trigger onDataAvailable, nothing will
                // happen
                fireListener = true;
            }
            action(ActionCode.DISPATCH_READ, null);
            if (!isRequestThread()) {
                // Not on a container thread so need to execute the dispatch
                action(ActionCode.DISPATCH_EXECUTE, null);
            }
        }
    }

    /**
     * Check if the request is ready for reading.
     *
     * @return {@code true} if ready for reading
     */
    public boolean isReady() {
        // Assume read is not possible
        boolean ready;
        synchronized (nonBlockingStateLock) {
            if (registeredForRead) {
                fireListener = true;
                return false;
            }
            ready = checkRegisterForRead();
            fireListener = !ready;
        }
        return ready;
    }

    private boolean checkRegisterForRead() {
        AtomicBoolean ready = new AtomicBoolean(false);
        synchronized (nonBlockingStateLock) {
            if (!registeredForRead) {
                action(ActionCode.NB_READ_INTEREST, ready);
                registeredForRead = !ready.get();
            }
        }
        return ready.get();
    }

    /**
     * Called when data is available for reading.
     *
     * @throws IOException if an I/O error occurs
     */
    public void onDataAvailable() throws IOException {
        boolean fire = false;
        synchronized (nonBlockingStateLock) {
            registeredForRead = false;
            if (fireListener) {
                fireListener = false;
                fire = true;
            }
        }
        if (fire) {
            listener.onDataAvailable();
        }
    }


    private final AtomicBoolean allDataReadEventSent = new AtomicBoolean(false);

    /**
     * Send the all-data-read event.
     *
     * @return {@code true} if the event was sent
     */
    public boolean sendAllDataReadEvent() {
        return allDataReadEventSent.compareAndSet(false, true);
    }


    // ------------------------------------------------------------- Properties

    /**
     * Return the MIME headers.
     *
     * @return the MIME headers
     */
    public MimeHeaders getMimeHeaders() {
        return headers;
    }


    /**
     * Check if trailer fields are ready.
     *
     * @return {@code true} if trailer fields are ready
     */
    public boolean isTrailerFieldsReady() {
        AtomicBoolean result = new AtomicBoolean(false);
        action(ActionCode.IS_TRAILER_FIELDS_READY, result);
        return result.get();
    }


    /**
     * Return the trailer fields as a map.
     *
     * @return the trailer fields
     */
    public Map<String,String> getTrailerFields() {
        return trailerFields.toMap();
    }


    /**
     * Return the MIME trailer fields.
     *
     * @return the MIME trailer fields
     */
    public MimeHeaders getMimeTrailerFields() {
        return trailerFields;
    }


    /**
     * Return the URL decoder.
     *
     * @return the URL decoder
     */
    public UDecoder getURLDecoder() {
        return urlDecoder;
    }


    // -------------------- Request data --------------------

    /**
     * Return the scheme (e.g. "http" or "https").
     *
     * @return the scheme
     */
    public MessageBytes scheme() {
        return schemeMB;
    }

    /**
     * Set the HTTP method.
     *
     * @param method the HTTP method
     */
    public void setMethod(String method) {
        this.method = method;
    }

    /**
     * Set the HTTP method from a byte buffer.
     *
     * @param buf the byte buffer
     * @param start the start offset
     * @param len the length
     */
    public void setMethod(byte[] buf, int start, int len) {
        this.method = Method.bytesToString(buf, start, len);
    }

    /**
     * Return the HTTP method.
     *
     * @return the HTTP method
     */
    public String getMethod() {
        return method;
    }

    /**
     * Return the request URI.
     *
     * @return the request URI
     */
    public MessageBytes requestURI() {
        return uriMB;
    }

    /**
     * Return the decoded request URI.
     *
     * @return the decoded URI
     */
    public MessageBytes decodedURI() {
        return decodedUriMB;
    }

    /**
     * Return the query string.
     *
     * @return the query string
     */
    public MessageBytes queryString() {
        return queryMB;
    }

    /**
     * Return the protocol.
     *
     * @return the protocol
     */
    public MessageBytes protocol() {
        return protoMB;
    }

    /**
     * Get the "virtual host", derived from the Host: header associated with this request.
     *
     * @return The buffer holding the server name, if any. Use isNull() to check if there is no value set.
     */
    public MessageBytes serverName() {
        return serverNameMB;
    }

    /**
     * Return the server port.
     *
     * @return the server port
     */
    public int getServerPort() {
        return serverPort;
    }

    /**
     * Set the server port.
     *
     * @param serverPort the server port
     */
    public void setServerPort(int serverPort) {
        this.serverPort = serverPort;
    }

    /**
     * Return the remote address.
     *
     * @return the remote address
     */
    public MessageBytes remoteAddr() {
        return remoteAddrMB;
    }

    /**
     * Return the peer address.
     *
     * @return the peer address
     */
    public MessageBytes peerAddr() {
        return peerAddrMB;
    }

    /**
     * Return the remote host.
     *
     * @return the remote host
     */
    public MessageBytes remoteHost() {
        return remoteHostMB;
    }

    /**
     * Return the local name.
     *
     * @return the local name
     */
    public MessageBytes localName() {
        return localNameMB;
    }

    /**
     * Return the local address.
     *
     * @return the local address
     */
    public MessageBytes localAddr() {
        return localAddrMB;
    }

    /**
     * Return the remote port.
     *
     * @return the remote port
     */
    public int getRemotePort() {
        return remotePort;
    }

    /**
     * Set the remote port.
     *
     * @param port the remote port
     */
    public void setRemotePort(int port) {
        this.remotePort = port;
    }

    /**
     * Return the local port.
     *
     * @return the local port
     */
    public int getLocalPort() {
        return localPort;
    }

    /**
     * Set the local port.
     *
     * @param port the local port
     */
    public void setLocalPort(int port) {
        this.localPort = port;
    }


    // -------------------- encoding/type --------------------

    /**
     * Return the charset holder.
     *
     * @return the charset holder
     */
    public CharsetHolder getCharsetHolder() {
        if (charsetHolder == null) {
            charsetHolder = CharsetHolder.getInstance(getCharsetFromContentType(getContentType()));
        }
        return charsetHolder;
    }


    /**
     * Set the charset holder.
     *
     * @param charsetHolder the charset holder
     */
    public void setCharsetHolder(CharsetHolder charsetHolder) {
        if (charsetHolder == null || charsetHolder.getName() == null) {
            this.charsetHolder = null;
        } else {
            this.charsetHolder = charsetHolder;
        }
    }


    /**
     * Set the content length.
     *
     * @param len the content length
     */
    public void setContentLength(long len) {
        this.contentLength = len;
    }


    /**
     * Return the content length.
     *
     * @return the content length
     */
    public int getContentLength() {
        long length = getContentLengthLong();

        if (length < Integer.MAX_VALUE) {
            return (int) length;
        }
        return -1;
    }

    /**
     * Return the content length as a long.
     *
     * @return the content length
     */
    public long getContentLengthLong() {
        if (contentLength > -1) {
            return contentLength;
        }

        MessageBytes clB = headers.getUniqueValue("content-length");
        contentLength = (clB == null || clB.isNull()) ? -1 : clB.getLong();

        return contentLength;
    }

    /**
     * Return the content type as a string.
     *
     * @return the content type
     */
    public String getContentType() {
        contentType();
        if (contentTypeMB == null || contentTypeMB.isNull()) {
            return null;
        }
        return contentTypeMB.toStringType();
    }


    /**
     * Set the content type.
     *
     * @param type the content type
     */
    public void setContentType(String type) {
        contentTypeMB.setString(type);
    }


    /**
     * Return the content type.
     *
     * @return the content type
     */
    public MessageBytes contentType() {
        if (contentTypeMB == null) {
            contentTypeMB = headers.getValue("content-type");
        }
        return contentTypeMB;
    }


    /**
     * Set the content type.
     *
     * @param mb the content type
     */
    public void setContentType(MessageBytes mb) {
        contentTypeMB = mb;
    }


    /**
     * Return the value of the specified header.
     *
     * @param name the header name
     * @return the header value
     */
    public String getHeader(String name) {
        return headers.getHeader(name);
    }


    /**
     * Set the expectation flag.
     *
     * @param expectation the expectation flag
     */
    public void setExpectation(boolean expectation) {
        this.expectation = expectation;
    }


    /**
     * Check if there is an expectation.
     *
     * @return {@code true} if there is an expectation
     */
    public boolean hasExpectation() {
        return expectation;
    }


    // -------------------- Associated response --------------------

    /**
     * Return the associated response.
     *
     * @return the response
     */
    public Response getResponse() {
        return response;
    }

    /**
     * Set the associated response.
     *
     * @param response the response
     */
    public void setResponse(Response response) {
        this.response = response;
        response.setRequest(this);
    }

    void setHook(ActionHook hook) {
        this.hook = hook;
    }

    /**
     * Perform an action on this request.
     *
     * @param actionCode the action code
     * @param param the action parameter
     */
    public void action(ActionCode actionCode, Object param) {
        if (hook != null) {
            hook.action(actionCode, Objects.requireNonNullElse(param, this));
        }
    }


    // -------------------- Cookies --------------------

    /**
     * Return the server cookies.
     *
     * @return the server cookies
     */
    public ServerCookies getCookies() {
        return serverCookies;
    }


    // -------------------- Parameters --------------------

    /**
     * Return the request parameters.
     *
     * @return the parameters
     */
    public Parameters getParameters() {
        return parameters;
    }


    /**
     * Add a path parameter.
     *
     * @param name the parameter name
     * @param value the parameter value
     */
    public void addPathParameter(String name, String value) {
        pathParameters.put(name, value);
    }

    /**
     * Return the value of the specified path parameter.
     *
     * @param name the parameter name
     * @return the parameter value
     */
    public String getPathParameter(String name) {
        return pathParameters.get(name);
    }


    // -------------------- Other attributes --------------------
    // We can use notes for most - need to discuss what is of general interest

    /**
     * Set an attribute.
     *
     * @param name the attribute name
     * @param o the attribute value
     */
    public void setAttribute(String name, Object o) {
        attributes.put(name, o);
    }

    /**
     * Return the request attributes map.
     *
     * @return the attributes map
     */
    public HashMap<String,Object> getAttributes() {
        return attributes;
    }

    /**
     * Return the value of the specified attribute.
     *
     * @param name the attribute name
     * @return the attribute value
     */
    public Object getAttribute(String name) {
        return attributes.get(name);
    }

    /**
     * Return the remote user.
     *
     * @return the remote user
     */
    public MessageBytes getRemoteUser() {
        return remoteUser;
    }

    /**
     * Check if the remote user needs authorization.
     *
     * @return {@code true} if the remote user needs authorization
     */
    public boolean getRemoteUserNeedsAuthorization() {
        return remoteUserNeedsAuthorization;
    }

    /**
     * Set whether the remote user needs authorization.
     *
     * @param remoteUserNeedsAuthorization {@code true} if authorization is needed
     */
    public void setRemoteUserNeedsAuthorization(boolean remoteUserNeedsAuthorization) {
        this.remoteUserNeedsAuthorization = remoteUserNeedsAuthorization;
    }

    /**
     * Return the authentication type.
     *
     * @return the authentication type
     */
    public MessageBytes getAuthType() {
        return authType;
    }

    /**
     * Return the number of available bytes.
     *
     * @return the available bytes
     */
    public int getAvailable() {
        return available;
    }

    /**
     * Set the number of available bytes.
     *
     * @param available the available bytes
     */
    public void setAvailable(int available) {
        this.available = available;
    }

    /**
     * Check if sendfile is enabled.
     *
     * @return {@code true} if sendfile is enabled
     */
    public boolean getSendfile() {
        return sendfile;
    }

    /**
     * Set whether sendfile is enabled.
     *
     * @param sendfile {@code true} to enable sendfile
     */
    public void setSendfile(boolean sendfile) {
        this.sendfile = sendfile;
    }

    /**
     * Check if the request body has been fully read.
     *
     * @return {@code true} if finished
     */
    public boolean isFinished() {
        AtomicBoolean result = new AtomicBoolean(false);
        action(ActionCode.REQUEST_BODY_FULLY_READ, result);
        return result.get();
    }

    /**
     * Check if relative redirects are supported.
     *
     * @return {@code true} if relative redirects are supported
     */
    public boolean getSupportsRelativeRedirects() {
        return !protocol().equals("") && !protocol().equals("HTTP/1.0");
    }


    // -------------------- Input Buffer --------------------

    /**
     * Return the input buffer.
     *
     * @return the input buffer
     */
    public InputBuffer getInputBuffer() {
        return inputBuffer;
    }


    /**
     * Set the input buffer.
     *
     * @param inputBuffer the input buffer
     */
    public void setInputBuffer(InputBuffer inputBuffer) {
        this.inputBuffer = inputBuffer;
    }


    /**
     * Read data from the input buffer and put it into ApplicationBufferHandler. The buffer is owned by the protocol
     * implementation - it will be reused on the next read. The Adapter must either process the data in place or copy it
     * to a separate buffer if it needs to hold it. In most cases this is done during byte-&gt;char conversions or via
     * InputStream. Unlike InputStream, this interface allows the app to process data in place, without copy.
     *
     * @param handler The destination to which to copy the data
     *
     * @return The number of bytes copied
     *
     * @throws IOException If an I/O error occurs during the copy
     */
    public int doRead(ApplicationBufferHandler handler) throws IOException {
        if (getBytesRead() == 0 && !response.isCommitted()) {
            action(ActionCode.ACK, ContinueResponseTiming.ON_REQUEST_BODY_READ);
        }

        int n = inputBuffer.doRead(handler);
        if (n > 0) {
            bytesRead += n;
        }
        return n;
    }


    // -------------------- Error tracking --------------------

    /**
     * Set the error Exception that occurred during the writing of the response processing.
     *
     * @param ex The exception that occurred
     */
    public void setErrorException(Exception ex) {
        errorException = ex;
    }


    /**
     * Get the Exception that occurred during the writing of the response.
     *
     * @return The exception that occurred
     */
    public Exception getErrorException() {
        return errorException;
    }


    /**
     * Check if an error exception is present.
     *
     * @return {@code true} if an exception is present
     */
    public boolean isExceptionPresent() {
        return errorException != null;
    }


    // -------------------- debug --------------------

    /**
     * Return the request ID.
     *
     * @return the request ID
     */
    public String getRequestId() {
        return requestId;
    }


    /**
     * Return the protocol request ID.
     *
     * @return the protocol request ID
     */
    public String getProtocolRequestId() {
        if (hook != null) {
            AtomicReference<String> ref = new AtomicReference<>();
            hook.action(ActionCode.PROTOCOL_REQUEST_ID, ref);
            return ref.get();
        } else {
            return null;
        }
    }


    /**
     * Return the servlet connection.
     *
     * @return the servlet connection
     */
    public ServletConnection getServletConnection() {
        if (hook != null) {
            AtomicReference<ServletConnection> ref = new AtomicReference<>();
            hook.action(ActionCode.SERVLET_CONNECTION, ref);
            return ref.get();
        } else {
            return null;
        }
    }


    @Override
    public String toString() {
        return "R( " + requestURI().toString() + ")";
    }

    /**
     * Return the request start time in milliseconds.
     *
     * @return the start time
     */
    public long getStartTime() {
        return System.currentTimeMillis() - TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - startTimeNanos);
    }

    /**
     * Return the request start time in nanoseconds.
     *
     * @return the start time in nanoseconds
     */
    public long getStartTimeNanos() {
        return startTimeNanos;
    }

    /**
     * Mark the request start time.
     */
    public void markStartTime() {
        startTimeNanos = System.nanoTime();
        startInstant = Instant.now();
    }

    /**
     * Return the request start instant.
     *
     * @return the start instant
     */
    public Instant getStartInstant() {
        return startInstant;
    }

    /**
     * Return the thread ID.
     *
     * @return the thread ID
     */
    public long getThreadId() {
        return threadId;
    }

    /**
     * Clear the request thread ID.
     */
    public void clearRequestThread() {
        threadId = 0;
    }

    /**
     * Set the request thread ID.
     */
    @SuppressWarnings("deprecation")
    public void setRequestThread() {
        Thread t = Thread.currentThread();
        threadId = t.getId();
        getRequestProcessor().setWorkerThreadName(t.getName());
    }

    /**
     * Check if the current thread is the request thread.
     *
     * @return {@code true} if the current thread is the request thread
     */
    @SuppressWarnings("deprecation")
    public boolean isRequestThread() {
        return Thread.currentThread().getId() == threadId;
    }

    // -------------------- Per-Request "notes" --------------------


    /**
     * Used to store private data. Thread data could be used instead - but if you have the req, getting/setting a note
     * is just an array access, may be faster than ThreadLocal for very frequent operations. Example use: Catalina
     * CoyoteAdapter: ADAPTER_NOTES = 1 - stores the HttpServletRequest object ( req/res) To avoid conflicts, note in
     * the range 0 - 8 are reserved for the servlet container ( catalina connector, etc ), and values in 9 - 16 for
     * connector use. 17-31 range is not allocated or used.
     *
     * @param pos   Index to use to store the note
     * @param value The value to store at that index
     */
    public void setNote(int pos, Object value) {
        notes[pos] = value;
    }


    /**
     * Return the note at the specified position.
     *
     * @param pos the position
     * @return the note
     */
    public Object getNote(int pos) {
        return notes[pos];
    }


    // -------------------- Recycling --------------------


    /**
     * Recycle this request for reuse.
     */
    public void recycle() {
        bytesRead = 0;

        contentLength = -1;
        contentTypeMB = null;
        charsetHolder = null;
        expectation = false;
        headers.recycle();
        trailerFields.recycle();
        /*
         * Trailer fields are limited in size by bytes. The following calls ensures that any request with a large number
         * of small trailer fields doesn't result in a long lasting, large array of headers inside the MimeHeader
         * instance. The first call ensures the array is no larger than 8. The second call allows the next request to
         * process more than 8 headers if it needs to.
         */
        trailerFields.setLimit(MimeHeaders.DEFAULT_HEADER_SIZE);
        trailerFields.setLimit(-1);
        serverNameMB.recycle();
        serverPort = -1;
        localAddrMB.recycle();
        localNameMB.recycle();
        localPort = -1;
        peerAddrMB.recycle();
        remoteAddrMB.recycle();
        remoteHostMB.recycle();
        remotePort = -1;
        available = 0;
        sendfile = true;

        // There may be multiple calls to recycle but only the first should
        // trigger a change in the request ID until a new request has been
        // started. Use startTimeNanos to detect when a request has started so a
        // subsequent call to recycle() will trigger a change in the request ID.
        if (startTimeNanos != -1) {
            requestId = Long.toHexString(requestIdGenerator.getAndIncrement());
        }

        serverCookies.recycle();
        parameters.recycle();
        pathParameters.clear();

        uriMB.recycle();
        decodedUriMB.recycle();
        queryMB.recycle();
        method = null;
        protoMB.recycle();

        schemeMB.recycle();

        remoteUser.recycle();
        remoteUserNeedsAuthorization = false;
        authType.recycle();
        attributes.clear();

        errorException = null;

        listener = null;
        synchronized (nonBlockingStateLock) {
            fireListener = false;
            registeredForRead = false;
        }
        allDataReadEventSent.set(false);

        startTimeNanos = -1;
        startInstant = null;
        threadId = 0;

        if (hook instanceof NonPipeliningProcessor) {
            /*
             * No requirement to maintain state between requests so clear the hook (a.k.a. Processor) and the input
             * buffer to aid GC.
             */
            setHook(null);
            setInputBuffer(null);
        }
    }

    // -------------------- Info --------------------
    /**
     * Update request counters.
     */
    public void updateCounters() {
        reqProcessorMX.updateCounters();
    }

    /**
     * Return the request processor info.
     *
     * @return the request processor info
     */
    public RequestInfo getRequestProcessor() {
        return reqProcessorMX;
    }

    /**
     * Return the number of bytes read.
     *
     * @return the bytes read
     */
    public long getBytesRead() {
        return bytesRead;
    }

    /**
     * Check if the request is currently being processed.
     *
     * @return {@code true} if processing
     */
    public boolean isProcessing() {
        return reqProcessorMX.getStage() == Constants.STAGE_SERVICE;
    }

    /**
     * Parse the character encoding from the specified content type header. If the content type is null, or there is no
     * explicit character encoding, <code>null</code> is returned.
     *
     * @param contentType a content type header
     */
    private static String getCharsetFromContentType(String contentType) {

        if (contentType == null) {
            return null;
        }

        MediaType mediaType = null;
        try {
            mediaType = MediaType.parseMediaType(new StringReader(contentType));
        } catch (IOException ioe) {
            // Ignore - null test below handles this
        }
        if (mediaType != null) {
            return mediaType.getCharset();
        }

        return null;
    }
}
