Skip to content

Commit 207c335

Browse files
authored
Merge pull request #176 from blackbeam/v0.29.0-release
v0.29.0 release
2 parents 7b59d28 + df6328f commit 207c335

File tree

7 files changed

+61
-127
lines changed

7 files changed

+61
-127
lines changed

Cargo.toml

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ license = "MIT/Apache-2.0"
77
name = "mysql_async"
88
readme = "README.md"
99
repository = "https://github.com/blackbeam/mysql_async"
10-
version = "0.28.1"
10+
version = "0.29.0"
1111
exclude = ["test/*"]
1212
edition = "2018"
1313
categories = ["asynchronous", "database"]
@@ -20,16 +20,17 @@ futures-core = "0.3"
2020
futures-util = "0.3"
2121
futures-sink = "0.3"
2222
lazy_static = "1"
23-
lru = "0.6.0"
24-
mio = "0.7.7"
25-
mysql_common = { version = "0.27.2", default-features = false }
23+
lru = "0.7.0"
24+
mio = { version = "0.8.0", features = ["os-poll", "net"] }
25+
mysql_common = { version = "0.28.0", default-features = false }
2626
native-tls = "0.2"
2727
once_cell = "1.7.2"
28-
pem = "0.8.1"
28+
pem = "1.0.1"
2929
percent-encoding = "2.1.0"
3030
pin-project = "1.0.2"
3131
serde = "1"
3232
serde_json = "1"
33+
socket2 = "0.4.2"
3334
thiserror = "1.0.4"
3435
tokio = { version = "1.0", features = ["io-util", "fs", "net", "time", "rt"] }
3536
tokio-util = { version = "0.6.0", features = ["codec"] }
@@ -47,10 +48,9 @@ rand = "0.8.0"
4748
[features]
4849
default = [
4950
"flate2/zlib",
50-
"mysql_common/bigdecimal",
51-
"mysql_common/chrono",
51+
"mysql_common/bigdecimal03",
5252
"mysql_common/rust_decimal",
53-
"mysql_common/time",
53+
"mysql_common/time03",
5454
"mysql_common/uuid",
5555
"mysql_common/frunk",
5656
]

azure-pipelines.yml

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ jobs:
5151
5252
- job: "TestBasicWindows"
5353
pool:
54-
vmImage: "vs2017-win2016"
54+
vmImage: "windows-2019"
5555
strategy:
5656
maxParallel: 10
5757
matrix:
@@ -136,6 +136,10 @@ jobs:
136136
strategy:
137137
maxParallel: 10
138138
matrix:
139+
v107:
140+
DB_VERSION: "10.7"
141+
v106:
142+
DB_VERSION: "10.6"
139143
v105:
140144
DB_VERSION: "10.5"
141145
v104:
@@ -156,12 +160,15 @@ jobs:
156160
displayName: Install docker
157161
- bash: |
158162
git clone https://github.com/blackbeam/rust-mysql-simple.git
163+
cd rust-mysql-simple
164+
git checkout 8d745ee
159165
displayName: Clone rust-mysql-simple (for ssl certs)
160166
- bash: |
161167
docker run --rm -d \
162168
--name container \
163169
-v `pwd`:/root \
164170
-p 3307:3306 \
171+
-e MARIADB_ROOT_PASSWORD=password \
165172
-e MYSQL_ROOT_PASSWORD=password \
166173
mariadb:$(DB_VERSION) \
167174
--max-allowed-packet=36700160 \

src/conn/mod.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -429,9 +429,14 @@ impl Conn {
429429
async fn handle_handshake(&mut self) -> Result<()> {
430430
let packet = self.read_packet().await?;
431431
let handshake = ParseBuf(&*packet).parse::<HandshakePacket>(())?;
432+
433+
// Handshake scramble is always 21 bytes length (20 + zero terminator)
432434
self.inner.nonce = {
433435
let mut nonce = Vec::from(handshake.scramble_1_ref());
434436
nonce.extend_from_slice(handshake.scramble_2_ref().unwrap_or(&[][..]));
437+
// Trim zero terminator. Fill with zeroes if nonce
438+
// is somehow smaller than 20 bytes (this matches the server behavior).
439+
nonce.resize(20, 0);
435440
nonce
436441
};
437442

src/io/mod.rs

Lines changed: 32 additions & 96 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,10 @@ pub use self::{read_packet::ReadPacket, write_packet::WritePacket};
1010

1111
use bytes::BytesMut;
1212
use futures_core::{ready, stream};
13-
use futures_util::stream::{FuturesUnordered, StreamExt};
14-
use mio::net::{TcpKeepalive, TcpSocket};
1513
use mysql_common::proto::codec::PacketCodec as PacketCodecInner;
1614
use native_tls::{Certificate, Identity, TlsConnector};
1715
use pin_project::pin_project;
16+
use socket2::{Socket as Socket2Socket, TcpKeepalive};
1817
#[cfg(unix)]
1918
use tokio::io::AsyncWriteExt;
2019
use tokio::{
@@ -35,14 +34,17 @@ use std::{
3534
Read,
3635
},
3736
mem::replace,
38-
net::{SocketAddr, ToSocketAddrs},
3937
ops::{Deref, DerefMut},
4038
pin::Pin,
4139
task::{Context, Poll},
4240
time::Duration,
4341
};
4442

45-
use crate::{buffer_pool::PooledBuf, error::IoError, opts::SslOpts};
43+
use crate::{
44+
buffer_pool::PooledBuf,
45+
error::IoError,
46+
opts::{HostPortOrUrl, SslOpts, DEFAULT_PORT},
47+
};
4648

4749
#[cfg(unix)]
4850
use crate::io::socket::Socket;
@@ -208,6 +210,7 @@ impl Endpoint {
208210
.map(|x| vec![x])
209211
.or_else(|_| {
210212
pem::parse_many(&*root_cert_data)
213+
.unwrap_or_default()
211214
.iter()
212215
.map(pem::encode)
213216
.map(|s| Certificate::from_pem(s.as_bytes()))
@@ -354,108 +357,41 @@ impl Stream {
354357
}
355358
}
356359

357-
pub(crate) async fn connect_tcp<S>(addr: S, keepalive: Option<Duration>) -> io::Result<Stream>
358-
where
359-
S: ToSocketAddrs,
360-
{
361-
// TODO: Use tokio to setup keepalive (see tokio-rs/tokio#3082)
362-
async fn connect_stream(
363-
addr: SocketAddr,
364-
keepalive_opts: Option<TcpKeepalive>,
365-
) -> io::Result<TcpStream> {
366-
let socket = if addr.is_ipv6() {
367-
TcpSocket::new_v6()?
368-
} else {
369-
TcpSocket::new_v4()?
370-
};
371-
372-
if let Some(keepalive_opts) = keepalive_opts {
373-
socket.set_keepalive_params(keepalive_opts)?;
360+
pub(crate) async fn connect_tcp(
361+
addr: &HostPortOrUrl,
362+
keepalive: Option<Duration>,
363+
) -> io::Result<Stream> {
364+
let tcp_stream = match addr {
365+
HostPortOrUrl::HostPort(host, port) => {
366+
TcpStream::connect((host.as_str(), *port)).await?
374367
}
368+
HostPortOrUrl::Url(url) => {
369+
let addrs = url.socket_addrs(|| Some(DEFAULT_PORT))?;
370+
TcpStream::connect(&*addrs).await?
371+
}
372+
};
375373

376-
let stream = tokio::task::spawn_blocking(move || {
377-
let mut stream = socket.connect(addr)?;
378-
let mut poll = mio::Poll::new()?;
379-
let mut events = mio::Events::with_capacity(1024);
380-
381-
poll.registry()
382-
.register(&mut stream, mio::Token(0), mio::Interest::WRITABLE)?;
383-
384-
loop {
385-
poll.poll(&mut events, None)?;
386-
387-
for event in &events {
388-
if event.token() == mio::Token(0) && event.is_error() {
389-
return Err(io::Error::new(
390-
io::ErrorKind::ConnectionRefused,
391-
"Connection refused",
392-
));
393-
}
394-
395-
if event.token() == mio::Token(0) && event.is_writable() {
396-
// The socket connected (probably, it could still be a spurious
397-
// wakeup)
398-
return Ok::<_, io::Error>(stream);
399-
}
400-
}
401-
}
402-
})
403-
.await??;
404-
374+
if let Some(duration) = keepalive {
405375
#[cfg(unix)]
406-
let std_stream = unsafe {
376+
let socket = unsafe {
407377
use std::os::unix::prelude::*;
408-
let fd = stream.into_raw_fd();
409-
std::net::TcpStream::from_raw_fd(fd)
378+
let fd = tcp_stream.as_raw_fd();
379+
Socket2Socket::from_raw_fd(fd)
410380
};
411-
412381
#[cfg(windows)]
413-
let std_stream = unsafe {
382+
let socket = unsafe {
414383
use std::os::windows::prelude::*;
415-
let fd = stream.into_raw_socket();
416-
std::net::TcpStream::from_raw_socket(fd)
384+
let sock = tcp_stream.as_raw_socket();
385+
Socket2Socket::from_raw_socket(sock)
417386
};
418-
419-
Ok(TcpStream::from_std(std_stream)?)
387+
socket.set_tcp_keepalive(&TcpKeepalive::new().with_time(duration))?;
388+
std::mem::forget(socket);
420389
}
421390

422-
let keepalive_opts = keepalive.map(|time| TcpKeepalive::new().with_time(time));
423-
424-
match addr.to_socket_addrs() {
425-
Ok(addresses) => {
426-
let mut streams = FuturesUnordered::new();
427-
428-
for address in addresses {
429-
streams.push(connect_stream(address, keepalive_opts.clone()));
430-
}
431-
432-
let mut err = None;
433-
while let Some(stream) = streams.next().await {
434-
match stream {
435-
Err(e) => {
436-
err = Some(e);
437-
}
438-
Ok(stream) => {
439-
return Ok(Stream {
440-
closed: false,
441-
codec: Box::new(Framed::new(stream.into(), PacketCodec::default()))
442-
.into(),
443-
});
444-
}
445-
}
446-
}
447-
448-
if let Some(e) = err {
449-
Err(e)
450-
} else {
451-
Err(io::Error::new(
452-
io::ErrorKind::InvalidInput,
453-
"could not resolve to any address",
454-
))
455-
}
456-
}
457-
Err(err) => Err(err),
458-
}
391+
Ok(Stream {
392+
closed: false,
393+
codec: Box::new(Framed::new(tcp_stream.into(), PacketCodec::default())).into(),
394+
})
459395
}
460396

461397
#[cfg(unix)]

src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@
9191
#[cfg(feature = "nightly")]
9292
extern crate test;
9393

94-
pub use mysql_common::{chrono, constants as consts, params, time, uuid};
94+
pub use mysql_common::{constants as consts, params};
9595

9696
use std::sync::Arc;
9797

src/opts.rs

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,7 @@ use url::{Host, Url};
1212
use std::{
1313
borrow::Cow,
1414
convert::TryFrom,
15-
io,
16-
net::{Ipv4Addr, Ipv6Addr, SocketAddr, ToSocketAddrs},
15+
net::{Ipv4Addr, Ipv6Addr},
1716
path::Path,
1817
str::FromStr,
1918
sync::Arc,
@@ -40,7 +39,7 @@ const_assert!(
4039
pub const DEFAULT_STMT_CACHE_SIZE: usize = 32;
4140

4241
/// Default server port.
43-
const DEFAULT_PORT: u16 = 3306;
42+
pub const DEFAULT_PORT: u16 = 3306;
4443

4544
/// Default `inactive_connection_ttl` of a pool.
4645
///
@@ -67,19 +66,6 @@ impl Default for HostPortOrUrl {
6766
}
6867
}
6968

70-
impl ToSocketAddrs for HostPortOrUrl {
71-
type Iter = vec::IntoIter<SocketAddr>;
72-
73-
fn to_socket_addrs(&self) -> io::Result<vec::IntoIter<SocketAddr>> {
74-
let res = match self {
75-
Self::Url(url) => url.socket_addrs(|| Some(DEFAULT_PORT))?.into_iter(),
76-
Self::HostPort(host, port) => (host.as_ref(), *port).to_socket_addrs()?,
77-
};
78-
79-
Ok(res)
80-
}
81-
}
82-
8369
impl HostPortOrUrl {
8470
pub fn get_ip_or_hostname(&self) -> &str {
8571
match self {

tests/exports.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
#[allow(unused_imports)]
22
use mysql_async::{
3-
chrono, consts, from_row, from_row_opt, from_value, from_value_opt,
3+
consts, from_row, from_row_opt, from_value, from_value_opt,
44
futures::{DisconnectPool, GetConn},
55
params,
66
prelude::{
77
BatchQuery, ConvIr, FromRow, FromValue, LocalInfileHandler, Protocol, Query, Queryable,
88
StatementLike, ToValue,
99
},
10-
time, uuid, BinaryProtocol, Column, Conn, Deserialized, DriverError, Error, FromRowError,
11-
FromValueError, IoError, IsolationLevel, Opts, OptsBuilder, Params, ParseError, Pool,
12-
PoolConstraints, PoolOpts, QueryResult, Result, Row, Serialized, ServerError, SslOpts,
13-
Statement, TextProtocol, Transaction, TxOpts, UrlError, Value, WhiteListFsLocalInfileHandler,
10+
BinaryProtocol, Column, Conn, Deserialized, DriverError, Error, FromRowError, FromValueError,
11+
IoError, IsolationLevel, Opts, OptsBuilder, Params, ParseError, Pool, PoolConstraints,
12+
PoolOpts, QueryResult, Result, Row, Serialized, ServerError, SslOpts, Statement, TextProtocol,
13+
Transaction, TxOpts, UrlError, Value, WhiteListFsLocalInfileHandler,
1414
DEFAULT_INACTIVE_CONNECTION_TTL, DEFAULT_TTL_CHECK_INTERVAL,
1515
};

0 commit comments

Comments
 (0)