Skip to content

Hyper Curl test 580 and 580 Root cause #2780

Closed
@liamwarfield

Description

@liamwarfield

Version
hyper::ffi current version

Platform
All?

Description
Found the RC of failing curl tests 580 and 581!

[short summary of the bug]
hyper_headers_foreach iterates through headers in by header name, not by order recieved! The smoking gun for for curl tests 580 and 581 is this line.

For test 581:
Raw response sent by server:

HTTP/1.1 200 OK
Content-Length: 18

WE ROOLZ: 118369
HTTP/1.1 200 all good!
Date: Tue, 09 Nov 2010 14:49:00 GMT
Server: test-server/fake
Content-Type: text/html
Content-Length: 0
Connection: close
Content-Type: changed/my/mind

Curl is expecting an iterator that returns headers in the order that they were received:

HTTP/1.1 200 all good![CR][LF]
Date: Tue, 09 Nov 2010 14:49:00 GMT[CR][LF]
Server: test-server/fake[CR][LF]
Content-Type: text/html[CR][LF]
Content-Length: 0[CR][LF]
Connection: close[CR][LF]
Content-Type: changed/my/mind[CR][LF]
[CR][LF]

but hyper is returning ALL of the Content-Type headers before moving onto the Connection header. Results in:

HTTP/1.1 200 all good![CR][LF]
Date: Tue, 09 Nov 2010 14:49:00 GMT[CR][LF]
Server: test-server/fake[CR][LF]
Content-Type: text/html[CR][LF]
Content-Type: changed/my/mind[CR][LF]  <------ comes to early!
Content-Length: 0[CR][LF]
Connection: close[CR][LF]
[CR][LF]

Hyper Code Responcible

hyper_headers_foreach_callback, userdata: *mut c_void) {
        let headers = non_null!(&*headers ?= ());
        for name in headers.headers.keys() {
            let mut names = headers.orig_casing.get_all(name);

            /// HERE is the bug, this iterates through all headers with the
            /// same name before moving on to the next header name.
            for value in headers.headers.get_all(name) {
                let (name_ptr, name_len) = if let Some(orig_name) = names.next() {
                    (orig_name.as_ref().as_ptr(), orig_name.as_ref().len())
                } else {
                    (
                        name.as_str().as_bytes().as_ptr(),
                        name.as_str().as_bytes().len(),
                    )
                };

                let val_ptr = value.as_bytes().as_ptr();
                let val_len = value.as_bytes().len();

                if HYPER_ITER_CONTINUE != func(userdata, name_ptr, name_len, val_ptr, val_len) {
                    return;
                }
            }
        }
    }
}

@seanmonstar

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-ffiArea: ffi (C API)C-bugCategory: bug. Something is wrong. This is bad!

    Type

    No type

    Projects

    Status

    Done

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions