Skip to content

request error = HttpMethodError logs #197

Closed
@rictic

Description

@rictic

I'm finding the following in my server logs with some frequency:

ERROR:hyper::server: request error = HttpMethodError

After spending some time on this, I've found a simple reproduction that seems to hinge on requests with a chunked transfer encoding, though I couldn't tell if it was the hyper client or the server that was incorrect. Wireshark hinted that it may be the client, but I believe that I've encountered this log message in the wild and not just when testing the hyper server with the hyper client.

The log message is produced when the server is trying to read the http method of a request but encounters unexpected characters. In the case of the error reproduction below, the server appears to be trying to read for a second request on the connection, and it encounters \r\n instead of the expected http method.

extern crate test;
extern crate hyper;

use std::io;
use std::rand;
use hyper::method::Method;
use hyper::client::Request;
use hyper::server;
use hyper::status::StatusCode;

#[test]
fn http_method_error_is_logged() {
    let ts = TestServer::new();
    Request::new(Method::Post, ts.get_url())
        .unwrap().start().unwrap().send().unwrap();
    io::stdio::stderr().write_line(
        "^^^^^^^     That ERROR log message there     ^^^^^^^").unwrap();

    // I couldn't work out how to capture the error logs, stdio::set_stderr()
    // only catches messages sent with panic! I think. As a result this "test" 
    // doesn't assert, you just have to look at the printed output.

    // Things which cause this error to not reproduce:
    //   * changing the request to one with no body, like a GET
    //   * providing a Content-Length on the request
}

fn hello(_: server::Request, mut res: server::Response) {
    *res.status_mut() = StatusCode::Ok;
    let mut res = res.start().unwrap();
    res.write(b"Hello World!").unwrap();
    res.end().unwrap();
}


struct TestServer {
    listen_serv : hyper::server::Listening,
    port : u16,
}

impl TestServer {
    fn new() -> TestServer {
        let host = from_str("127.0.0.1").unwrap();
        // Try to guess a free port that we can bind to:
        for _ in range(0, 100u) {
            let port = rand::random();
            let server = hyper::server::Server::http(host, port);

            match server.listen(hello) {
                Ok(listening) => {
                    return TestServer {
                        listen_serv: listening,
                        port: port
                    }
                },
                Err(_) => (),
            };
        }

        panic!("Could not find a port to bind the test server to!");
    }

    fn get_url(&self) -> hyper::Url {
        let mut url = "http://127.0.0.1:".to_string();
        url.push_str(self.port.to_string().as_slice());
        url.push_str("/");
        hyper::Url::parse(url.as_slice()).unwrap()
    }
}

impl Drop for TestServer {
    fn drop(&mut self) {
        self.listen_serv.close().unwrap();
    }
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-serverArea: server.C-bugCategory: bug. Something is wrong. This is bad!

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions