mirror of
https://git.proxmox.com/git/rustc
synced 2025-08-17 02:40:45 +00:00
1040 lines
22 KiB
Rust
1040 lines
22 KiB
Rust
use std::cell::{Cell, RefCell};
|
|
use std::io::Read;
|
|
use std::rc::Rc;
|
|
use std::str;
|
|
use std::time::Duration;
|
|
|
|
macro_rules! t {
|
|
($e:expr) => {
|
|
match $e {
|
|
Ok(e) => e,
|
|
Err(e) => panic!("{} failed with {:?}", stringify!($e), e),
|
|
}
|
|
};
|
|
}
|
|
|
|
use curl::easy::{Easy, Easy2, List, ReadError, Transfer, WriteError};
|
|
use curl::{Error, Version};
|
|
|
|
use crate::server::Server;
|
|
mod server;
|
|
|
|
fn handle() -> Easy {
|
|
let mut e = Easy::new();
|
|
t!(e.timeout(Duration::new(20, 0)));
|
|
e
|
|
}
|
|
|
|
fn sink(data: &[u8]) -> Result<usize, WriteError> {
|
|
Ok(data.len())
|
|
}
|
|
|
|
#[test]
|
|
fn get_smoke() {
|
|
let s = Server::new();
|
|
s.receive(
|
|
"\
|
|
GET / HTTP/1.1\r\n\
|
|
Host: 127.0.0.1:$PORT\r\n\
|
|
Accept: */*\r\n\
|
|
\r\n",
|
|
);
|
|
s.send("HTTP/1.1 200 OK\r\n\r\n");
|
|
|
|
let mut handle = handle();
|
|
t!(handle.url(&s.url("/")));
|
|
t!(handle.perform());
|
|
}
|
|
|
|
#[test]
|
|
fn download_zero_size() {
|
|
let s = Server::new();
|
|
s.receive(
|
|
"\
|
|
GET / HTTP/1.1\r\n\
|
|
Host: 127.0.0.1:$PORT\r\n\
|
|
Accept: */*\r\n\
|
|
\r\n",
|
|
);
|
|
s.send("HTTP/1.1 200 OK\r\n\r\n");
|
|
|
|
let mut handle = handle();
|
|
t!(handle.url(&s.url("/")));
|
|
t!(handle.perform());
|
|
assert_eq!(handle.download_size().unwrap(), 0_f64);
|
|
}
|
|
|
|
#[test]
|
|
fn download_nonzero_size() {
|
|
let s = Server::new();
|
|
s.receive(
|
|
"\
|
|
GET / HTTP/1.1\r\n\
|
|
Host: 127.0.0.1:$PORT\r\n\
|
|
Accept: */*\r\n\
|
|
\r\n",
|
|
);
|
|
s.send("HTTP/1.1 200 OK\r\n\r\nHello!");
|
|
|
|
let mut handle = handle();
|
|
t!(handle.url(&s.url("/")));
|
|
t!(handle.perform());
|
|
assert_eq!(handle.download_size().unwrap(), 6_f64);
|
|
}
|
|
|
|
#[test]
|
|
fn upload_zero_size() {
|
|
let s = Server::new();
|
|
s.receive(
|
|
"\
|
|
GET / HTTP/1.1\r\n\
|
|
Host: 127.0.0.1:$PORT\r\n\
|
|
Accept: */*\r\n\
|
|
\r\n",
|
|
);
|
|
s.send("HTTP/1.1 200 OK\r\n\r\n");
|
|
|
|
let mut handle = handle();
|
|
t!(handle.url(&s.url("/")));
|
|
t!(handle.perform());
|
|
assert_eq!(handle.upload_size().unwrap(), 0_f64);
|
|
}
|
|
|
|
#[test]
|
|
fn upload_nonzero_size() {
|
|
let s = Server::new();
|
|
s.receive(
|
|
"\
|
|
PUT / HTTP/1.1\r\n\
|
|
Host: 127.0.0.1:$PORT\r\n\
|
|
Accept: */*\r\n\
|
|
Content-Length: 5\r\n\
|
|
\r\n\
|
|
data\n",
|
|
);
|
|
s.send(
|
|
"\
|
|
HTTP/1.1 200 OK\r\n\
|
|
\r\n",
|
|
);
|
|
|
|
let mut data = "data\n".as_bytes();
|
|
let mut list = List::new();
|
|
t!(list.append("Expect:"));
|
|
let mut h = handle();
|
|
t!(h.url(&s.url("/")));
|
|
t!(h.put(true));
|
|
t!(h.in_filesize(5));
|
|
t!(h.upload(true));
|
|
t!(h.http_headers(list));
|
|
{
|
|
let mut h = h.transfer();
|
|
t!(h.read_function(|buf| Ok(data.read(buf).unwrap())));
|
|
t!(h.perform());
|
|
}
|
|
|
|
assert_eq!(h.upload_size().unwrap(), 5_f64);
|
|
}
|
|
|
|
#[test]
|
|
fn get_path() {
|
|
let s = Server::new();
|
|
s.receive(
|
|
"\
|
|
GET /foo HTTP/1.1\r\n\
|
|
Host: 127.0.0.1:$PORT\r\n\
|
|
Accept: */*\r\n\
|
|
\r\n",
|
|
);
|
|
s.send("HTTP/1.1 200 OK\r\n\r\n");
|
|
|
|
let mut handle = handle();
|
|
t!(handle.url(&s.url("/foo")));
|
|
t!(handle.perform());
|
|
}
|
|
|
|
#[test]
|
|
fn write_callback() {
|
|
let s = Server::new();
|
|
s.receive(
|
|
"\
|
|
GET / HTTP/1.1\r\n\
|
|
Host: 127.0.0.1:$PORT\r\n\
|
|
Accept: */*\r\n\
|
|
\r\n",
|
|
);
|
|
s.send("HTTP/1.1 200 OK\r\n\r\nhello!");
|
|
|
|
let mut all = Vec::<u8>::new();
|
|
{
|
|
let mut handle = handle();
|
|
t!(handle.url(&s.url("/")));
|
|
let mut handle = handle.transfer();
|
|
t!(handle.write_function(|data| {
|
|
all.extend(data);
|
|
Ok(data.len())
|
|
}));
|
|
t!(handle.perform());
|
|
}
|
|
assert_eq!(all, b"hello!");
|
|
}
|
|
|
|
#[test]
|
|
fn resolve() {
|
|
let s = Server::new();
|
|
s.receive(
|
|
"\
|
|
GET / HTTP/1.1\r\n\
|
|
Host: example.com:$PORT\r\n\
|
|
Accept: */*\r\n\
|
|
\r\n",
|
|
);
|
|
s.send("HTTP/1.1 200 OK\r\n\r\n");
|
|
|
|
let mut list = List::new();
|
|
t!(list.append(&format!("example.com:{}:127.0.0.1", s.addr().port())));
|
|
let mut handle = handle();
|
|
t!(handle.url(&format!("http://example.com:{}/", s.addr().port())));
|
|
t!(handle.resolve(list));
|
|
t!(handle.perform());
|
|
}
|
|
|
|
#[test]
|
|
fn progress() {
|
|
let s = Server::new();
|
|
s.receive(
|
|
"\
|
|
GET /foo HTTP/1.1\r\n\
|
|
Host: 127.0.0.1:$PORT\r\n\
|
|
Accept: */*\r\n\
|
|
\r\n",
|
|
);
|
|
s.send("HTTP/1.1 200 OK\r\n\r\nHello!");
|
|
|
|
let mut hits = 0;
|
|
let mut dl = 0.0;
|
|
{
|
|
let mut handle = handle();
|
|
t!(handle.url(&s.url("/foo")));
|
|
t!(handle.progress(true));
|
|
t!(handle.write_function(sink));
|
|
|
|
let mut handle = handle.transfer();
|
|
t!(handle.progress_function(|_, a, _, _| {
|
|
hits += 1;
|
|
dl = a;
|
|
true
|
|
}));
|
|
t!(handle.perform());
|
|
}
|
|
assert!(hits > 0);
|
|
assert_eq!(dl, 6.0);
|
|
}
|
|
|
|
#[test]
|
|
fn headers() {
|
|
let s = Server::new();
|
|
s.receive(
|
|
"\
|
|
GET / HTTP/1.1\r\n\
|
|
Host: 127.0.0.1:$PORT\r\n\
|
|
Accept: */*\r\n\
|
|
\r\n",
|
|
);
|
|
s.send(
|
|
"\
|
|
HTTP/1.1 200 OK\r\n\
|
|
Foo: bar\r\n\
|
|
Bar: baz\r\n\
|
|
\r\n
|
|
Hello!",
|
|
);
|
|
|
|
let mut headers = Vec::new();
|
|
{
|
|
let mut handle = handle();
|
|
t!(handle.url(&s.url("/")));
|
|
|
|
let mut handle = handle.transfer();
|
|
t!(handle.header_function(|h| {
|
|
headers.push(str::from_utf8(h).unwrap().to_string());
|
|
true
|
|
}));
|
|
t!(handle.write_function(sink));
|
|
t!(handle.perform());
|
|
}
|
|
assert_eq!(
|
|
headers,
|
|
vec![
|
|
"HTTP/1.1 200 OK\r\n".to_string(),
|
|
"Foo: bar\r\n".to_string(),
|
|
"Bar: baz\r\n".to_string(),
|
|
"\r\n".to_string(),
|
|
]
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn fail_on_error() {
|
|
let s = Server::new();
|
|
s.receive(
|
|
"\
|
|
GET / HTTP/1.1\r\n\
|
|
Host: 127.0.0.1:$PORT\r\n\
|
|
Accept: */*\r\n\
|
|
\r\n",
|
|
);
|
|
s.send(
|
|
"\
|
|
HTTP/1.1 401 Not so good\r\n\
|
|
\r\n",
|
|
);
|
|
|
|
let mut h = handle();
|
|
t!(h.url(&s.url("/")));
|
|
t!(h.fail_on_error(true));
|
|
assert!(h.perform().is_err());
|
|
|
|
let s = Server::new();
|
|
s.receive(
|
|
"\
|
|
GET / HTTP/1.1\r\n\
|
|
Host: 127.0.0.1:$PORT\r\n\
|
|
Accept: */*\r\n\
|
|
\r\n",
|
|
);
|
|
s.send(
|
|
"\
|
|
HTTP/1.1 401 Not so good\r\n\
|
|
\r\n",
|
|
);
|
|
|
|
let mut h = handle();
|
|
t!(h.url(&s.url("/")));
|
|
t!(h.fail_on_error(false));
|
|
t!(h.perform());
|
|
}
|
|
|
|
#[test]
|
|
fn port() {
|
|
let s = Server::new();
|
|
s.receive(
|
|
"\
|
|
GET / HTTP/1.1\r\n\
|
|
Host: localhost:$PORT\r\n\
|
|
Accept: */*\r\n\
|
|
\r\n",
|
|
);
|
|
s.send(
|
|
"\
|
|
HTTP/1.1 200 OK\r\n\
|
|
\r\n",
|
|
);
|
|
|
|
let mut h = handle();
|
|
t!(h.url("http://localhost/"));
|
|
t!(h.port(s.addr().port()));
|
|
t!(h.perform());
|
|
}
|
|
|
|
#[test]
|
|
fn proxy() {
|
|
let s = Server::new();
|
|
s.receive(
|
|
"\
|
|
GET http://example.com/ HTTP/1.1\r\n\
|
|
Host: example.com\r\n\
|
|
Accept: */*\r\n\
|
|
\r\n",
|
|
);
|
|
s.send(
|
|
"\
|
|
HTTP/1.1 200 OK\r\n\
|
|
\r\n",
|
|
);
|
|
|
|
let mut h = handle();
|
|
t!(h.url("http://example.com/"));
|
|
t!(h.proxy(&s.url("/")));
|
|
t!(h.perform());
|
|
}
|
|
|
|
#[test]
|
|
#[ignore] // fails on newer curl versions? seems benign
|
|
fn noproxy() {
|
|
let s = Server::new();
|
|
s.receive(
|
|
"\
|
|
GET / HTTP/1.1\r\n\
|
|
Host: 127.0.0.1:$PORT\r\n\
|
|
Accept: */*\r\n\
|
|
\r\n",
|
|
);
|
|
s.send(
|
|
"\
|
|
HTTP/1.1 200 OK\r\n\
|
|
\r\n",
|
|
);
|
|
|
|
let mut h = handle();
|
|
t!(h.url(&s.url("/")));
|
|
t!(h.proxy(&s.url("/")));
|
|
t!(h.noproxy("127.0.0.1"));
|
|
t!(h.perform());
|
|
}
|
|
|
|
#[test]
|
|
fn misc() {
|
|
let mut h = handle();
|
|
t!(h.tcp_nodelay(true));
|
|
// t!(h.tcp_keepalive(true));
|
|
// t!(h.tcp_keepidle(Duration::new(3, 0)));
|
|
// t!(h.tcp_keepintvl(Duration::new(3, 0)));
|
|
t!(h.buffer_size(10));
|
|
|
|
if Version::get().version_num() >= 0x073e00 {
|
|
// only available on curl 7.62.0 or later:
|
|
t!(h.upload_buffer_size(10));
|
|
}
|
|
|
|
t!(h.dns_cache_timeout(Duration::new(1, 0)));
|
|
}
|
|
|
|
#[test]
|
|
fn dns_servers() {
|
|
let mut h = handle();
|
|
// Tests are not using a libcurl with c-ares, so this
|
|
// always fails. Test anyway to make sure it returns
|
|
// an error instead of panicing.
|
|
assert!(h.dns_servers("").is_err());
|
|
assert!(h.dns_servers("nonsense").is_err());
|
|
assert!(h.dns_servers("8.8.8.8,8.8.4.4").is_err());
|
|
}
|
|
|
|
#[test]
|
|
fn userpass() {
|
|
let s = Server::new();
|
|
s.receive(
|
|
"\
|
|
GET / HTTP/1.1\r\n\
|
|
Authorization: Basic YmFyOg==\r\n\
|
|
Host: 127.0.0.1:$PORT\r\n\
|
|
Accept: */*\r\n\
|
|
\r\n",
|
|
);
|
|
s.send(
|
|
"\
|
|
HTTP/1.1 200 OK\r\n\
|
|
\r\n",
|
|
);
|
|
|
|
let mut h = handle();
|
|
t!(h.url(&s.url("/")));
|
|
t!(h.username("foo"));
|
|
t!(h.username("bar"));
|
|
t!(h.perform());
|
|
}
|
|
|
|
#[test]
|
|
fn accept_encoding() {
|
|
let s = Server::new();
|
|
s.receive(
|
|
"\
|
|
GET / HTTP/1.1\r\n\
|
|
Host: 127.0.0.1:$PORT\r\n\
|
|
Accept: */*\r\n\
|
|
Accept-Encoding: gzip\r\n\
|
|
\r\n",
|
|
);
|
|
s.send(
|
|
"\
|
|
HTTP/1.1 200 OK\r\n\
|
|
\r\n",
|
|
);
|
|
|
|
let mut h = handle();
|
|
t!(h.url(&s.url("/")));
|
|
t!(h.accept_encoding("gzip"));
|
|
t!(h.perform());
|
|
}
|
|
|
|
#[test]
|
|
fn follow_location() {
|
|
let s1 = Server::new();
|
|
let s2 = Server::new();
|
|
s1.receive(
|
|
"\
|
|
GET / HTTP/1.1\r\n\
|
|
Host: 127.0.0.1:$PORT\r\n\
|
|
Accept: */*\r\n\
|
|
\r\n",
|
|
);
|
|
s1.send(&format!(
|
|
"\
|
|
HTTP/1.1 301 Moved Permanently\r\n\
|
|
Location: http://{}/foo\r\n\
|
|
\r\n",
|
|
s2.addr()
|
|
));
|
|
|
|
s2.receive(
|
|
"\
|
|
GET /foo HTTP/1.1\r\n\
|
|
Host: 127.0.0.1:$PORT\r\n\
|
|
Accept: */*\r\n\
|
|
\r\n",
|
|
);
|
|
s2.send(
|
|
"\
|
|
HTTP/1.1 200 OK\r\n\
|
|
\r\n",
|
|
);
|
|
|
|
let mut h = handle();
|
|
t!(h.url(&s1.url("/")));
|
|
t!(h.follow_location(true));
|
|
t!(h.perform());
|
|
}
|
|
|
|
#[test]
|
|
fn put() {
|
|
let s = Server::new();
|
|
s.receive(
|
|
"\
|
|
PUT / HTTP/1.1\r\n\
|
|
Host: 127.0.0.1:$PORT\r\n\
|
|
Accept: */*\r\n\
|
|
Content-Length: 5\r\n\
|
|
\r\n\
|
|
data\n",
|
|
);
|
|
s.send(
|
|
"\
|
|
HTTP/1.1 200 OK\r\n\
|
|
\r\n",
|
|
);
|
|
|
|
let mut data = "data\n".as_bytes();
|
|
let mut list = List::new();
|
|
t!(list.append("Expect:"));
|
|
let mut h = handle();
|
|
t!(h.url(&s.url("/")));
|
|
t!(h.put(true));
|
|
t!(h.in_filesize(5));
|
|
t!(h.upload(true));
|
|
t!(h.http_headers(list));
|
|
let mut h = h.transfer();
|
|
t!(h.read_function(|buf| Ok(data.read(buf).unwrap())));
|
|
t!(h.perform());
|
|
}
|
|
|
|
#[test]
|
|
fn post1() {
|
|
let s = Server::new();
|
|
s.receive(
|
|
"\
|
|
POST / HTTP/1.1\r\n\
|
|
Host: 127.0.0.1:$PORT\r\n\
|
|
Accept: */*\r\n\
|
|
Content-Length: 5\r\n\
|
|
Content-Type: application/x-www-form-urlencoded\r\n\
|
|
\r\n\
|
|
data\n",
|
|
);
|
|
s.send(
|
|
"\
|
|
HTTP/1.1 200 OK\r\n\
|
|
\r\n",
|
|
);
|
|
|
|
let mut h = handle();
|
|
t!(h.url(&s.url("/")));
|
|
t!(h.post(true));
|
|
t!(h.post_fields_copy(b"data\n"));
|
|
t!(h.perform());
|
|
}
|
|
|
|
#[test]
|
|
fn post2() {
|
|
let s = Server::new();
|
|
s.receive(
|
|
"\
|
|
POST / HTTP/1.1\r\n\
|
|
Host: 127.0.0.1:$PORT\r\n\
|
|
Accept: */*\r\n\
|
|
Content-Length: 5\r\n\
|
|
Content-Type: application/x-www-form-urlencoded\r\n\
|
|
\r\n\
|
|
data\n",
|
|
);
|
|
s.send(
|
|
"\
|
|
HTTP/1.1 200 OK\r\n\
|
|
\r\n",
|
|
);
|
|
|
|
let mut h = handle();
|
|
t!(h.url(&s.url("/")));
|
|
t!(h.post(true));
|
|
t!(h.post_fields_copy(b"data\n"));
|
|
t!(h.write_function(sink));
|
|
t!(h.perform());
|
|
}
|
|
|
|
#[test]
|
|
fn post3() {
|
|
let s = Server::new();
|
|
s.receive(
|
|
"\
|
|
POST / HTTP/1.1\r\n\
|
|
Host: 127.0.0.1:$PORT\r\n\
|
|
Accept: */*\r\n\
|
|
Content-Length: 5\r\n\
|
|
Content-Type: application/x-www-form-urlencoded\r\n\
|
|
\r\n\
|
|
data\n",
|
|
);
|
|
s.send(
|
|
"\
|
|
HTTP/1.1 200 OK\r\n\
|
|
\r\n",
|
|
);
|
|
|
|
let mut data = "data\n".as_bytes();
|
|
let mut h = handle();
|
|
t!(h.url(&s.url("/")));
|
|
t!(h.post(true));
|
|
t!(h.post_field_size(5));
|
|
let mut h = h.transfer();
|
|
t!(h.read_function(|buf| Ok(data.read(buf).unwrap())));
|
|
t!(h.perform());
|
|
}
|
|
|
|
#[test]
|
|
fn referer() {
|
|
let s = Server::new();
|
|
s.receive(
|
|
"\
|
|
GET / HTTP/1.1\r\n\
|
|
Host: 127.0.0.1:$PORT\r\n\
|
|
Accept: */*\r\n\
|
|
Referer: foo\r\n\
|
|
\r\n",
|
|
);
|
|
s.send(
|
|
"\
|
|
HTTP/1.1 200 OK\r\n\
|
|
\r\n",
|
|
);
|
|
|
|
let mut h = handle();
|
|
t!(h.url(&s.url("/")));
|
|
t!(h.referer("foo"));
|
|
t!(h.perform());
|
|
}
|
|
|
|
#[test]
|
|
fn useragent() {
|
|
let s = Server::new();
|
|
s.receive(
|
|
"\
|
|
GET / HTTP/1.1\r\n\
|
|
User-Agent: foo\r\n\
|
|
Host: 127.0.0.1:$PORT\r\n\
|
|
Accept: */*\r\n\
|
|
\r\n",
|
|
);
|
|
s.send(
|
|
"\
|
|
HTTP/1.1 200 OK\r\n\
|
|
\r\n",
|
|
);
|
|
|
|
let mut h = handle();
|
|
t!(h.url(&s.url("/")));
|
|
t!(h.useragent("foo"));
|
|
t!(h.perform());
|
|
}
|
|
|
|
#[test]
|
|
fn custom_headers() {
|
|
let s = Server::new();
|
|
s.receive(
|
|
"\
|
|
GET / HTTP/1.1\r\n\
|
|
Host: 127.0.0.1:$PORT\r\n\
|
|
Foo: bar\r\n\
|
|
\r\n",
|
|
);
|
|
s.send(
|
|
"\
|
|
HTTP/1.1 200 OK\r\n\
|
|
\r\n",
|
|
);
|
|
|
|
let mut custom = List::new();
|
|
t!(custom.append("Foo: bar"));
|
|
t!(custom.append("Accept:"));
|
|
let mut h = handle();
|
|
t!(h.url(&s.url("/")));
|
|
t!(h.http_headers(custom));
|
|
t!(h.perform());
|
|
}
|
|
|
|
#[test]
|
|
fn cookie() {
|
|
let s = Server::new();
|
|
s.receive(
|
|
"\
|
|
GET / HTTP/1.1\r\n\
|
|
Host: 127.0.0.1:$PORT\r\n\
|
|
Accept: */*\r\n\
|
|
Cookie: foo\r\n\
|
|
\r\n",
|
|
);
|
|
s.send(
|
|
"\
|
|
HTTP/1.1 200 OK\r\n\
|
|
\r\n",
|
|
);
|
|
|
|
let mut h = handle();
|
|
t!(h.url(&s.url("/")));
|
|
t!(h.cookie("foo"));
|
|
t!(h.perform());
|
|
}
|
|
|
|
#[test]
|
|
fn url_encoding() {
|
|
let mut h = handle();
|
|
assert_eq!(h.url_encode(b"foo"), "foo");
|
|
assert_eq!(h.url_encode(b"foo bar"), "foo%20bar");
|
|
assert_eq!(h.url_encode(b"foo bar\xff"), "foo%20bar%FF");
|
|
assert_eq!(h.url_encode(b""), "");
|
|
assert_eq!(h.url_decode("foo"), b"foo");
|
|
assert_eq!(h.url_decode("foo%20bar"), b"foo bar");
|
|
assert_eq!(h.url_decode("foo%2"), b"foo%2");
|
|
assert_eq!(h.url_decode("foo%xx"), b"foo%xx");
|
|
assert_eq!(h.url_decode("foo%ff"), b"foo\xff");
|
|
assert_eq!(h.url_decode(""), b"");
|
|
}
|
|
|
|
#[test]
|
|
fn getters() {
|
|
let s = Server::new();
|
|
s.receive(
|
|
"\
|
|
GET / HTTP/1.1\r\n\
|
|
Host: 127.0.0.1:$PORT\r\n\
|
|
Accept: */*\r\n\
|
|
\r\n",
|
|
);
|
|
s.send(
|
|
"\
|
|
HTTP/1.1 200 OK\r\n\
|
|
\r\n",
|
|
);
|
|
|
|
let mut h = handle();
|
|
t!(h.url(&s.url("/")));
|
|
t!(h.cookie_file("/dev/null"));
|
|
t!(h.perform());
|
|
assert_eq!(t!(h.response_code()), 200);
|
|
assert_eq!(t!(h.redirect_count()), 0);
|
|
assert_eq!(t!(h.redirect_url()), None);
|
|
assert_eq!(t!(h.content_type()), None);
|
|
|
|
let addr = format!("http://{}/", s.addr());
|
|
assert_eq!(t!(h.effective_url()), Some(&addr[..]));
|
|
|
|
// TODO: test this
|
|
// let cookies = t!(h.cookies()).iter()
|
|
// .map(|s| s.to_vec())
|
|
// .collect::<Vec<_>>();
|
|
// assert_eq!(cookies.len(), 1);
|
|
}
|
|
|
|
#[test]
|
|
#[should_panic]
|
|
fn panic_in_callback() {
|
|
let s = Server::new();
|
|
s.receive(
|
|
"\
|
|
GET / HTTP/1.1\r\n\
|
|
Host: 127.0.0.1:$PORT\r\n\
|
|
Accept: */*\r\n\
|
|
\r\n",
|
|
);
|
|
s.send(
|
|
"\
|
|
HTTP/1.1 200 OK\r\n\
|
|
\r\n",
|
|
);
|
|
|
|
let mut h = handle();
|
|
t!(h.url(&s.url("/")));
|
|
t!(h.header_function(|_| panic!()));
|
|
t!(h.perform());
|
|
}
|
|
|
|
#[test]
|
|
fn abort_read() {
|
|
let s = Server::new();
|
|
// 8.7.0 seems to have changed the behavior that curl will call the read
|
|
// function before sending headers (I'm guessing so that it batches
|
|
// everything up into a single write).
|
|
if Version::get().version_num() < 0x080700 {
|
|
s.receive(
|
|
"\
|
|
PUT / HTTP/1.1\r\n\
|
|
Host: 127.0.0.1:$PORT\r\n\
|
|
Accept: */*\r\n\
|
|
Content-Length: 2\r\n\
|
|
\r\n",
|
|
);
|
|
s.send(
|
|
"\
|
|
HTTP/1.1 200 OK\r\n\
|
|
\r\n",
|
|
);
|
|
} else {
|
|
s.receive("");
|
|
}
|
|
|
|
let mut h = handle();
|
|
t!(h.url(&s.url("/")));
|
|
t!(h.read_function(|_| Err(ReadError::Abort)));
|
|
t!(h.put(true));
|
|
t!(h.in_filesize(2));
|
|
let mut list = List::new();
|
|
t!(list.append("Expect:"));
|
|
t!(h.http_headers(list));
|
|
let err = h.perform().unwrap_err();
|
|
assert!(err.is_aborted_by_callback());
|
|
}
|
|
|
|
#[test]
|
|
fn pause_write_then_resume() {
|
|
let s = Server::new();
|
|
s.receive(
|
|
"\
|
|
GET / HTTP/1.1\r\n\
|
|
Host: 127.0.0.1:$PORT\r\n\
|
|
Accept: */*\r\n\
|
|
\r\n",
|
|
);
|
|
s.send(
|
|
"\
|
|
HTTP/1.1 200 OK\r\n\
|
|
\r\n
|
|
a\n
|
|
b",
|
|
);
|
|
|
|
let mut h = handle();
|
|
t!(h.url(&s.url("/")));
|
|
t!(h.progress(true));
|
|
|
|
struct State<'a, 'b> {
|
|
paused: Cell<bool>,
|
|
unpaused: Cell<bool>,
|
|
transfer: RefCell<Transfer<'a, 'b>>,
|
|
}
|
|
|
|
let h = Rc::new(State {
|
|
paused: Cell::new(false),
|
|
unpaused: Cell::new(false),
|
|
transfer: RefCell::new(h.transfer()),
|
|
});
|
|
|
|
let h2 = h.clone();
|
|
t!(h.transfer
|
|
.borrow_mut()
|
|
.write_function(move |data| if h2.unpaused.get() {
|
|
h2.unpaused.set(false);
|
|
Ok(data.len())
|
|
} else {
|
|
h2.paused.set(true);
|
|
Err(WriteError::Pause)
|
|
}));
|
|
let h2 = h.clone();
|
|
t!(h.transfer
|
|
.borrow_mut()
|
|
.progress_function(move |_, _, _, _| {
|
|
if h2.paused.get() {
|
|
h2.paused.set(false);
|
|
h2.unpaused.set(true);
|
|
t!(h2.transfer.borrow().unpause_write());
|
|
}
|
|
true
|
|
}));
|
|
t!(h.transfer.borrow().perform());
|
|
}
|
|
|
|
#[test]
|
|
fn perform_in_perform_is_bad() {
|
|
let s = Server::new();
|
|
s.receive(
|
|
"\
|
|
GET / HTTP/1.1\r\n\
|
|
Host: 127.0.0.1:$PORT\r\n\
|
|
Accept: */*\r\n\
|
|
\r\n",
|
|
);
|
|
s.send(
|
|
"\
|
|
HTTP/1.1 200 OK\r\n\
|
|
\r\n
|
|
a\n
|
|
b",
|
|
);
|
|
|
|
let mut h = handle();
|
|
t!(h.url(&s.url("/")));
|
|
t!(h.progress(true));
|
|
|
|
let h = Rc::new(RefCell::new(h.transfer()));
|
|
|
|
let h2 = h.clone();
|
|
t!(h.borrow_mut().write_function(move |data| {
|
|
assert!(h2.borrow().perform().is_err());
|
|
Ok(data.len())
|
|
}));
|
|
t!(h.borrow().perform());
|
|
}
|
|
|
|
#[cfg(not(windows))]
|
|
#[test]
|
|
fn check_unix_socket() {
|
|
let s = Server::new_unix();
|
|
s.receive(
|
|
"\
|
|
POST / HTTP/1.1\r\n\
|
|
Host: localhost\r\n\
|
|
Accept: */*\r\n\
|
|
Content-Length: 5\r\n\
|
|
Content-Type: application/x-www-form-urlencoded\r\n\
|
|
\r\n\
|
|
data\n",
|
|
);
|
|
s.send(
|
|
"\
|
|
HTTP/1.1 200 OK\r\n\
|
|
\r\n",
|
|
);
|
|
|
|
let mut h = handle();
|
|
t!(h.unix_socket(s.path()));
|
|
t!(h.url(&s.url("/")));
|
|
t!(h.post(true));
|
|
t!(h.post_fields_copy(b"data\n"));
|
|
t!(h.perform());
|
|
}
|
|
|
|
#[cfg(feature = "upkeep_7_62_0")]
|
|
#[test]
|
|
fn test_upkeep() {
|
|
let s = Server::new();
|
|
s.receive(
|
|
"\
|
|
GET / HTTP/1.1\r\n\
|
|
Host: 127.0.0.1:$PORT\r\n\
|
|
Accept: */*\r\n\
|
|
\r\n",
|
|
);
|
|
s.send("HTTP/1.1 200 OK\r\n\r\n");
|
|
|
|
let mut handle = handle();
|
|
t!(handle.url(&s.url("/")));
|
|
t!(handle.perform());
|
|
|
|
// Ensure that upkeep can be called on the handle without problem.
|
|
t!(handle.upkeep());
|
|
}
|
|
|
|
#[test]
|
|
fn path_as_is() {
|
|
let s = Server::new();
|
|
s.receive(
|
|
"\
|
|
GET /test/../ HTTP/1.1\r\n\
|
|
Host: 127.0.0.1:$PORT\r\n\
|
|
Accept: */*\r\n\
|
|
\r\n",
|
|
);
|
|
s.send(
|
|
"\
|
|
HTTP/1.1 200 OK\r\n\
|
|
\r\n",
|
|
);
|
|
|
|
let mut h = handle();
|
|
t!(h.url(&s.url("/test/../")));
|
|
t!(h.path_as_is(true));
|
|
t!(h.perform());
|
|
|
|
let addr = format!("http://{}/test/../", s.addr());
|
|
assert_eq!(t!(h.response_code()), 200);
|
|
assert_eq!(t!(h.effective_url()), Some(&addr[..]));
|
|
}
|
|
|
|
#[test]
|
|
fn test_connect_timeout() {
|
|
use curl::easy::Handler;
|
|
struct Collector(Vec<u8>);
|
|
|
|
impl Handler for Collector {
|
|
fn write(&mut self, data: &[u8]) -> Result<usize, WriteError> {
|
|
self.0.extend_from_slice(data);
|
|
Ok(data.len())
|
|
}
|
|
}
|
|
let mut easy2 = Easy2::new(Collector(Vec::new()));
|
|
|
|
// Overflow value test must return an Error
|
|
assert_eq!(
|
|
Error::new(curl_sys::CURLE_BAD_FUNCTION_ARGUMENT),
|
|
easy2
|
|
.connect_timeout(Duration::from_secs(std::u64::MAX))
|
|
.unwrap_err()
|
|
);
|
|
|
|
// Valid value
|
|
assert_eq!(
|
|
(),
|
|
easy2
|
|
.connect_timeout(Duration::from_millis(i32::MAX as u64))
|
|
.unwrap()
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn test_timeout() {
|
|
use curl::easy::Handler;
|
|
struct Collector(Vec<u8>);
|
|
|
|
impl Handler for Collector {
|
|
fn write(&mut self, data: &[u8]) -> Result<usize, WriteError> {
|
|
self.0.extend_from_slice(data);
|
|
Ok(data.len())
|
|
}
|
|
}
|
|
let mut easy2 = Easy2::new(Collector(Vec::new()));
|
|
|
|
// Overflow value test must return an Error
|
|
assert_eq!(
|
|
Error::new(curl_sys::CURLE_BAD_FUNCTION_ARGUMENT),
|
|
easy2
|
|
.timeout(Duration::from_secs(std::u64::MAX))
|
|
.unwrap_err()
|
|
);
|
|
|
|
// Valid value
|
|
assert_eq!(
|
|
(),
|
|
easy2
|
|
.timeout(Duration::from_millis(i32::MAX as u64))
|
|
.unwrap()
|
|
);
|
|
}
|