Best way to parse HTTP headers from String HTTP request without using third-party libraries (Core Java)

Given the HTTP request header, does anyone have any suggestions or know the existing code for proper header analysis? I try to do this only with Core Java, no third-party libraries

Edit:

Trying to find key fields from this line, for example:

GET / HTTP / 1.1User-Agent: curl / 7.19.7 (x86_64-pc-linux-gnu) libcurl / 7.19.7 OpenSSL / 0.9.8k zlib / 1.2.3.3 libidn / 1.15 Host: localhost: 9000Accept: /

Want to analyze a method and a method

+4
source share
4 answers

Start by reading and understanding the HTTP specification .

The query string and headers are separated by CR LF sequences (bytes with decimal values ​​13 and 10), so you can read the stream and highlight each line. I believe that headers should be encoded in US-ASCII, so you can just convert the bytes to characters and add to StringBuilder (but check the specification: it can allow ISO-8859-1 or another encoding).

The end of the headings is denoted by CR LF CR LF.

+3
source

A concatenated single-line string is not an HTTP header.

The correct HTTP request message should look like this (not always)

 GET / HTTP/1.1 CRLF Host: localhost:9000 CRLF User-Agent: curl/7.19.7 blar blar CRLF Accept: */* CRLF Content-Length: ?? CRLF ...: ... CRLF CRLF octets 

See here http://www.w3.org/Protocols/rfc2616/rfc2616-sec5.html

If you want to implement an HTTP server without any help from Sevlets, JavaEE containers, you should use Sockets.

  • Read the first line [Request-Line = Method SP Request-URI SP HTTP-Version CRLF]
  • Read the request header line by line until you get an empty line
  • For each header line, you can parse [fieldName: fieldValue]
  • Read the body of the object.

This is NOT the only case for HTTP message contracts.

+2
source

I use the guava library to include preconditions in my methods. You can remove them in favor of zero checks.

  /** * @return a string consisting of the HTTP headers, concatenating the keys and values delimited by * CFLR (empty line) capable of serialization to the database. */ public static final String httpHeadersToString(final HttpResponse httpResponse) { Preconditions.checkNotNull(httpResponse); Preconditions.checkNotNull(httpResponse.getAllHeaders()); final Header[] allHeaders = httpResponse.getAllHeaders(); StringBuffer sb = new StringBuffer(); int index = 0; while(index < allHeaders.length) { Header header = allHeaders[index]; sb.append(header.getName()) .append(System.getProperty("line.separator")) .append(header.getValue()); if (++index < allHeaders.length) { sb.append(System.getProperty("line.separator")); } } return sb.toString(); } /** * @return reconstruct HTTP headers from a string, delimited by CFLR (empty line). */ public final HttpHeaders stringToHttpHeaders(final String headerContents) { HttpHeaders httpHeaders = new HttpHeaders(); final String[] tempHeaderArray = headerContents.split(System.getProperty("line.separator")); int i = 0; while (i + 1 <= tempHeaderArray.length) { httpHeaders.add(tempHeaderArray[i++], tempHeaderArray[i++]); } return httpHeaders; } 
0
source

I wrote the RawHTTP library, whose sole purpose is to parse HTTP messages (requests and responses).

If you do not want to use the library, you can copy the source to your own code base, starting with the form: https://github.com/renatoathaydes/rawhttp/blob/a6588b116a4008e5b5840d4eb66374c0357b726d/rawhttp-core/src/main/java/com/athaydes /rawhttp/core/RawHttp.java#L52

This will split the lines of the HTTP message to the end of the metadata sections (start line + headers).

Using a list of metadata lines, you can call the parseHeaders method, which will create headers for you. You can easily adapt this to simply return Map<String, List<String>> to avoid having to import header classes.

That says ... RawHTTP has no dependencies, so I would just use it instead :), but up to you.

0
source

All Articles