Class HttpHeader

java.lang.Object
eu.bandm.tools.util.http.HttpHeader

public class HttpHeader extends Object
Consumes input from an Inputstream and stores it in key/value pairs, as long as no empty line is found. Typical usage pattern is new HttpHeader().read(socket.getInputStream()). After consuming the empty line that ends the header, the InputStream is left for further reading. The first line is split into the three pseudo-header-parameters: method, URI, and httpVersion.

The code follows the specification in rfc 9112 and rfc 3986.

Additionally this class provides simple URI decoding functions which are restricted as they do not allow the encoding of syntactically relevant characters, but sufficient for our current applications.

  • Field Details

  • Constructor Details

    • HttpHeader

      public HttpHeader()
      Only constructor.
  • Method Details

    • isBlank

      public static boolean isBlank(char c)
      Returns whether the character is a whitespace ' ' or a tabulator '\t'.
      Parameters:
      c - character to test.
      Returns:
      whether the test character is a whitespace ' ' or a tabulator '\t'.
    • toString

      public String toString()
      String representation including all key/value pairs from keyValue.
      Overrides:
      toString in class Object
      Returns:
      human-readable representation.
    • get

      @Opt public @Opt String get(String key)
      Return the value of a certain key from the html header, null in case there is no entry.
      Parameters:
      key - of the entry to retrieve.
      Returns:
      the value in the header which corresponds to the key, or null if no such entry exists.
    • getContentLength

      public int getContentLength() throws IOException
      Returns the value of the parameter with name KEY_contentLength. May only be called if such is present. Throws IOException if not found in the keys, and NumberFormatException if the string value does not correspond to a positive or zero integer.
      Returns:
      the integer value stored in the (pseudo) field with the name KEY_contentLength.
      Throws:
      IOException - if not content length is defined in the decoded HTTP message.
    • beforeOrAlternative

      protected String beforeOrAlternative(String s, String alt, int i)
      Return the prefix of s if i >= 0, else the alternative "alt".
      Parameters:
      s - the basic data from which a prefix will be returned.
      alt - the alternative string which will be returned if i<0.
      i - the length of the returned prefix, or <0 to return the alternative string.
      Returns:
      the prefix starting at i, or the alternative string.
    • afterOrAlternative

      protected String afterOrAlternative(String s, String alt, int i)
      Return the suffix of s if i >= 0, else the alternative "alt".
      Parameters:
      s - the basic data from which a suffix will be returned.
      alt - the alternative string which will be returned if i<0.
      i - the start index of the returned suffix, or <0 to return the alternative string.
      Returns:
      the suffix starting at i, or the alternative string.
    • beforeFirstOrAll

      protected String beforeFirstOrAll(String s, char c)
      Return the prefix of s up to the first occuring character c, exclusively, or the total string if no c is contained.
      Parameters:
      s - the basic data from which a suffix will be returned.
      c - the delimiting character
      Returns:
      the prefix up to the first occurence of c in s, or the whole s.
    • afterFirstOrEmpty

      protected String afterFirstOrEmpty(String s, char c)
      Return the suffix of s following the first occuring character c, exclusively, or the total string if no c is contained.
      Parameters:
      s - the basic data from which a suffix will be returned.
      c - the delimiting character
      Returns:
      the suffix starting after the first occurence of c in s, or an empty string.
    • beforeLastOrAll

      protected String beforeLastOrAll(String s, char c)
      Return the prefix of s up to the last occuring character c, exclusively, or the total string if no c is contained.
      Parameters:
      s - the basic data from which a suffix will be returned.
      c - the delimiting character
      Returns:
      the prefix up to the last occurence of c in s, or the whole s.
    • afterLastOrAll

      protected String afterLastOrAll(String s, char c)
      Return the suffix of s following the last occuring character c, exclusively, or the total string if no c is contained.
      Parameters:
      s - the basic data from which a suffix will be returned.
      c - the delimiting character
      Returns:
      the suffix starting after the last occurence of c in s, or the whole string.
    • afterLastOrEmpty

      protected String afterLastOrEmpty(String s, char c)
      Return the suffix of s following the last occuring character c, exclusively, or an empty string if no c is contained.
      Parameters:
      s - the basic data from which a suffix will be returned.
      c - the delimiting character
      Returns:
      the suffix starting after the last occurence of c in s, or the empty string.
    • uriNoFragment

      public String uriNoFragment()
      Strip the fragment part (= location information = part starting with hash mark) from the URI.
      Returns:
      the prefix of the URI without the fragment part = location information.
    • uriNoQueryNorFragment

      public String uriNoQueryNorFragment()
      Strip the fragment part and the query component (starting with "?") from the URI.
      Returns:
      the prefix of the URI without the fragment part (= location information) and the query part.
    • uriFragment

      public String uriFragment()
      Return the fragment part contained in the URI. It is the information = the part starting with hashmark '#', maybe including parameters. If no hashmark is contained, then return the empty string.
      Returns:
      the suffix the URI after a hashmark, or an empty string if no hashmark is contained.
    • uriQuery

      public String uriQuery()
      Return only the query component (= part starting with "?") of the URI, or empty string.
      Returns:
      only the query component (= part starting with "?") of the URI, or empty string.
    • uriPathOnly

      public String uriPathOnly() throws IOException
      Returns only the local file system path component of an URI. Assume a server identification must be thrown away only when the string value starts with "http://a.b.c./" or "https://a.b.c./".
      If not, URI must start with "/" or "*". See https://www.rfc-editor.org/rfc/rfc9112#section-3.2.4 »The "asterisk-form" of request-target is only used for a server-wide OPTIONS request.«
      Returns:
      only the local file system path component of an URI.
      Throws:
      IOException - when the path component of the URI has syntax errors.
    • uriLowestFilename

      public String uriLowestFilename() throws IOException
      Return the last file name of the directory path of the URI.
      Returns:
      the last file name of the directory path of the URI.
      Throws:
      IOException - when the path component of the URI has syntax errors.
    • uriLowestSuffix

      public String uriLowestSuffix() throws IOException
      Return the suffix of the last file name of the directory path of the URI. Or return an string, if there is no dot.
      Returns:
      the suffix of the last file name of the directory path of the URI, or an empty string.
      Throws:
      IOException - when the path component of the URI has syntax errors.
    • uriLowestFilenameNoSuffix

      public String uriLowestFilenameNoSuffix() throws IOException
      Return the last file name of the directory path of the URI without its suffix. Or return it completely, if it does not contain a dot.
      Returns:
      the last file name of the directory path of the URI without its suffix.
      Throws:
      IOException - when the path component of the URI has syntax errors.
    • uriPathOnlyNoSuffix

      public String uriPathOnlyNoSuffix() throws IOException
      Return the complete directory path from the URI, but without the lowest suffix, if any.
      Returns:
      the complete directory path from the URI, but without the lowest suffix, if any.
      Throws:
      IOException - when the path component of the URI has syntax errors.
    • extractCookie

      @Opt public @Opt String extractCookie(String name)
      Return the value which is assigned to the given key in the set of all cookies. Cookies are separated by semicolon ";". Assumes that cookies come in simple form, no attributes, paths etc. are decoded. Lead-in for cookie parameter is KEY_allcookies.
      Parameters:
      name - the key under which the cookie data is found.
      Returns:
      the value of the cookie data under the given name, or null if no such cookie exists.
    • readC

      protected void readC() throws IOException
      Aux method for reading one character. The read character is stored globally in c. Any CR must be followed by a LF, and only the CR is stored.
      Throws:
      IOException - when trying to reach beyond the data of the HTTP header, or when a CR is followed by a non-LF.
    • readToken

      protected String readToken(String key) throws IOException
      Reads a maximal sequence of non-blanks/non-CRs and stores it with the given key in keyValue. Only used for the very first line.
      Parameters:
      key - under which the read data shall be stored.
      Returns:
      the read value.
      Throws:
      IOException - if the sequence is empty
    • read

      public void read(InputStream in) throws IOException
      Decode the HTTP header, store its result in keyValue, and leave the InputStream in the state for further reading. A http REQUEST header looks like
      POST http://server.com/dir/dir/dir/file.html?a=b&c=d#fragment HTTP/1.0«
      param1:value1«
      param2:«
      param2:a very long value«
         extending over more than«
         one line«
      «
      DATA ---
        
      Not yet supported:
      A http STATUS header (in a server response) has a different start-line:
          HTTP/1.1 440 not found 
        
      i.e. version, status code, explanation text for status code.

      (See https://datatracker.ietf.org/doc/html/rfc822#section-3.1 for "folding" = multiple line values).

      (See https://datatracker.ietf.org/doc/html/rfc3986 for URI syntax.)

      (Please note that the format of the query component a=b&c=d is mere convention and not part of a standard. see https://stackoverflow.com/questions/39266970.)

      ("parameters", lead in by a semicolon in the URI, are currently not supported.)

      Parameters:
      in - the data source to read from.
      Throws:
      IOException - on format errors: parameter names not followed by colon; missing empty line; etc.