Repository: Orange-OpenSource/hurl
File: packages/hurl/src/http/client.rs (Rust)

Code before:
            } else {
                NetRc::Required
            })?;
        } else if options.netrc_optional {
            self.handle.netrc(NetRc::Optional)?;
        } else if options.netrc {
            self.handle.netrc(NetRc::Required)?;
        }
        self.handle.timeout(options.timeout)?;
        self.handle.connect_timeout(options.connect_timeout)?;
        if let Some(max_filesize) = options.max_filesize {
            self.handle.max_filesize(max_filesize)?;
        }
        if let Some(max_recv_speed) = options.max_recv_speed {
            self.handle.max_recv_speed(max_recv_speed.0)?;
        }
        if let Some(max_send_speed) = options.max_send_speed {
            self.handle.max_send_speed(max_send_speed.0)?;
        }
        if let Some(pinned_pub_key) = &options.pinned_pub_key {
            self.handle.pinned_public_key(pinned_pub_key)?;
        }
        if options.ntlm {
            self.handle.http_auth(easy::Auth::new().ntlm(true))?;
        }
        if options.negotiate {
            self.handle
                .http_auth(easy::Auth::new().gssnegotiate(true))?;
        }

        self.set_ssl_options(options.ssl_no_revoke)?;

        let url = self.generate_url(&request_spec.url, &request_spec.querystring);
        self.handle.url(url.as_str())?;
        let method = &request_spec.method;
        self.set_method(method)?;
        self.set_cookies(&request_spec.cookies)?;
        self.set_form(&request_spec.form)?;
        self.set_multipart(&request_spec.multipart)?;
        let request_spec_body = &request_spec.body.bytes();
        self.set_body(request_spec_body)?;
        // TODO: do we want to manage the headers with no content? There are two type of no-content
        // headers: `foo:` and `foo;`. The first one can be used to remove libcurl headers (`Host:`)
        // while the second one is used to send an empty header.
        // See <https://github.com/Orange-OpenSource/hurl/issues/3536>
        let options_headers = options
            .headers
            .iter()
            .map(|h| h.as_str())
            .collect::<Vec<&str>>();
        let headers = &request_spec.headers.with_raw_headers(&options_headers);

Review comment (security):
Written like this, if `options.negociate` is true is will set a new `easy::Auth` instance on `self.handle`, and possibly overwrite the previously instance written for ntlm. We should write something like:

```rust 
if options.ntlm || options.negociate {
    let auth = easy::Auth::new().ntlm(options.ntlm).gssnegotiate(options.negociate);
    self.handle.http_auth(auth)?;
}
```

Code after:
            } else {
                NetRc::Required
            })?;
        } else if options.netrc_optional {
            self.handle.netrc(NetRc::Optional)?;
        } else if options.netrc {
            self.handle.netrc(NetRc::Required)?;
        }
        self.handle.timeout(options.timeout)?;
        self.handle.connect_timeout(options.connect_timeout)?;
        if let Some(max_filesize) = options.max_filesize {
            self.handle.max_filesize(max_filesize)?;
        }
        if let Some(max_recv_speed) = options.max_recv_speed {
            self.handle.max_recv_speed(max_recv_speed.0)?;
        }
        if let Some(max_send_speed) = options.max_send_speed {
            self.handle.max_send_speed(max_send_speed.0)?;
        }
        if let Some(pinned_pub_key) = &options.pinned_pub_key {
            self.handle.pinned_public_key(pinned_pub_key)?;
        }
        if options.ntlm || options.negotiate {
            let mut auth = easy::Auth::new();
            if options.ntlm {
                auth.ntlm(true);
            }
            if options.negotiate {
                auth.gssnegotiate(true);
            }
            self.handle.http_auth(&auth)?;
        }

        self.set_ssl_options(options.ssl_no_revoke)?;

        let url = self.generate_url(&request_spec.url, &request_spec.querystring);
        self.handle.url(url.as_str())?;
        let method = &request_spec.method;
        self.set_method(method)?;
        self.set_cookies(&request_spec.cookies)?;
        self.set_form(&request_spec.form)?;
        self.set_multipart(&request_spec.multipart)?;
        let request_spec_body = &request_spec.body.bytes();
        self.set_body(request_spec_body)?;
        // TODO: do we want to manage the headers with no content? There are two type of no-content
        // headers: `foo:` and `foo;`. The first one can be used to remove libcurl headers (`Host:`)
        // while the second one is used to send an empty header.
        // See <https://github.com/Orange-OpenSource/hurl/issues/3536>
        let options_headers = options
            .headers
            .iter()