Skip to content

Commit 43af9ab

Browse files
committed
Add alpn switch to windows and openssl targets
1 parent 06e0af7 commit 43af9ab

File tree

6 files changed

+50
-48
lines changed

6 files changed

+50
-48
lines changed

Cargo.toml

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,7 @@ readme = "README.md"
99

1010
[features]
1111
vendored = ["openssl/vendored"]
12-
13-
# Switch for MacOS to keep support for older versions, Windows targets and openssl target will have alpn regardless
14-
alpn = ["security-framework/alpn"]
12+
alpn = ["security-framework/alpn", "openssl/v102"]
1513

1614
[target.'cfg(any(target_os = "macos", target_os = "ios"))'.dependencies]
1715
security-framework = "2.0.0"

src/imp/openssl.rs

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -274,21 +274,24 @@ impl TlsConnector {
274274
}
275275
}
276276

277-
if !builder.alpn.is_empty() {
278-
// Wire format is each alpn preceded by its length as a byte.
279-
let mut alpn_wire_format = Vec::with_capacity(
280-
builder
281-
.alpn
282-
.iter()
283-
.map(|s| s.as_bytes().len())
284-
.sum::<usize>()
285-
+ builder.alpn.len(),
286-
);
287-
for alpn in builder.alpn.iter().map(|s| s.as_bytes()) {
288-
alpn_wire_format.push(alpn.len() as u8);
289-
alpn_wire_format.extend(alpn);
277+
#[cfg(feature = "alpn")]
278+
{
279+
if !builder.alpn.is_empty() {
280+
// Wire format is each alpn preceded by its length as a byte.
281+
let mut alpn_wire_format = Vec::with_capacity(
282+
builder
283+
.alpn
284+
.iter()
285+
.map(|s| s.as_bytes().len())
286+
.sum::<usize>()
287+
+ builder.alpn.len(),
288+
);
289+
for alpn in builder.alpn.iter().map(|s| s.as_bytes()) {
290+
alpn_wire_format.push(alpn.len() as u8);
291+
alpn_wire_format.extend(alpn);
292+
}
293+
connector.set_alpn_protos(&alpn_wire_format)?;
290294
}
291-
connector.set_alpn_protos(&alpn_wire_format)?;
292295
}
293296

294297
#[cfg(target_os = "android")]
@@ -383,6 +386,7 @@ impl<S: io::Read + io::Write> TlsStream<S> {
383386
Ok(self.0.ssl().peer_certificate().map(Certificate))
384387
}
385388

389+
#[cfg(feature = "alpn")]
386390
pub fn negotiated_alpn(&self) -> Result<Option<Vec<u8>>, Error> {
387391
Ok(self
388392
.0

src/imp/schannel.rs

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,8 @@ impl Identity {
8686
return Err(io::Error::new(
8787
io::ErrorKind::InvalidInput,
8888
"No identity found in PKCS #12 archive",
89-
).into());
89+
)
90+
.into());
9091
}
9192
};
9293

@@ -112,7 +113,8 @@ impl Certificate {
112113
Err(_) => Err(io::Error::new(
113114
io::ErrorKind::InvalidInput,
114115
"PEM representation contains non-UTF-8 bytes",
115-
).into()),
116+
)
117+
.into()),
116118
}
117119
}
118120

@@ -251,8 +253,13 @@ impl TlsConnector {
251253
))
252254
});
253255
}
254-
if !self.alpn.is_empty() {
255-
builder.request_application_protocols(&self.alpn.iter().map(|s| s.as_bytes()).collect::<Vec<_>>());
256+
#[cfg(feature = "alpn")]
257+
{
258+
if !self.alpn.is_empty() {
259+
builder.request_application_protocols(
260+
&self.alpn.iter().map(|s| s.as_bytes()).collect::<Vec<_>>(),
261+
);
262+
}
256263
}
257264
match builder.connect(cred, stream) {
258265
Ok(s) => Ok(TlsStream(s)),
@@ -324,6 +331,7 @@ impl<S: io::Read + io::Write> TlsStream<S> {
324331
}
325332
}
326333

334+
#[cfg(feature = "alpn")]
327335
pub fn negotiated_alpn(&self) -> Result<Option<Vec<u8>>, Error> {
328336
Ok(self.0.negotiated_application_protocol()?)
329337
}

src/imp/security_framework.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -306,8 +306,11 @@ impl TlsConnector {
306306
builder.danger_accept_invalid_certs(self.danger_accept_invalid_certs);
307307
builder.trust_anchor_certificates_only(self.disable_built_in_roots);
308308

309-
if !self.alpn.is_empty() {
310-
builder.alpn_protocols(&self.alpn.iter().map(String::as_str).collect::<Vec<_>>());
309+
#[cfg(feature = "alpn")]
310+
{
311+
if !self.alpn.is_empty() {
312+
builder.alpn_protocols(&self.alpn.iter().map(String::as_str).collect::<Vec<_>>());
313+
}
311314
}
312315

313316
match builder.handshake(domain, stream) {
@@ -395,6 +398,7 @@ impl<S: io::Read + io::Write> TlsStream<S> {
395398
Ok(trust.certificate_at_index(0).map(Certificate))
396399
}
397400

401+
#[cfg(feature = "alpn")]
398402
pub fn negotiated_alpn(&self) -> Result<Option<Vec<u8>>, Error> {
399403
match self.stream.context().alpn_protocols() {
400404
Ok(protocols) => {

src/lib.rs

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -380,6 +380,7 @@ impl TlsConnectorBuilder {
380380
/// Request specific protocols through ALPN (Application-Layer Protocol Negotiation).
381381
///
382382
/// Defaults to none
383+
#[cfg(feature = "alpn")]
383384
pub fn request_alpns(&mut self, protocols: &[&str]) -> &mut TlsConnectorBuilder {
384385
self.alpn = protocols.iter().map(|s| (*s).to_owned()).collect();
385386
self
@@ -655,12 +656,9 @@ impl<S: io::Read + io::Write> TlsStream<S> {
655656
}
656657

657658
/// Returns the negotiated ALPN protocols
658-
pub fn negotiated_alpn(&self) -> Result<Option<String>> {
659-
let protocol = self
660-
.0
661-
.negotiated_alpn()?
662-
.map(|bytes| String::from_utf8_lossy(&bytes).into_owned());
663-
Ok(protocol)
659+
#[cfg(feature = "alpn")]
660+
pub fn negotiated_alpn(&self) -> Result<Option<Vec<u8>>> {
661+
Ok(self.0.negotiated_alpn()?)
664662
}
665663

666664
/// Shuts down the TLS session.

src/test.rs

Lines changed: 9 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -420,42 +420,32 @@ mod tests {
420420
}
421421

422422
#[test]
423-
#[cfg_attr(not(feature = "alpn"), ignore)]
423+
#[cfg(feature = "alpn")]
424424
fn alpn_google_h2() {
425425
let builder = p!(TlsConnector::builder().request_alpns(&["h2"]).build());
426426
let s = p!(TcpStream::connect("google.com:443"));
427427
let socket = p!(builder.connect("google.com", s));
428-
429-
assert_eq!(
430-
p!(socket.negotiated_alpn())
431-
.as_ref()
432-
.map(|alpn| alpn.as_str()),
433-
Some("h2")
434-
);
428+
let alpn = p!(socket.negotiated_alpn());
429+
assert_eq!(alpn.as_deref(), Some(b"h2".as_ref()));
435430
}
436431

437432
#[test]
438-
#[cfg_attr(not(feature = "alpn"), ignore)]
433+
#[cfg(feature = "alpn")]
439434
fn alpn_google_invalid() {
440435
let builder = p!(TlsConnector::builder().request_alpns(&["h2c"]).build());
441436
let s = p!(TcpStream::connect("google.com:443"));
442437
let socket = p!(builder.connect("google.com", s));
443-
444-
assert_eq!(
445-
p!(socket.negotiated_alpn())
446-
.as_ref()
447-
.map(|alpn| alpn.as_str()),
448-
None
449-
);
438+
let alpn = p!(socket.negotiated_alpn());
439+
assert_eq!(alpn.as_deref(), None);
450440
}
451441

452442
#[test]
453-
#[cfg_attr(not(feature = "alpn"), ignore)]
443+
#[cfg(feature = "alpn")]
454444
fn alpn_google_none() {
455445
let builder = p!(TlsConnector::new());
456446
let s = p!(TcpStream::connect("google.com:443"));
457447
let socket = p!(builder.connect("google.com", s));
458-
459-
assert_eq!(p!(socket.negotiated_alpn()), None);
448+
let alpn = p!(socket.negotiated_alpn());
449+
assert_eq!(alpn.as_deref(), None);
460450
}
461451
}

0 commit comments

Comments
 (0)