summerwind / h2spec

A conformance testing tool for HTTP/2 implementation.
MIT License
662 stars 74 forks source link

Support servers that rst_stream on unsupported request #73

Open daurnimator opened 7 years ago

daurnimator commented 7 years ago

I have a server/set of endpoints that will RST_STREAM if the request is not of a certain form.

Failures: 

Generic tests for HTTP/2 server
  2. Streams and Multiplexing
    × 2: Sends a WINDOW_UPDATE frame on half-closed (remote) stream
      -> The endpoint MUST accept WINDOW_UPDATE frame.
         Expected: DATA frame
           Actual: RST_STREAM Frame (length:4, flags:0x00, stream_id:1)
    × 3: Sends a PRIORITY frame on half-closed (remote) stream
      -> The endpoint MUST accept PRIORITY frame.
         Expected: DATA frame
           Actual: RST_STREAM Frame (length:4, flags:0x00, stream_id:1)

  3. Frame Definitions
    3.1. DATA
      × 1: Sends a DATA frame
        -> The endpoint MUST accept DATA frame.
           Expected: HEADERS Frame (stream_id:1)
             Actual: WINDOW_UPDATE Frame (length:4, flags:0x00, stream_id:0)
      × 2: Sends multiple DATA frames
        -> The endpoint MUST accept multiple DATA frames.
           Expected: HEADERS Frame (stream_id:1)
             Actual: Connection closed
      × 3: Sends a DATA frame with padding
        -> The endpoint MUST accept DATA frame with padding.
           Expected: HEADERS Frame (stream_id:1)
             Actual: Connection closed

    3.2. HEADERS
      × 1: Sends a HEADERS frame
        -> The endpoint MUST accept HEADERS frame.
           Expected: HEADERS Frame (stream_id:1)
             Actual: RST_STREAM Frame (length:4, flags:0x00, stream_id:1)
      × 2: Sends a HEADERS frame with padding
        -> The endpoint MUST accept HEADERS frame with padding.
           Expected: HEADERS Frame (stream_id:1)
             Actual: RST_STREAM Frame (length:4, flags:0x00, stream_id:1)
      × 3: Sends a HEADERS frame with priority
        -> The endpoint MUST accept HEADERS frame with priority.
           Expected: HEADERS Frame (stream_id:1)
             Actual: RST_STREAM Frame (length:4, flags:0x00, stream_id:1)

    3.3. PRIORITY
      × 1: Sends a PRIORITY frame with priority 1
        -> The endpoint MUST accept PRIORITY frame with priority 1.
           Expected: HEADERS Frame (stream_id:1)
             Actual: RST_STREAM Frame (length:4, flags:0x00, stream_id:1)
      × 2: Sends a PRIORITY frame with priority 256
        -> The endpoint MUST accept PRIORITY frame with priority 256.
           Expected: HEADERS Frame (stream_id:1)
             Actual: RST_STREAM Frame (length:4, flags:0x00, stream_id:1)
      × 3: Sends a PRIORITY frame with stream dependency
        -> The endpoint MUST accept PRIORITY frame with stream dependency.
           Expected: HEADERS Frame (stream_id:1)
             Actual: RST_STREAM Frame (length:4, flags:0x00, stream_id:1)
      × 4: Sends a PRIORITY frame with exclusive
        -> The endpoint MUST accept PRIORITY frame with exclusive.
           Expected: HEADERS Frame (stream_id:1)
             Actual: RST_STREAM Frame (length:4, flags:0x00, stream_id:1)
      × 5: Sends a PRIORITY frame for an idle stream, then send a HEADER frame for a lower stream ID
        -> The endpoint MUST respond the HEADER frame.
           Expected: HEADERS Frame (stream_id:1)
             Actual: RST_STREAM Frame (length:4, flags:0x00, stream_id:1)

    3.9. WINDOW_UPDATE
      × 2: Sends a WINDOW_UPDATE frame with stream ID 1
        -> The endpoint MUST accept WINDOW_UPDATE frame.
           Expected: HEADERS Frame (stream_id:1)
             Actual: RST_STREAM Frame (length:4, flags:0x00, stream_id:1)

    3.10. CONTINUATION
      × 1: Sends a CONTINUATION frame
        -> The endpoint MUST accept CONTINUATION frame.
           Expected: HEADERS Frame (stream_id:1)
             Actual: RST_STREAM Frame (length:4, flags:0x00, stream_id:1)
      × 2: Sends multiple CONTINUATION frames
        -> The endpoint MUST accept multiple CONTINUATION frames.
           Expected: HEADERS Frame (stream_id:1)
             Actual: RST_STREAM Frame (length:4, flags:0x00, stream_id:1)

  4. HTTP Message Exchanges
    × 1: Sends a GET request
      -> The endpoint MUST respond to the request.
         Expected: HEADERS Frame (stream_id:1)
           Actual: RST_STREAM Frame (length:4, flags:0x00, stream_id:1)
    × 2: Sends a HEAD request
      -> The endpoint MUST respond to the request.
         Expected: HEADERS Frame (stream_id:1)
           Actual: RST_STREAM Frame (length:4, flags:0x00, stream_id:1)
    × 3: Sends a POST request
      -> The endpoint MUST respond to the request.
         Expected: HEADERS Frame (stream_id:1)
           Actual: WINDOW_UPDATE Frame (length:4, flags:0x00, stream_id:0)
    × 4: Sends a POST request with trailers
      -> The endpoint MUST respond to the request.
         Expected: HEADERS Frame (stream_id:1)
           Actual: Connection closed

  5. HPACK
    × 1: Sends a indexed header field representation
      -> The endpoint MUST accept indexed header field representation
         Expected: HEADERS Frame (stream_id:1)
           Actual: RST_STREAM Frame (length:4, flags:0x00, stream_id:1)
    × 2: Sends a literal header field with incremental indexing - indexed name
      -> The endpoint MUST accept literal header field with incremental indexing
         Expected: HEADERS Frame (stream_id:1)
           Actual: RST_STREAM Frame (length:4, flags:0x00, stream_id:1)
    × 3: Sends a literal header field with incremental indexing - indexed name (with Huffman coding)
      -> The endpoint MUST accept literal header field with incremental indexing
         Expected: HEADERS Frame (stream_id:1)
           Actual: RST_STREAM Frame (length:4, flags:0x00, stream_id:1)
    × 4: Sends a literal header field with incremental indexing - new name
      -> The endpoint MUST accept literal header field with incremental indexing
         Expected: HEADERS Frame (stream_id:1)
           Actual: RST_STREAM Frame (length:4, flags:0x00, stream_id:1)
    × 5: Sends a literal header field with incremental indexing - new name (with Huffman coding)
      -> The endpoint MUST accept literal header field with incremental indexing
         Expected: HEADERS Frame (stream_id:1)
           Actual: RST_STREAM Frame (length:4, flags:0x00, stream_id:1)
    × 6: Sends a literal header field without indexing - indexed name
      -> The endpoint MUST accept literal header field without indexing
         Expected: HEADERS Frame (stream_id:1)
           Actual: RST_STREAM Frame (length:4, flags:0x00, stream_id:1)
    × 7: Sends a literal header field without indexing - indexed name (with Huffman coding)
      -> The endpoint MUST accept literal header field without indexing
         Expected: HEADERS Frame (stream_id:1)
           Actual: RST_STREAM Frame (length:4, flags:0x00, stream_id:1)
    × 8: Sends a literal header field without indexing - new name
      -> The endpoint MUST accept literal header field without indexing
         Expected: HEADERS Frame (stream_id:1)
           Actual: RST_STREAM Frame (length:4, flags:0x00, stream_id:1)
    × 9: Sends a literal header field without indexing - new name (huffman encoded)
      -> The endpoint MUST accept literal header field without indexing
         Expected: HEADERS Frame (stream_id:1)
           Actual: RST_STREAM Frame (length:4, flags:0x00, stream_id:1)
    × 10: Sends a literal header field never indexed - indexed name
      -> The endpoint MUST accept literal header field never indexed
         Expected: HEADERS Frame (stream_id:1)
           Actual: RST_STREAM Frame (length:4, flags:0x00, stream_id:1)
    × 11: Sends a literal header field never indexed - indexed name (huffman encoded)
      -> The endpoint MUST accept literal header field never indexed
         Expected: HEADERS Frame (stream_id:1)
           Actual: RST_STREAM Frame (length:4, flags:0x00, stream_id:1)
    × 12: Sends a literal header field never indexed - new name
      -> The endpoint MUST accept literal header field never indexed
         Expected: HEADERS Frame (stream_id:1)
           Actual: RST_STREAM Frame (length:4, flags:0x00, stream_id:1)
    × 13: Sends a literal header field never indexed - new name (huffman encoded)
      -> The endpoint MUST accept literal header field never indexed
         Expected: HEADERS Frame (stream_id:1)
           Actual: RST_STREAM Frame (length:4, flags:0x00, stream_id:1)
    × 14: Sends a dynamic table size update
      -> The endpoint MUST accept dynamic table size update
         Expected: HEADERS Frame (stream_id:1)
           Actual: RST_STREAM Frame (length:4, flags:0x00, stream_id:1)
    × 15: Sends multiple dynamic table size update
      -> The endpoint MUST accept multiple dynamic table size update
         Expected: HEADERS Frame (stream_id:1)
           Actual: RST_STREAM Frame (length:4, flags:0x00, stream_id:1)

Hypertext Transfer Protocol Version 2 (HTTP/2)
  4. HTTP Frames
    4.2. Frame Size
      × 1: Sends a DATA frame with 2^14 octets in length
        -> The endpoint MUST be capable of receiving and minimally processing frames up to 2^14 octets in length.
           Expected: HEADERS Frame (stream_id:1)
             Actual: Connection closed

  6. Frame Definitions
    6.5. SETTINGS
      6.5.3. Settings Synchronization
        × 1: Sends multiple values of SETTINGS_INITIAL_WINDOW_SIZE
        Error: Unable to get server data length

    6.9. WINDOW_UPDATE
      6.9.1. The Flow-Control Window
        × 1: Sends SETTINGS frame to set the initial window size to 1 and sends HEADERS frame
        Error: Unable to get server data length

      6.9.2. Initial Flow-Control Window Size
        × 1: Changes SETTINGS_INITIAL_WINDOW_SIZE after sending HEADERS frame
        Error: Unable to get server data length
        × 2: Sends a SETTINGS frame for window size to be negative
        Error: Unable to get server data length

    6.10. CONTINUATION
      × 1: Sends multiple CONTINUATION frames preceded by a HEADERS frame
        -> The endpoint must accept the frame.
           Expected: HEADERS Frame (stream_id:1)
             Actual: RST_STREAM Frame (length:4, flags:0x00, stream_id:1)
summerwind commented 7 years ago

What do you mean about "the request is not of a certain form"? Can I have a verbose log (-v option) to understand what is going on?

daurnimator commented 7 years ago

What do you mean about "the request is not of a certain form"?

As in if the HEADERS block does not contain $SPECIAL_HEADER then the server immediately responds with RST_STREAM.

i.e. after every request headers block sent for the test, the server immediately replies with a RST_STREAM.

summerwind commented 7 years ago

What is the $SPECIAL_HEADER? Is it implementation dependent header? If so, there is nothing that h2spec can do...

daurnimator commented 7 years ago

What is the $SPECIAL_HEADER? Is it implementation dependent header?

It's something purposefully abstract :)

If so, there is nothing that h2spec can do...

As I see it: the server isn't doing anything against the http2 specification, so h2spec shouldn't have tests fail on it. I think there could be a check that if a RST_STREAM comes back, h2spec skips the test.