How to store an Http Response that may contain binary data?

前端 未结 5 1709
情话喂你
情话喂你 2020-12-31 19:03

As I described in a previous question, I have an assignment to write a proxy server. It partially works now, but I still have a problem with handling of gzipped information.

5条回答
  •  生来不讨喜
    2020-12-31 19:10

    Store it in a byte array:

    byte[] bufer = new byte[???];
    

    A more detailed process:

    • Create a buffer large enough for the response header (and drop exception if it is bigger).
    • Read bytes to the buffer until you find \r\n\r\n in the buffer. You can write a helper function for example static int arrayIndexOf(byte[] haystack, int offset, int length, byte[] needle)
    • When you encounter the end of header, create a strinform the first n bytes of the buffer. You can then use RegEx on this strng (also note that RegEx is not the best method to parse HTTPeaders).
    • Be prepared that the buffer will contain additional data after the header, which are the first bytes of the response body. You have to copy these bytes to the output stream or output file or output buffer.
    • Read the rest of the response body. (Until content-length is read or stream is closed).

    Edit:

    You are not following these steps I suggested. inputReader.ready() is a wrong way to detect the phases of the response. There is no guarantee that the header will be sent in a single burst.

    I tried to write a schematics in code (except the arrayIndexOf) function.

    InputStream is;
    
    // Create a buffer large enough for the response header (and drop exception if it is bigger).
    byte[] headEnd = {13, 10, 13, 10}; // \r \n \r \n
    byte[] buffer = new byte[10 * 1024];
    int length = 0;
    
    // Read bytes to the buffer until you find `\r\n\r\n` in the buffer. 
    int bytes = 0;
    int pos;
    while ((pos = arrayIndexOf(buffer, 0, length, headEnd)) == -1 && (bytes = is.read(buffer, length, buffer.length() - length)) > -1) {
        length += bytes;
    
        // buffer is full but have not found end siganture
        if (length == buffer.length())
            throw new RuntimeException("Response header too long");
    }
    
    // pos contains the starting index of the end signature (\r\n\r\n) so we add 4 bytes
    pos += 4;
    
    // When you encounter the end of header, create a strinform the first *n* bytes
    String header = new String(buffer, 0, pos);
    
    System.out.println(header);
    
    // Be prepared that the buffer will contain additional data after the header
    // ... so we process it
    System.out.write(buffer, pos, length - pos);
    
    // process the rest until connection is closed
    while (bytes = is.read(buffer, 0, bufer.length())) {
        System.out.write(buffer, 0, bytes);
    }
    

    The arrayIndexOf method could look something like this: (there are probably faster versions)

    public static int arrayIndexOf(byte[] haystack, int offset, int length, byte[] needle) {
        for (int i=offset; i

提交回复
热议问题