Class Request

java.lang.Object
com.soklet.Request

@ThreadSafe public final class Request extends Object
Encapsulates information specified in an HTTP request.

Instances can be acquired via the withRawUrl(HttpMethod, String) (e.g. provided by clients on a "raw" HTTP/1.1 request line, un-decoded) and withPath(HttpMethod, String) (e.g. manually-constructed during integration testing, understood to be already-decoded) builder factory methods.

Any necessary decoding (path, URL parameter, Content-Type: application/x-www-form-urlencoded, etc.) will be automatically performed. Unless otherwise indicated, all accessor methods will return decoded data.

Detailed documentation available at https://www.soklet.com/docs/request-handling.

Author:
Mark Allen
  • Method Details

    • withRawUrl

      Acquires a builder for Request instances from the URL provided by clients on a "raw" HTTP/1.1 request line.

      The provided rawUrl must be un-decoded and in either "path-and-query" form (i.e. starts with a / character) or an absolute URL (i.e. starts with http:// or https://). It might include un-decoded query parameters, e.g. https://www.example.com/one?two=thr%20ee or /one?two=thr%20ee. An exception to this rule is OPTIONS * requests, where the URL is the * "splat" symbol.

      Paths will be percent-decoded.

      Query parameters are parsed and decoded using RFC 3986 semantics - see QueryFormat.RFC_3986_STRICT.

      Request body form parameters with Content-Type: application/x-www-form-urlencoded are parsed and decoded by using QueryFormat.X_WWW_FORM_URLENCODED.

      Parameters:
      httpMethod - the HTTP method for this request (GET, POST, etc.)
      rawUrl - the raw (un-decoded) URL for this request
      Returns:
      the builder
    • withPath

      Acquires a builder for Request instances from already-decoded path and query components - useful for manual construction, e.g. integration tests.

      The provided path must start with the / character and already be decoded (e.g. "/my path", not "/my%20path"). It must not include query parameters. For OPTIONS * requests, the path must be * - the "splat" symbol.

      Query parameters must be specified via Request.PathBuilder.queryParameters(Map) and are assumed to be already-decoded.

      Request body form parameters with Content-Type: application/x-www-form-urlencoded are parsed and decoded by using QueryFormat.X_WWW_FORM_URLENCODED.

      Parameters:
      httpMethod - the HTTP method for this request (GET, POST, etc.)
      path - the decoded URL path for this request
      Returns:
      the builder
    • copy

      Vends a mutable copier seeded with this instance's data, suitable for building new instances.
      Returns:
      a copier for this instance
    • toString

      public String toString()
      Overrides:
      toString in class Object
    • equals

      public boolean equals(@Nullable Object object)
      Overrides:
      equals in class Object
    • hashCode

      public int hashCode()
      Overrides:
      hashCode in class Object
    • getId

      @Nonnull public Object getId()
      An application-specific identifier for this request.

      The identifier is not necessarily unique (for example, numbers that "wrap around" if they get too large).

      Returns:
      the request's identifier
    • getHttpMethod

      The HTTP method for this request.
      Returns:
      the request's HTTP method
    • getPath

      The percent-decoded path component of this request (no query string).
      Returns:
      the path for this request
    • getResourcePath

      Convenience method to acquire a ResourcePath representation of getPath().
      Returns:
      the resource path for this request
    • getCookies

      The cookies provided by the client for this request.

      The keys are the Cookie header names and the values are Cookie header values (it is possible for a client to send multiple Cookie headers with the same name).

      Note that Cookie headers, like all request headers, have case-insensitive names per the HTTP spec.

      Use getCookie(String) for a convenience method to access cookie values when only one is expected.

      Returns:
      the request's cookies
    • getQueryParameters

      The decoded query parameters provided by the client for this request.

      The keys are the query parameter names and the values are query parameter values (it is possible for a client to send multiple query parameters with the same name, e.g. ?test=1&test=2).

      Note that query parameters have case-sensitive names per the HTTP spec.

      Use getQueryParameter(String) for a convenience method to access query parameter values when only one is expected.

      Returns:
      the request's query parameters
    • getFormParameters

      The decoded HTML application/x-www-form-urlencoded form parameters provided by the client for this request.

      The keys are the form parameter names and the values are form parameter values (it is possible for a client to send multiple form parameters with the same name, e.g. ?test=1&test=2).

      Note that form parameters have case-sensitive names per the HTTP spec.

      Use getFormParameter(String) for a convenience method to access form parameter values when only one is expected.

      Returns:
      the request's form parameters
    • getRawPath

      The raw (un-decoded) path component of this request exactly as the client specified.

      For example, "/a%20b" (never decoded).

      Note: For requests constructed via withPath(HttpMethod, String), this value is generated by encoding the decoded path, which may not exactly match the original wire format.

      Returns:
      the raw path for this request
    • getRawQuery

      The raw (un-decoded) query component of this request exactly as the client specified.

      For example, "a=b&c=d+e" (never decoded).

      This is useful for special cases like HMAC signature verification, which relies on the exact client format.

      Note: For requests constructed via withPath(HttpMethod, String), this value is generated by encoding the decoded query parameters, which may not exactly match the original wire format.

      Returns:
      the raw query for this request, or Optional.empty() if none was specified
    • getRawPathAndQuery

      The raw (un-decoded) path and query components of this request exactly as the client specified.

      For example, "/my%20path?a=b&c=d%20e" (never decoded).

      Note: For requests constructed via withPath(HttpMethod, String), this value is generated by encoding the decoded path and query parameters, which may not exactly match the original wire format.

      Returns:
      the raw path and query for this request
    • getHeaders

      The headers provided by the client for this request.

      The keys are the header names and the values are header values (it is possible for a client to send multiple headers with the same name).

      Note that request headers have case-insensitive names per the HTTP spec.

      Use getHeader(String) for a convenience method to access header values when only one is expected.

      Returns:
      the request's headers
    • getContentType

      The Content-Type header value, as specified by the client.
      Returns:
      the request's Content-Type header value, or Optional.empty() if not specified
    • getCharset

      The request's character encoding, as specified by the client in the Content-Type header value.
      Returns:
      the request's character encoding, or Optional.empty() if not specified
    • isMultipart

      Is this a request with Content-Type of multipart/form-data?
      Returns:
      true if this is a multipart/form-data request, false otherwise
    • getMultipartFields

      The decoded HTML multipart/form-data fields provided by the client for this request.

      The keys are the multipart field names and the values are multipart field values (it is possible for a client to send multiple multipart fields with the same name).

      Note that multipart fields have case-sensitive names per the HTTP spec.

      Use getMultipartField(String) for a convenience method to access a multipart parameter field value when only one is expected.

      When using Soklet's default Server, multipart fields are parsed using the MultipartParser as configured by Server.Builder.multipartParser(MultipartParser).

      Returns:
      the request's multipart fields, or the empty map if none are present
    • getBody

      @Nonnull public Optional<byte[]> getBody()
      The raw bytes of the request body - callers should not modify this array; it is not defensively copied for performance reasons.

      For convenience, getBodyAsString() is available if you expect your request body to be of type String.

      Returns:
      the request body bytes, or Optional.empty() if none was supplied
    • isContentTooLarge

      Was this request too large for the server to handle?

      If so, this request might have incomplete sets of headers/cookies. It will always have a zero-length body.

      Soklet is designed to power systems that exchange small "transactional" payloads that live entirely in memory. It is not appropriate for handling multipart files at scale, buffering uploads to disk, streaming, etc.

      When using Soklet's default Server, maximum request size is configured by Server.Builder.maximumRequestSizeInBytes(Integer).

      Returns:
      true if this request is larger than the server is able to handle, false otherwise
    • getBodyAsString

      Convenience method that provides the getBody() bytes as a String encoded using the client-specified character set per getCharset().

      If no character set is specified, StandardCharsets.UTF_8 is used to perform the encoding.

      This method will lazily convert the raw bytes as specified by getBody() to an instance of String when first invoked. The String representation is then cached and re-used for subsequent invocations.

      This method is threadsafe.

      Returns:
      a String representation of this request's body, or Optional.empty() if no request body was specified by the client
    • getCors

      Returns:
      non-preflight CORS request data, or Optional.empty() if none was specified
    • getCorsPreflight

      CORS preflight-related request data.

      See https://www.soklet.com/docs/cors for details.

      Returns:
      preflight CORS request data, or Optional.empty() if none was specified
    • getLocales

      Locale information for this request as specified by Accept-Language header value[s] and ordered by weight as defined by RFC 7231, Section 5.3.5.

      This method will lazily parse Accept-Language header values into to an ordered List of Locale when first invoked. This representation is then cached and re-used for subsequent invocations.

      This method is threadsafe.

      See getLanguageRanges() for a variant that pulls Locale.LanguageRange values.

      Returns:
      locale information for this request, or the empty list if none was specified
    • getLanguageRanges

      Locale.LanguageRange information for this request as specified by Accept-Language header value[s].

      This method will lazily parse Accept-Language header values into to an ordered List of Locale.LanguageRange when first invoked. This representation is then cached and re-used for subsequent invocations.

      This method is threadsafe.

      See getLocales() for a variant that pulls Locale values.

      Returns:
      language range information for this request, or the empty list if none was specified
    • getQueryParameter

      Convenience method to access a decoded query parameter's value when at most one is expected for the given name.

      If a query parameter name can support multiple values, getQueryParameters() should be used instead of this method.

      If this method is invoked for a query parameter name with multiple values, Soklet will throw IllegalQueryParameterException.

      Note that query parameters have case-sensitive names per the HTTP spec.

      Parameters:
      name - the name of the query parameter
      Returns:
      the value for the query parameter, or Optional.empty() if none is present
      Throws:
      IllegalQueryParameterException - if the query parameter with the given name has multiple values
    • getFormParameter

      Convenience method to access a decoded form parameter's value when at most one is expected for the given name.

      If a form parameter name can support multiple values, getFormParameters() should be used instead of this method.

      If this method is invoked for a form parameter name with multiple values, Soklet will throw IllegalFormParameterException.

      Note that form parameters have case-sensitive names per the HTTP spec.

      Parameters:
      name - the name of the form parameter
      Returns:
      the value for the form parameter, or Optional.empty() if none is present
      Throws:
      IllegalFormParameterException - if the form parameter with the given name has multiple values
    • getHeader

      Convenience method to access a header's value when at most one is expected for the given name.

      If a header name can support multiple values, getHeaders() should be used instead of this method.

      If this method is invoked for a header name with multiple values, Soklet will throw IllegalRequestHeaderException.

      Note that request headers have case-insensitive names per the HTTP spec.

      Parameters:
      name - the name of the header
      Returns:
      the value for the header, or Optional.empty() if none is present
      Throws:
      IllegalRequestHeaderException - if the header with the given name has multiple values
    • getCookie

      Convenience method to access a cookie's value when at most one is expected for the given name.

      If a cookie name can support multiple values, getCookies() should be used instead of this method.

      If this method is invoked for a cookie name with multiple values, Soklet will throw IllegalRequestCookieException.

      Note that Cookie headers, like all request headers, have case-insensitive names per the HTTP spec.

      Parameters:
      name - the name of the cookie
      Returns:
      the value for the cookie, or Optional.empty() if none is present
      Throws:
      IllegalRequestCookieException - if the cookie with the given name has multiple values
    • getMultipartField

      Convenience method to access a decoded multipart field when at most one is expected for the given name.

      If a name can support multiple multipart fields, getMultipartFields() should be used instead of this method.

      If this method is invoked for a name with multiple multipart field values, Soklet will throw IllegalMultipartFieldException.

      Note that multipart fields have case-sensitive names per the HTTP spec.

      Parameters:
      name - the name of the multipart field
      Returns:
      the multipart field value, or Optional.empty() if none is present
      Throws:
      IllegalMultipartFieldException - if the multipart field with the given name has multiple values