mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-24 19:37:15 +00:00
Bug 1749893 - P1 - mach vendor rust;r=mjf
Depends on D135818 Differential Revision: https://phabricator.services.mozilla.com/D135819
This commit is contained in:
parent
0cf4dd0932
commit
b36bf46d68
4
Cargo.lock
generated
4
Cargo.lock
generated
@ -5742,9 +5742,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "webrtc-sdp"
|
||||
version = "0.3.8"
|
||||
version = "0.3.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "98db6ff463a94d727ee7c1188bab33146468add6dfb94df30a1f4a3495a700d9"
|
||||
checksum = "99abde0f90c17b56ccc3c105f719d61535003862bdb357465f04181ca667ca16"
|
||||
dependencies = [
|
||||
"log",
|
||||
"url",
|
||||
|
File diff suppressed because one or more lines are too long
4
third_party/rust/webrtc-sdp/CHANGELOG.md
vendored
4
third_party/rust/webrtc-sdp/CHANGELOG.md
vendored
@ -1,4 +1,8 @@
|
||||
# Changelog
|
||||
## [0.3.9] - 2022-01-12
|
||||
- Add support for RFC8858 rtcp-mux-only
|
||||
- Correct seperation of tokens in FMTP parameters
|
||||
- Do not emit an empty line after a media description
|
||||
## [0.3.8] - 2021-01-16
|
||||
- fmt numbers 35 to 63 are now usable for dynamic allocation
|
||||
- parse extmap-allow-mixed as per RFC 8285
|
||||
|
114
third_party/rust/webrtc-sdp/Cargo.lock
generated
vendored
114
third_party/rust/webrtc-sdp/Cargo.lock
generated
vendored
@ -1,16 +1,28 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "0.1.10"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
|
||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "form_urlencoded"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5fc25a87fa4fd2094bffb06925852034d90a17f0d1e05197d4956d3555752191"
|
||||
dependencies = [
|
||||
"matches",
|
||||
"percent-encoding",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "idna"
|
||||
version = "0.2.0"
|
||||
version = "0.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "02e2673c30ee86b5b96a9cb52ad15718aa1f966f5ab9ad54a8b95d5ca33120a9"
|
||||
checksum = "418a0a6fab821475f634efe3ccc45c013f742efe03d853e8d3355d5cb850ecf8"
|
||||
dependencies = [
|
||||
"matches",
|
||||
"unicode-bidi",
|
||||
@ -19,30 +31,24 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "0.4.4"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "501266b7edd0174f8530248f87f99c88fbe60ca4ef3dd486835b8d8d53136f7f"
|
||||
checksum = "1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35"
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.8"
|
||||
version = "0.4.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7"
|
||||
checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "matches"
|
||||
version = "0.1.8"
|
||||
version = "0.1.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08"
|
||||
|
||||
[[package]]
|
||||
name = "maybe-uninit"
|
||||
version = "2.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00"
|
||||
checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f"
|
||||
|
||||
[[package]]
|
||||
name = "percent-encoding"
|
||||
@ -52,39 +58,39 @@ checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.6"
|
||||
version = "1.0.36"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9c9e470a8dc4aeae2dee2f335e8f533e2d4b347e1434e5671afc49b054592f27"
|
||||
checksum = "c7342d5883fbccae1cc37a2353b09c87c9b0f3afd73f5fb9bba687a1f733b029"
|
||||
dependencies = [
|
||||
"unicode-xid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.2"
|
||||
version = "1.0.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "053a8c8bcc71fcce321828dc897a98ab9760bef03a4fc36693c231e5b3216cfe"
|
||||
checksum = "47aa80447ce4daf1717500037052af176af5d38cc3e571d9ec1c7353fc10c87d"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ryu"
|
||||
version = "1.0.2"
|
||||
version = "1.0.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bfa8506c1de11c9c4e4c38863ccbe02a305c8188e85a05a784c9e11e1c3910c8"
|
||||
checksum = "73b4b750c782965c211b42f022f59af1fbceabdd026623714f104152f1ec149f"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.102"
|
||||
version = "1.0.133"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0c4b39bd9b0b087684013a792c59e3e07a46a01d2322518d8a1104641a0b1be0"
|
||||
checksum = "97565067517b60e2d1ea8b268e59ce036de907ac523ad83a0475da04e818989a"
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.102"
|
||||
version = "1.0.133"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ca13fc1a832f793322228923fbb3aba9f3f44444898f835d31ad1b74fa0a2bf8"
|
||||
checksum = "ed201699328568d8d08208fdd080e3ff594e6c422e438b6705905da01005d537"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@ -93,29 +99,20 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.41"
|
||||
version = "1.0.74"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2f72eb2a68a7dc3f9a691bfda9305a1c017a6215e5a4545c258500d2099a37c2"
|
||||
checksum = "ee2bb9cd061c5865d345bb02ca49fcef1391741b672b54a0bf7b679badec3142"
|
||||
dependencies = [
|
||||
"itoa",
|
||||
"ryu",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "smallvec"
|
||||
version = "0.6.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f7b0758c52e15a8b5e3691eae6cc559f08eee9406e548a4477ba4e67770a82b6"
|
||||
dependencies = [
|
||||
"maybe-uninit",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.8"
|
||||
version = "1.0.85"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "661641ea2aa15845cddeb97dad000d22070bb5c1fb456b96c1cba883ec691e92"
|
||||
checksum = "a684ac3dcd8913827e18cd09a68384ee66c1de24157e3c556c9ab16d85695fb7"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@ -123,35 +120,48 @@ dependencies = [
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-bidi"
|
||||
version = "0.3.4"
|
||||
name = "tinyvec"
|
||||
version = "1.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "49f2bd0c6468a8230e1db229cff8029217cf623c767ea5d60bfbd42729ea54d5"
|
||||
checksum = "2c1c1d5a42b6245520c249549ec267180beaffcc0615401ac8e31853d4b6d8d2"
|
||||
dependencies = [
|
||||
"matches",
|
||||
"tinyvec_macros",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-normalization"
|
||||
version = "0.1.9"
|
||||
name = "tinyvec_macros"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "09c8070a9942f5e7cfccd93f490fdebd230ee3c3c9f107cb25bad5351ef671cf"
|
||||
checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-bidi"
|
||||
version = "0.3.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1a01404663e3db436ed2746d9fefef640d868edae3cceb81c3b8d5732fda678f"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-normalization"
|
||||
version = "0.1.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d54590932941a9e9266f0832deed84ebe1bf2e4c9e4a3554d393d18f5e854bf9"
|
||||
dependencies = [
|
||||
"smallvec",
|
||||
"tinyvec",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-xid"
|
||||
version = "0.2.0"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c"
|
||||
checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3"
|
||||
|
||||
[[package]]
|
||||
name = "url"
|
||||
version = "2.1.0"
|
||||
version = "2.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "75b414f6c464c879d7f9babf951f23bc3743fb7313c081b2e6ca719067ea9d61"
|
||||
checksum = "a507c383b2d33b5fc35d1861e77e6b383d158b2da5e14fe51b83dfedf6fd578c"
|
||||
dependencies = [
|
||||
"form_urlencoded",
|
||||
"idna",
|
||||
"matches",
|
||||
"percent-encoding",
|
||||
@ -159,7 +169,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "webrtc-sdp"
|
||||
version = "0.3.8"
|
||||
version = "0.3.9"
|
||||
dependencies = [
|
||||
"log",
|
||||
"serde",
|
||||
|
17
third_party/rust/webrtc-sdp/Cargo.toml
vendored
17
third_party/rust/webrtc-sdp/Cargo.toml
vendored
@ -3,25 +3,24 @@
|
||||
# When uploading crates to the registry Cargo will automatically
|
||||
# "normalize" Cargo.toml files for maximal compatibility
|
||||
# with all versions of Cargo and also rewrite `path` dependencies
|
||||
# to registry (e.g., crates.io) dependencies
|
||||
# to registry (e.g., crates.io) dependencies.
|
||||
#
|
||||
# If you believe there's an error in this file please file an
|
||||
# issue against the rust-lang/cargo repository. If you're
|
||||
# editing this file be aware that the upstream Cargo.toml
|
||||
# will likely look very different (and much more reasonable)
|
||||
# If you are reading this file be aware that the original Cargo.toml
|
||||
# will likely look very different (and much more reasonable).
|
||||
# See Cargo.toml.orig for the original contents.
|
||||
|
||||
[package]
|
||||
name = "webrtc-sdp"
|
||||
version = "0.3.8"
|
||||
authors = ["Nils Ohlmeier <github@ohlmeier.org>"]
|
||||
description = "This create parses strings in the format of the Session Description Protocol according to RFC4566. It specifically supports the subset of features required to support WebRTC according to the JSEP draft."
|
||||
version = "0.3.9"
|
||||
authors = ["Nicolas Grunbaum <na-g+github@nostrum.com>", "Nils Ohlmeier <github@ohlmeier.org>"]
|
||||
description = "webrtc-sdp parses strings in the format of the Session Description Protocol according to RFC4566. It specifically supports the subset of features required to support WebRTC according to the JSEP draft."
|
||||
readme = "README.md"
|
||||
keywords = ["webrtc", "sdp", "jsep"]
|
||||
categories = ["parsing", "network-programming"]
|
||||
license = "MPL-2.0"
|
||||
repository = "https://github.com/mozilla/webrtc-sdp"
|
||||
[dependencies.log]
|
||||
version = "0.4.6"
|
||||
version = "0.4"
|
||||
|
||||
[dependencies.serde]
|
||||
version = "1.0"
|
||||
|
73
third_party/rust/webrtc-sdp/src/address.rs
vendored
73
third_party/rust/webrtc-sdp/src/address.rs
vendored
@ -195,74 +195,5 @@ impl PartialEq for ExplicitlyTypedAddress {
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use self::url::ParseError;
|
||||
use super::*;
|
||||
use std::error::Error;
|
||||
use std::net::{AddrParseError, Ipv4Addr, Ipv6Addr};
|
||||
|
||||
#[derive(Debug)]
|
||||
enum ParseTestError {
|
||||
Host(ParseError),
|
||||
Ip(AddrParseError),
|
||||
}
|
||||
impl fmt::Display for ParseTestError {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self {
|
||||
ParseTestError::Host(inner) => inner.fmt(f),
|
||||
ParseTestError::Ip(inner) => inner.fmt(f),
|
||||
}
|
||||
}
|
||||
}
|
||||
impl From<ParseError> for ParseTestError {
|
||||
fn from(err: ParseError) -> Self {
|
||||
ParseTestError::Host(err)
|
||||
}
|
||||
}
|
||||
impl From<AddrParseError> for ParseTestError {
|
||||
fn from(err: AddrParseError) -> Self {
|
||||
ParseTestError::Ip(err)
|
||||
}
|
||||
}
|
||||
impl Error for ParseTestError {
|
||||
fn source(&self) -> Option<&(dyn Error + 'static)> {
|
||||
// Generic error, underlying cause isn't tracked.
|
||||
match self {
|
||||
ParseTestError::Host(a) => Some(a),
|
||||
ParseTestError::Ip(a) => Some(a),
|
||||
}
|
||||
}
|
||||
}
|
||||
#[test]
|
||||
fn test_domain_name_parsing() -> Result<(), ParseTestError> {
|
||||
let address = Host::parse("this.is.a.fqdn")?;
|
||||
if let Host::Domain(domain) = address {
|
||||
assert_eq!(domain, "this.is.a.fqdn");
|
||||
} else {
|
||||
panic!();
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_ipv4_address_parsing() -> Result<(), ParseTestError> {
|
||||
let address = Host::parse("1.0.0.1")?;
|
||||
if let Host::Ipv4(ip) = address {
|
||||
assert_eq!(ip, "1.0.0.1".parse::<Ipv4Addr>()?);
|
||||
} else {
|
||||
panic!();
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_ipv6_address_parsing() -> Result<(), ParseTestError> {
|
||||
let address = Host::parse("[::1]")?;
|
||||
if let Host::Ipv6(ip) = address {
|
||||
assert_eq!(ip, "::1".parse::<Ipv6Addr>()?);
|
||||
} else {
|
||||
panic!();
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
#[path = "./address_tests.rs"]
|
||||
mod address_tests;
|
||||
|
73
third_party/rust/webrtc-sdp/src/address_tests.rs
vendored
Normal file
73
third_party/rust/webrtc-sdp/src/address_tests.rs
vendored
Normal file
@ -0,0 +1,73 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
use self::url::ParseError;
|
||||
use super::*;
|
||||
use std::error::Error;
|
||||
use std::net::{AddrParseError, Ipv4Addr, Ipv6Addr};
|
||||
|
||||
#[derive(Debug)]
|
||||
enum ParseTestError {
|
||||
Host(ParseError),
|
||||
Ip(AddrParseError),
|
||||
}
|
||||
impl fmt::Display for ParseTestError {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self {
|
||||
ParseTestError::Host(inner) => inner.fmt(f),
|
||||
ParseTestError::Ip(inner) => inner.fmt(f),
|
||||
}
|
||||
}
|
||||
}
|
||||
impl From<ParseError> for ParseTestError {
|
||||
fn from(err: ParseError) -> Self {
|
||||
ParseTestError::Host(err)
|
||||
}
|
||||
}
|
||||
impl From<AddrParseError> for ParseTestError {
|
||||
fn from(err: AddrParseError) -> Self {
|
||||
ParseTestError::Ip(err)
|
||||
}
|
||||
}
|
||||
impl Error for ParseTestError {
|
||||
fn source(&self) -> Option<&(dyn Error + 'static)> {
|
||||
// Generic error, underlying cause isn't tracked.
|
||||
match self {
|
||||
ParseTestError::Host(a) => Some(a),
|
||||
ParseTestError::Ip(a) => Some(a),
|
||||
}
|
||||
}
|
||||
}
|
||||
#[test]
|
||||
fn test_domain_name_parsing() -> Result<(), ParseTestError> {
|
||||
let address = Host::parse("this.is.a.fqdn")?;
|
||||
if let Host::Domain(domain) = address {
|
||||
assert_eq!(domain, "this.is.a.fqdn");
|
||||
} else {
|
||||
panic!();
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_ipv4_address_parsing() -> Result<(), ParseTestError> {
|
||||
let address = Host::parse("1.0.0.1")?;
|
||||
if let Host::Ipv4(ip) = address {
|
||||
assert_eq!(ip, "1.0.0.1".parse::<Ipv4Addr>()?);
|
||||
} else {
|
||||
panic!();
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_ipv6_address_parsing() -> Result<(), ParseTestError> {
|
||||
let address = Host::parse("[::1]")?;
|
||||
if let Host::Ipv6(ip) = address {
|
||||
assert_eq!(ip, "::1".parse::<Ipv6Addr>()?);
|
||||
} else {
|
||||
panic!();
|
||||
}
|
||||
Ok(())
|
||||
}
|
121
third_party/rust/webrtc-sdp/src/anonymizer.rs
vendored
121
third_party/rust/webrtc-sdp/src/anonymizer.rs
vendored
@ -194,122 +194,5 @@ impl AnonymizationStrMap {
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_mask_ip() {
|
||||
let mut anon = StatefulSdpAnonymizer::default();
|
||||
let v4 = [
|
||||
Ipv4Addr::new(127, 0, 0, 1),
|
||||
Ipv4Addr::new(10, 0, 0, 1),
|
||||
Ipv4Addr::new(1, 1, 1, 1),
|
||||
];
|
||||
let v4_masked = [
|
||||
Ipv4Addr::new(0, 0, 0, 1),
|
||||
Ipv4Addr::new(0, 0, 0, 2),
|
||||
Ipv4Addr::new(0, 0, 0, 3),
|
||||
];
|
||||
let v6 = [
|
||||
Ipv6Addr::from(0),
|
||||
Ipv6Addr::from(528_189_235),
|
||||
Ipv6Addr::from(1_623_734_988_148_990),
|
||||
];
|
||||
let v6_masked = [Ipv6Addr::from(1), Ipv6Addr::from(2), Ipv6Addr::from(3)];
|
||||
for _ in 0..2 {
|
||||
assert_eq!(anon.mask_ip(&IpAddr::V4(v4[0])), v4_masked[0]);
|
||||
assert_eq!(anon.mask_ip(&IpAddr::V6(v6[0])), v6_masked[0]);
|
||||
|
||||
assert_eq!(anon.mask_ip(&IpAddr::V4(v4[1])), v4_masked[1]);
|
||||
assert_eq!(anon.mask_ip(&IpAddr::V6(v6[1])), v6_masked[1]);
|
||||
|
||||
assert_eq!(anon.mask_ip(&IpAddr::V4(v4[2])), v4_masked[2]);
|
||||
assert_eq!(anon.mask_ip(&IpAddr::V6(v6[2])), v6_masked[2]);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_mask_port() {
|
||||
let mut anon = StatefulSdpAnonymizer::default();
|
||||
let ports = [0, 125, 12346];
|
||||
let masked_ports = [1, 2, 3];
|
||||
for _ in 0..2 {
|
||||
assert_eq!(anon.mask_port(ports[0]), masked_ports[0]);
|
||||
assert_eq!(anon.mask_port(ports[1]), masked_ports[1]);
|
||||
assert_eq!(anon.mask_port(ports[2]), masked_ports[2]);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_mask_ice_password() {
|
||||
let mut anon = StatefulSdpAnonymizer::default();
|
||||
let passwords = ["vasdfioqwenl14082`14", "0", "ncp HY878hp(poh"];
|
||||
let masked_passwords = [
|
||||
"ice-password-00000001",
|
||||
"ice-password-00000002",
|
||||
"ice-password-00000003",
|
||||
];
|
||||
for _ in 0..2 {
|
||||
assert_eq!(anon.mask_ice_password(passwords[0]), masked_passwords[0]);
|
||||
assert_eq!(anon.mask_ice_password(passwords[1]), masked_passwords[1]);
|
||||
assert_eq!(anon.mask_ice_password(passwords[2]), masked_passwords[2]);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_mask_ice_user() {
|
||||
let mut anon = StatefulSdpAnonymizer::default();
|
||||
let users = ["user1", "user2", "8109q2asdf"];
|
||||
let masked_users = [
|
||||
"ice-user-00000001",
|
||||
"ice-user-00000002",
|
||||
"ice-user-00000003",
|
||||
];
|
||||
for _ in 0..2 {
|
||||
assert_eq!(anon.mask_ice_user(users[0]), masked_users[0]);
|
||||
assert_eq!(anon.mask_ice_user(users[1]), masked_users[1]);
|
||||
assert_eq!(anon.mask_ice_user(users[2]), masked_users[2]);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_mask_cert_fingerprint() {
|
||||
let mut anon = StatefulSdpAnonymizer::default();
|
||||
let prints: [Vec<u8>; 3] = [
|
||||
vec![
|
||||
0x59u8, 0x4A, 0x8B, 0x73, 0xA7, 0x73, 0x53, 0x71, 0x88, 0xD7, 0x4D, 0x58, 0x28,
|
||||
0x0C, 0x79, 0x72, 0x31, 0x29, 0x9B, 0x05, 0x37, 0xDD, 0x58, 0x43, 0xC2, 0xD4, 0x85,
|
||||
0xA2, 0xB3, 0x66, 0x38, 0x7A,
|
||||
],
|
||||
vec![
|
||||
0x30u8, 0xFF, 0x8E, 0x2B, 0xAC, 0x9D, 0xED, 0x70, 0x18, 0x10, 0x67, 0xC8, 0xAE,
|
||||
0x9E, 0x68, 0xF3, 0x86, 0x53, 0x51, 0xB0, 0xAC, 0x31, 0xB7, 0xBE, 0x6D, 0xCF, 0xA4,
|
||||
0x2E, 0xD3, 0x6E, 0xB4, 0x28,
|
||||
],
|
||||
vec![
|
||||
0xDFu8, 0x2E, 0xAC, 0x8A, 0xFD, 0x0A, 0x8E, 0x99, 0xBF, 0x5D, 0xE8, 0x3C, 0xE7,
|
||||
0xFA, 0xFB, 0x08, 0x3B, 0x3C, 0x54, 0x1D, 0xD7, 0xD4, 0x05, 0x77, 0xA0, 0x72, 0x9B,
|
||||
0x14, 0x08, 0x6D, 0x0F, 0x4C,
|
||||
],
|
||||
];
|
||||
|
||||
let masked_prints = [1u64.to_byte_vec(), 2u64.to_byte_vec(), 3u64.to_byte_vec()];
|
||||
for _ in 0..2 {
|
||||
assert_eq!(anon.mask_cert_finger_print(&prints[0]), masked_prints[0]);
|
||||
assert_eq!(anon.mask_cert_finger_print(&prints[1]), masked_prints[1]);
|
||||
assert_eq!(anon.mask_cert_finger_print(&prints[2]), masked_prints[2]);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_mask_cname() {
|
||||
let mut anon = StatefulSdpAnonymizer::default();
|
||||
let cnames = ["mailto:foo@bar", "JohnDoe", "Jane Doe"];
|
||||
let masked_cnames = ["cname-00000001", "cname-00000002", "cname-00000003"];
|
||||
for _ in 0..2 {
|
||||
assert_eq!(anon.mask_cname(cnames[0]), masked_cnames[0]);
|
||||
assert_eq!(anon.mask_cname(cnames[1]), masked_cnames[1]);
|
||||
assert_eq!(anon.mask_cname(cnames[2]), masked_cnames[2]);
|
||||
}
|
||||
}
|
||||
}
|
||||
#[path = "./anonymizer_tests.rs"]
|
||||
mod tests;
|
||||
|
121
third_party/rust/webrtc-sdp/src/anonymizer_tests.rs
vendored
Normal file
121
third_party/rust/webrtc-sdp/src/anonymizer_tests.rs
vendored
Normal file
@ -0,0 +1,121 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_mask_ip() {
|
||||
let mut anon = StatefulSdpAnonymizer::default();
|
||||
let v4 = [
|
||||
Ipv4Addr::new(127, 0, 0, 1),
|
||||
Ipv4Addr::new(10, 0, 0, 1),
|
||||
Ipv4Addr::new(1, 1, 1, 1),
|
||||
];
|
||||
let v4_masked = [
|
||||
Ipv4Addr::new(0, 0, 0, 1),
|
||||
Ipv4Addr::new(0, 0, 0, 2),
|
||||
Ipv4Addr::new(0, 0, 0, 3),
|
||||
];
|
||||
let v6 = [
|
||||
Ipv6Addr::from(0),
|
||||
Ipv6Addr::from(528_189_235),
|
||||
Ipv6Addr::from(1_623_734_988_148_990),
|
||||
];
|
||||
let v6_masked = [Ipv6Addr::from(1), Ipv6Addr::from(2), Ipv6Addr::from(3)];
|
||||
for _ in 0..2 {
|
||||
assert_eq!(anon.mask_ip(&IpAddr::V4(v4[0])), v4_masked[0]);
|
||||
assert_eq!(anon.mask_ip(&IpAddr::V6(v6[0])), v6_masked[0]);
|
||||
|
||||
assert_eq!(anon.mask_ip(&IpAddr::V4(v4[1])), v4_masked[1]);
|
||||
assert_eq!(anon.mask_ip(&IpAddr::V6(v6[1])), v6_masked[1]);
|
||||
|
||||
assert_eq!(anon.mask_ip(&IpAddr::V4(v4[2])), v4_masked[2]);
|
||||
assert_eq!(anon.mask_ip(&IpAddr::V6(v6[2])), v6_masked[2]);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_mask_port() {
|
||||
let mut anon = StatefulSdpAnonymizer::default();
|
||||
let ports = [0, 125, 12346];
|
||||
let masked_ports = [1, 2, 3];
|
||||
for _ in 0..2 {
|
||||
assert_eq!(anon.mask_port(ports[0]), masked_ports[0]);
|
||||
assert_eq!(anon.mask_port(ports[1]), masked_ports[1]);
|
||||
assert_eq!(anon.mask_port(ports[2]), masked_ports[2]);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_mask_ice_password() {
|
||||
let mut anon = StatefulSdpAnonymizer::default();
|
||||
let passwords = ["vasdfioqwenl14082`14", "0", "ncp HY878hp(poh"];
|
||||
let masked_passwords = [
|
||||
"ice-password-00000001",
|
||||
"ice-password-00000002",
|
||||
"ice-password-00000003",
|
||||
];
|
||||
for _ in 0..2 {
|
||||
assert_eq!(anon.mask_ice_password(passwords[0]), masked_passwords[0]);
|
||||
assert_eq!(anon.mask_ice_password(passwords[1]), masked_passwords[1]);
|
||||
assert_eq!(anon.mask_ice_password(passwords[2]), masked_passwords[2]);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_mask_ice_user() {
|
||||
let mut anon = StatefulSdpAnonymizer::default();
|
||||
let users = ["user1", "user2", "8109q2asdf"];
|
||||
let masked_users = [
|
||||
"ice-user-00000001",
|
||||
"ice-user-00000002",
|
||||
"ice-user-00000003",
|
||||
];
|
||||
for _ in 0..2 {
|
||||
assert_eq!(anon.mask_ice_user(users[0]), masked_users[0]);
|
||||
assert_eq!(anon.mask_ice_user(users[1]), masked_users[1]);
|
||||
assert_eq!(anon.mask_ice_user(users[2]), masked_users[2]);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_mask_cert_fingerprint() {
|
||||
let mut anon = StatefulSdpAnonymizer::default();
|
||||
let prints: [Vec<u8>; 3] = [
|
||||
vec![
|
||||
0x59u8, 0x4A, 0x8B, 0x73, 0xA7, 0x73, 0x53, 0x71, 0x88, 0xD7, 0x4D, 0x58, 0x28, 0x0C,
|
||||
0x79, 0x72, 0x31, 0x29, 0x9B, 0x05, 0x37, 0xDD, 0x58, 0x43, 0xC2, 0xD4, 0x85, 0xA2,
|
||||
0xB3, 0x66, 0x38, 0x7A,
|
||||
],
|
||||
vec![
|
||||
0x30u8, 0xFF, 0x8E, 0x2B, 0xAC, 0x9D, 0xED, 0x70, 0x18, 0x10, 0x67, 0xC8, 0xAE, 0x9E,
|
||||
0x68, 0xF3, 0x86, 0x53, 0x51, 0xB0, 0xAC, 0x31, 0xB7, 0xBE, 0x6D, 0xCF, 0xA4, 0x2E,
|
||||
0xD3, 0x6E, 0xB4, 0x28,
|
||||
],
|
||||
vec![
|
||||
0xDFu8, 0x2E, 0xAC, 0x8A, 0xFD, 0x0A, 0x8E, 0x99, 0xBF, 0x5D, 0xE8, 0x3C, 0xE7, 0xFA,
|
||||
0xFB, 0x08, 0x3B, 0x3C, 0x54, 0x1D, 0xD7, 0xD4, 0x05, 0x77, 0xA0, 0x72, 0x9B, 0x14,
|
||||
0x08, 0x6D, 0x0F, 0x4C,
|
||||
],
|
||||
];
|
||||
|
||||
let masked_prints = [1u64.to_byte_vec(), 2u64.to_byte_vec(), 3u64.to_byte_vec()];
|
||||
for _ in 0..2 {
|
||||
assert_eq!(anon.mask_cert_finger_print(&prints[0]), masked_prints[0]);
|
||||
assert_eq!(anon.mask_cert_finger_print(&prints[1]), masked_prints[1]);
|
||||
assert_eq!(anon.mask_cert_finger_print(&prints[2]), masked_prints[2]);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_mask_cname() {
|
||||
let mut anon = StatefulSdpAnonymizer::default();
|
||||
let cnames = ["mailto:foo@bar", "JohnDoe", "Jane Doe"];
|
||||
let masked_cnames = ["cname-00000001", "cname-00000002", "cname-00000003"];
|
||||
for _ in 0..2 {
|
||||
assert_eq!(anon.mask_cname(cnames[0]), masked_cnames[0]);
|
||||
assert_eq!(anon.mask_cname(cnames[1]), masked_cnames[1]);
|
||||
assert_eq!(anon.mask_cname(cnames[2]), masked_cnames[2]);
|
||||
}
|
||||
}
|
1210
third_party/rust/webrtc-sdp/src/attribute_type.rs
vendored
1210
third_party/rust/webrtc-sdp/src/attribute_type.rs
vendored
File diff suppressed because it is too large
Load Diff
1102
third_party/rust/webrtc-sdp/src/attribute_type_tests.rs
vendored
Normal file
1102
third_party/rust/webrtc-sdp/src/attribute_type_tests.rs
vendored
Normal file
File diff suppressed because it is too large
Load Diff
129
third_party/rust/webrtc-sdp/src/error.rs
vendored
129
third_party/rust/webrtc-sdp/src/error.rs
vendored
@ -207,130 +207,5 @@ impl From<ParseFloatError> for SdpParserInternalError {
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use address::Address;
|
||||
use std::str::FromStr;
|
||||
#[test]
|
||||
fn test_sdp_parser_internal_error_unknown_address_type() {
|
||||
let error = SdpParserInternalError::UnknownAddressType("foo".to_string());
|
||||
assert_eq!(
|
||||
format!("{}", error),
|
||||
format!("{}: {}", INTERNAL_ERROR_MESSAGE_UNKNOWN_ADDRESS_TYPE, "foo")
|
||||
);
|
||||
assert!(error.source().is_none());
|
||||
}
|
||||
#[test]
|
||||
fn test_sdp_parser_internal_error_address_type_mismatch() {
|
||||
let error = SdpParserInternalError::AddressTypeMismatch {
|
||||
found: AddressType::IpV4,
|
||||
expected: AddressType::IpV6,
|
||||
};
|
||||
assert_eq!(
|
||||
format!("{}", error),
|
||||
format!(
|
||||
"{}: {}, {}",
|
||||
INTERNAL_ERROR_MESSAGE_ADDRESS_TYPE_MISMATCH,
|
||||
AddressType::IpV4,
|
||||
AddressType::IpV6
|
||||
)
|
||||
);
|
||||
assert!(error.source().is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_sdp_parser_internal_error_generic() {
|
||||
let generic = SdpParserInternalError::Generic("generic message".to_string());
|
||||
assert_eq!(format!("{}", generic), "Parsing error: generic message");
|
||||
assert!(generic.source().is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_sdp_parser_internal_error_unsupported() {
|
||||
let unsupported =
|
||||
SdpParserInternalError::Unsupported("unsupported internal message".to_string());
|
||||
assert_eq!(
|
||||
format!("{}", unsupported),
|
||||
"Unsupported parsing error: unsupported internal message"
|
||||
);
|
||||
assert!(unsupported.source().is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_sdp_parser_internal_error_integer() {
|
||||
let v = "12a";
|
||||
let integer = v.parse::<u64>();
|
||||
assert!(integer.is_err());
|
||||
let int_err = SdpParserInternalError::Integer(integer.err().unwrap());
|
||||
assert_eq!(
|
||||
format!("{}", int_err),
|
||||
"Integer parsing error: invalid digit found in string"
|
||||
);
|
||||
assert!(!int_err.source().is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_sdp_parser_internal_error_float() {
|
||||
let v = "12.2a";
|
||||
let float = v.parse::<f32>();
|
||||
assert!(float.is_err());
|
||||
let int_err = SdpParserInternalError::Float(float.err().unwrap());
|
||||
assert_eq!(
|
||||
format!("{}", int_err),
|
||||
"Float parsing error: invalid float literal"
|
||||
);
|
||||
assert!(!int_err.source().is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_sdp_parser_internal_error_address() {
|
||||
let v = "127.0.0.500";
|
||||
let addr_err = Address::from_str(v).err().unwrap();
|
||||
assert_eq!(
|
||||
format!("{}", addr_err),
|
||||
"Domain name parsing error: invalid IPv4 address"
|
||||
);
|
||||
assert!(!addr_err.source().is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_sdp_parser_error_line() {
|
||||
let line1 = SdpParserError::Line {
|
||||
error: SdpParserInternalError::Generic("test message".to_string()),
|
||||
line: "test line".to_string(),
|
||||
line_number: 13,
|
||||
};
|
||||
assert_eq!(
|
||||
format!("{}", line1),
|
||||
"Line error: Parsing error: test message in line(13): test line"
|
||||
);
|
||||
assert!(line1.source().is_some());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_sdp_parser_error_unsupported() {
|
||||
let unsupported1 = SdpParserError::Unsupported {
|
||||
error: SdpParserInternalError::Generic("unsupported value".to_string()),
|
||||
line: "unsupported line".to_string(),
|
||||
line_number: 21,
|
||||
};
|
||||
assert_eq!(
|
||||
format!("{}", unsupported1),
|
||||
"Unsupported: Parsing error: unsupported value in line(21): unsupported line"
|
||||
);
|
||||
assert!(unsupported1.source().is_some());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_sdp_parser_error_sequence() {
|
||||
let sequence1 = SdpParserError::Sequence {
|
||||
message: "sequence message".to_string(),
|
||||
line_number: 42,
|
||||
};
|
||||
assert_eq!(
|
||||
format!("{}", sequence1),
|
||||
"Sequence error in line(42): sequence message"
|
||||
);
|
||||
assert!(sequence1.source().is_none());
|
||||
}
|
||||
}
|
||||
#[path = "./error_tests.rs"]
|
||||
mod tests;
|
||||
|
129
third_party/rust/webrtc-sdp/src/error_tests.rs
vendored
Normal file
129
third_party/rust/webrtc-sdp/src/error_tests.rs
vendored
Normal file
@ -0,0 +1,129 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
use super::*;
|
||||
use address::Address;
|
||||
use std::str::FromStr;
|
||||
#[test]
|
||||
fn test_sdp_parser_internal_error_unknown_address_type() {
|
||||
let error = SdpParserInternalError::UnknownAddressType("foo".to_string());
|
||||
assert_eq!(
|
||||
format!("{}", error),
|
||||
format!("{}: {}", INTERNAL_ERROR_MESSAGE_UNKNOWN_ADDRESS_TYPE, "foo")
|
||||
);
|
||||
assert!(error.source().is_none());
|
||||
}
|
||||
#[test]
|
||||
fn test_sdp_parser_internal_error_address_type_mismatch() {
|
||||
let error = SdpParserInternalError::AddressTypeMismatch {
|
||||
found: AddressType::IpV4,
|
||||
expected: AddressType::IpV6,
|
||||
};
|
||||
assert_eq!(
|
||||
format!("{}", error),
|
||||
format!(
|
||||
"{}: {}, {}",
|
||||
INTERNAL_ERROR_MESSAGE_ADDRESS_TYPE_MISMATCH,
|
||||
AddressType::IpV4,
|
||||
AddressType::IpV6
|
||||
)
|
||||
);
|
||||
assert!(error.source().is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_sdp_parser_internal_error_generic() {
|
||||
let generic = SdpParserInternalError::Generic("generic message".to_string());
|
||||
assert_eq!(format!("{}", generic), "Parsing error: generic message");
|
||||
assert!(generic.source().is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_sdp_parser_internal_error_unsupported() {
|
||||
let unsupported =
|
||||
SdpParserInternalError::Unsupported("unsupported internal message".to_string());
|
||||
assert_eq!(
|
||||
format!("{}", unsupported),
|
||||
"Unsupported parsing error: unsupported internal message"
|
||||
);
|
||||
assert!(unsupported.source().is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_sdp_parser_internal_error_integer() {
|
||||
let v = "12a";
|
||||
let integer = v.parse::<u64>();
|
||||
assert!(integer.is_err());
|
||||
let int_err = SdpParserInternalError::Integer(integer.err().unwrap());
|
||||
assert_eq!(
|
||||
format!("{}", int_err),
|
||||
"Integer parsing error: invalid digit found in string"
|
||||
);
|
||||
assert!(!int_err.source().is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_sdp_parser_internal_error_float() {
|
||||
let v = "12.2a";
|
||||
let float = v.parse::<f32>();
|
||||
assert!(float.is_err());
|
||||
let int_err = SdpParserInternalError::Float(float.err().unwrap());
|
||||
assert_eq!(
|
||||
format!("{}", int_err),
|
||||
"Float parsing error: invalid float literal"
|
||||
);
|
||||
assert!(!int_err.source().is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_sdp_parser_internal_error_address() {
|
||||
let v = "127.0.0.500";
|
||||
let addr_err = Address::from_str(v).err().unwrap();
|
||||
assert_eq!(
|
||||
format!("{}", addr_err),
|
||||
"Domain name parsing error: invalid IPv4 address"
|
||||
);
|
||||
assert!(!addr_err.source().is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_sdp_parser_error_line() {
|
||||
let line1 = SdpParserError::Line {
|
||||
error: SdpParserInternalError::Generic("test message".to_string()),
|
||||
line: "test line".to_string(),
|
||||
line_number: 13,
|
||||
};
|
||||
assert_eq!(
|
||||
format!("{}", line1),
|
||||
"Line error: Parsing error: test message in line(13): test line"
|
||||
);
|
||||
assert!(line1.source().is_some());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_sdp_parser_error_unsupported() {
|
||||
let unsupported1 = SdpParserError::Unsupported {
|
||||
error: SdpParserInternalError::Generic("unsupported value".to_string()),
|
||||
line: "unsupported line".to_string(),
|
||||
line_number: 21,
|
||||
};
|
||||
assert_eq!(
|
||||
format!("{}", unsupported1),
|
||||
"Unsupported: Parsing error: unsupported value in line(21): unsupported line"
|
||||
);
|
||||
assert!(unsupported1.source().is_some());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_sdp_parser_error_sequence() {
|
||||
let sequence1 = SdpParserError::Sequence {
|
||||
message: "sequence message".to_string(),
|
||||
line_number: 42,
|
||||
};
|
||||
assert_eq!(
|
||||
format!("{}", sequence1),
|
||||
"Sequence error in line(42): sequence message"
|
||||
);
|
||||
assert!(sequence1.source().is_none());
|
||||
}
|
776
third_party/rust/webrtc-sdp/src/lib.rs
vendored
776
third_party/rust/webrtc-sdp/src/lib.rs
vendored
@ -230,7 +230,7 @@ impl fmt::Display for SdpSession {
|
||||
bandwidth = maybe_vector_to_string!("b={}\r\n", self.bandwidth, "\r\nb="),
|
||||
connection = option_to_string!("c={}\r\n", self.connection),
|
||||
session_attributes = maybe_vector_to_string!("a={}\r\n", self.attribute, "\r\na="),
|
||||
media_sections = maybe_vector_to_string!("{}", self.media, "\r\n")
|
||||
media_sections = self.media.iter().map(|s| s.to_string()).collect::<String>(),
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -396,6 +396,9 @@ impl AnonymizingClone for SdpSession {
|
||||
}
|
||||
}
|
||||
|
||||
/* removing this wrap would not allow us to call this from the match statement inside
|
||||
* parse_sdp_line() */
|
||||
#[allow(clippy::unnecessary_wraps)]
|
||||
fn parse_session(value: &str) -> Result<SdpType, SdpParserInternalError> {
|
||||
trace!("session: {}", value);
|
||||
Ok(SdpType::Session(String::from(value)))
|
||||
@ -717,6 +720,16 @@ fn sanity_check_sdp_session(session: &SdpSession) -> Result<(), SdpParserError>
|
||||
}
|
||||
}
|
||||
|
||||
if msection
|
||||
.get_attribute(SdpAttributeType::RtcpMuxOnly)
|
||||
.is_some()
|
||||
&& msection.get_attribute(SdpAttributeType::RtcpMux).is_none()
|
||||
{
|
||||
return Err(make_seq_error(
|
||||
"rtcp-mux-only media sections must also contain the rtcp-mux attribute",
|
||||
));
|
||||
}
|
||||
|
||||
let rids: Vec<&SdpAttributeRid> = msection
|
||||
.get_attributes()
|
||||
.iter()
|
||||
@ -823,7 +836,7 @@ fn parse_sdp_vector(lines: &mut Vec<SdpLine>) -> Result<SdpSession, SdpParserErr
|
||||
|
||||
let _media_pos = lines
|
||||
.iter()
|
||||
.position(|ref l| matches!(l.sdp_type, SdpType::Media(_)));
|
||||
.position(|l| matches!(l.sdp_type, SdpType::Media(_)));
|
||||
|
||||
match _media_pos {
|
||||
Some(p) => {
|
||||
@ -922,760 +935,5 @@ pub fn parse_sdp(sdp: &str, fail_on_warning: bool) -> Result<SdpSession, SdpPars
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
extern crate url;
|
||||
use super::*;
|
||||
use address::{Address, AddressType};
|
||||
use anonymizer::ToBytesVec;
|
||||
use media_type::create_dummy_media_section;
|
||||
use std::net::IpAddr;
|
||||
use std::net::Ipv4Addr;
|
||||
|
||||
fn create_dummy_sdp_session() -> SdpSession {
|
||||
let origin = parse_origin("mozilla 506705521068071134 0 IN IP4 0.0.0.0");
|
||||
assert!(origin.is_ok());
|
||||
let connection = parse_connection("IN IP4 198.51.100.7");
|
||||
assert!(connection.is_ok());
|
||||
let mut sdp_session;
|
||||
if let SdpType::Origin(o) = origin.unwrap() {
|
||||
sdp_session = SdpSession::new(0, o, "-".to_string());
|
||||
|
||||
if let Ok(SdpType::Connection(c)) = connection {
|
||||
sdp_session.connection = Some(c);
|
||||
} else {
|
||||
unreachable!();
|
||||
}
|
||||
} else {
|
||||
unreachable!();
|
||||
}
|
||||
sdp_session
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_session_works() -> Result<(), SdpParserInternalError> {
|
||||
parse_session("topic")?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_version_works() -> Result<(), SdpParserInternalError> {
|
||||
parse_version("0")?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_version_unsupported_input() {
|
||||
assert!(parse_version("1").is_err());
|
||||
assert!(parse_version("11").is_err());
|
||||
assert!(parse_version("a").is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_origin_works() -> Result<(), SdpParserInternalError> {
|
||||
parse_origin("mozilla 506705521068071134 0 IN IP4 0.0.0.0")?;
|
||||
parse_origin("mozilla 506705521068071134 0 IN IP6 2001:db8::1")?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_origin_missing_username() {
|
||||
assert!(parse_origin("").is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_origin_missing_session_id() {
|
||||
assert!(parse_origin("mozilla ").is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_origin_missing_session_version() {
|
||||
assert!(parse_origin("mozilla 506705521068071134 ").is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_origin_missing_nettype() {
|
||||
assert!(parse_origin("mozilla 506705521068071134 0 ").is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_origin_unsupported_nettype() {
|
||||
assert!(parse_origin("mozilla 506705521068071134 0 UNSUPPORTED IP4 0.0.0.0").is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_origin_missing_addtype() {
|
||||
assert!(parse_origin("mozilla 506705521068071134 0 IN ").is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_origin_missing_ip_addr() {
|
||||
assert!(parse_origin("mozilla 506705521068071134 0 IN IP4 ").is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_origin_unsupported_addrtpe() {
|
||||
assert!(parse_origin("mozilla 506705521068071134 0 IN IP1 0.0.0.0").is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_origin_invalid_ip_addr() {
|
||||
assert!(parse_origin("mozilla 506705521068071134 0 IN IP4 1.1.1.256").is_err());
|
||||
assert!(parse_origin("mozilla 506705521068071134 0 IN IP6 ::g").is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_origin_addr_type_mismatch() {
|
||||
assert!(parse_origin("mozilla 506705521068071134 0 IN IP4 ::1").is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn connection_works() -> Result<(), SdpParserInternalError> {
|
||||
parse_connection("IN IP4 127.0.0.1")?;
|
||||
parse_connection("IN IP4 127.0.0.1/10/10")?;
|
||||
parse_connection("IN IP6 ::1")?;
|
||||
parse_connection("IN IP6 ::1/1/1")?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn connection_lots_of_whitespace() -> Result<(), SdpParserInternalError> {
|
||||
parse_connection("IN IP4 127.0.0.1")?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn connection_wrong_amount_of_tokens() {
|
||||
assert!(parse_connection("IN IP4").is_err());
|
||||
assert!(parse_connection("IN IP4 0.0.0.0 foobar").is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn connection_unsupported_nettype() {
|
||||
assert!(parse_connection("UNSUPPORTED IP4 0.0.0.0").is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn connection_unsupported_addrtpe() {
|
||||
assert!(parse_connection("IN IP1 0.0.0.0").is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn connection_broken_ip_addr() {
|
||||
assert!(parse_connection("IN IP4 1.1.1.256").is_err());
|
||||
assert!(parse_connection("IN IP6 ::g").is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn connection_addr_type_mismatch() {
|
||||
assert!(parse_connection("IN IP4 ::1").is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn bandwidth_works() -> Result<(), SdpParserInternalError> {
|
||||
parse_bandwidth("AS:1")?;
|
||||
parse_bandwidth("CT:123")?;
|
||||
parse_bandwidth("TIAS:12345")?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn bandwidth_wrong_amount_of_tokens() {
|
||||
assert!(parse_bandwidth("TIAS").is_err());
|
||||
assert!(parse_bandwidth("TIAS:12345:xyz").is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn bandwidth_unsupported_type() -> Result<(), SdpParserInternalError> {
|
||||
parse_bandwidth("UNSUPPORTED:12345")?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_timing_works() -> Result<(), SdpParserInternalError> {
|
||||
parse_timing("0 0")?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_timing_non_numeric_tokens() {
|
||||
assert!(parse_timing("a 0").is_err());
|
||||
assert!(parse_timing("0 a").is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_timing_wrong_amount_of_tokens() {
|
||||
assert!(parse_timing("0").is_err());
|
||||
assert!(parse_timing("0 0 0").is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_sdp_line_works() -> Result<(), SdpParserError> {
|
||||
parse_sdp_line("v=0", 0)?;
|
||||
parse_sdp_line("s=somesession", 0)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_sdp_line_empty_line() {
|
||||
assert!(parse_sdp_line("", 0).is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_sdp_line_unsupported_types() {
|
||||
assert!(parse_sdp_line("e=foobar", 0).is_err());
|
||||
assert!(parse_sdp_line("i=foobar", 0).is_err());
|
||||
assert!(parse_sdp_line("k=foobar", 0).is_err());
|
||||
assert!(parse_sdp_line("p=foobar", 0).is_err());
|
||||
assert!(parse_sdp_line("r=foobar", 0).is_err());
|
||||
assert!(parse_sdp_line("u=foobar", 0).is_err());
|
||||
assert!(parse_sdp_line("z=foobar", 0).is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_sdp_line_unknown_key() {
|
||||
assert!(parse_sdp_line("y=foobar", 0).is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_sdp_line_too_long_type() {
|
||||
assert!(parse_sdp_line("ab=foobar", 0).is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_sdp_line_without_equal() {
|
||||
assert!(parse_sdp_line("abcd", 0).is_err());
|
||||
assert!(parse_sdp_line("ab cd", 0).is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_sdp_line_empty_value() {
|
||||
assert!(parse_sdp_line("v=", 0).is_err());
|
||||
assert!(parse_sdp_line("o=", 0).is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_sdp_line_empty_name() {
|
||||
assert!(parse_sdp_line("=abc", 0).is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_sdp_line_valid_a_line() -> Result<(), SdpParserError> {
|
||||
parse_sdp_line("a=rtpmap:8 PCMA/8000", 0)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_sdp_line_invalid_a_line() {
|
||||
assert!(parse_sdp_line("a=rtpmap:200 PCMA/8000", 0).is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_add_attribute() -> Result<(), SdpParserInternalError> {
|
||||
let mut sdp_session = create_dummy_sdp_session();
|
||||
|
||||
sdp_session.add_attribute(SdpAttribute::Sendrecv)?;
|
||||
assert!(sdp_session.add_attribute(SdpAttribute::BundleOnly).is_err());
|
||||
assert_eq!(sdp_session.attribute.len(), 1);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_sanity_check_sdp_session_timing() -> Result<(), SdpParserError> {
|
||||
let mut sdp_session = create_dummy_sdp_session();
|
||||
sdp_session.extend_media(vec![create_dummy_media_section()]);
|
||||
|
||||
assert!(sanity_check_sdp_session(&sdp_session).is_err());
|
||||
|
||||
let t = SdpTiming { start: 0, stop: 0 };
|
||||
sdp_session.set_timing(t);
|
||||
|
||||
sanity_check_sdp_session(&sdp_session)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_sanity_check_sdp_session_media() -> Result<(), SdpParserError> {
|
||||
let mut sdp_session = create_dummy_sdp_session();
|
||||
let t = SdpTiming { start: 0, stop: 0 };
|
||||
sdp_session.set_timing(t);
|
||||
|
||||
sanity_check_sdp_session(&sdp_session)?;
|
||||
|
||||
sdp_session.extend_media(vec![create_dummy_media_section()]);
|
||||
|
||||
sanity_check_sdp_session(&sdp_session)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_sanity_check_sdp_connection() -> Result<(), SdpParserInternalError> {
|
||||
let origin = parse_origin("mozilla 506705521068071134 0 IN IP4 0.0.0.0")?;
|
||||
let mut sdp_session;
|
||||
if let SdpType::Origin(o) = origin {
|
||||
sdp_session = SdpSession::new(0, o, "-".to_string());
|
||||
} else {
|
||||
unreachable!();
|
||||
}
|
||||
let t = SdpTiming { start: 0, stop: 0 };
|
||||
sdp_session.set_timing(t);
|
||||
|
||||
assert!(sanity_check_sdp_session(&sdp_session).is_ok());
|
||||
|
||||
// the dummy media section doesn't contain a connection
|
||||
sdp_session.extend_media(vec![create_dummy_media_section()]);
|
||||
|
||||
assert!(sanity_check_sdp_session(&sdp_session).is_err());
|
||||
|
||||
let connection = parse_connection("IN IP6 ::1")?;
|
||||
if let SdpType::Connection(c) = connection {
|
||||
sdp_session.connection = Some(c);
|
||||
} else {
|
||||
unreachable!();
|
||||
}
|
||||
|
||||
assert!(sanity_check_sdp_session(&sdp_session).is_ok());
|
||||
|
||||
let mut second_media = create_dummy_media_section();
|
||||
let mconnection = parse_connection("IN IP4 0.0.0.0")?;
|
||||
if let SdpType::Connection(c) = mconnection {
|
||||
second_media.set_connection(c);
|
||||
} else {
|
||||
unreachable!();
|
||||
}
|
||||
sdp_session.extend_media(vec![second_media]);
|
||||
assert!(sdp_session.media.len() == 2);
|
||||
|
||||
assert!(sanity_check_sdp_session(&sdp_session).is_ok());
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_sanity_check_sdp_session_extmap() -> Result<(), SdpParserInternalError> {
|
||||
let mut sdp_session = create_dummy_sdp_session();
|
||||
let t = SdpTiming { start: 0, stop: 0 };
|
||||
sdp_session.set_timing(t);
|
||||
sdp_session.extend_media(vec![create_dummy_media_section()]);
|
||||
|
||||
let attribute =
|
||||
parse_attribute("extmap:3 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time")?;
|
||||
if let SdpType::Attribute(a) = attribute {
|
||||
sdp_session.add_attribute(a)?;
|
||||
} else {
|
||||
unreachable!();
|
||||
}
|
||||
assert!(sdp_session
|
||||
.get_attribute(SdpAttributeType::Extmap)
|
||||
.is_some());
|
||||
|
||||
assert!(sanity_check_sdp_session(&sdp_session).is_ok());
|
||||
|
||||
let mut second_media = create_dummy_media_section();
|
||||
let mattribute =
|
||||
parse_attribute("extmap:1/sendonly urn:ietf:params:rtp-hdrext:ssrc-audio-level")?;
|
||||
if let SdpType::Attribute(ma) = mattribute {
|
||||
second_media.add_attribute(ma)?;
|
||||
} else {
|
||||
unreachable!();
|
||||
}
|
||||
assert!(second_media
|
||||
.get_attribute(SdpAttributeType::Extmap)
|
||||
.is_some());
|
||||
|
||||
sdp_session.extend_media(vec![second_media]);
|
||||
assert!(sdp_session.media.len() == 2);
|
||||
|
||||
assert!(sanity_check_sdp_session(&sdp_session).is_err());
|
||||
|
||||
sdp_session.attribute = Vec::new();
|
||||
|
||||
assert!(sanity_check_sdp_session(&sdp_session).is_ok());
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_sanity_check_sdp_session_simulcast() -> Result<(), SdpParserError> {
|
||||
let mut sdp_session = create_dummy_sdp_session();
|
||||
let t = SdpTiming { start: 0, stop: 0 };
|
||||
sdp_session.set_timing(t);
|
||||
sdp_session.extend_media(vec![create_dummy_media_section()]);
|
||||
|
||||
sanity_check_sdp_session(&sdp_session)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_sdp_zero_length_string_fails() {
|
||||
assert!(parse_sdp("", true).is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_sdp_to_short_string() {
|
||||
assert!(parse_sdp("fooooobarrrr", true).is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_sdp_minimal_sdp_successfully() -> Result<(), SdpParserError> {
|
||||
parse_sdp(
|
||||
"v=0\r\n
|
||||
o=- 0 0 IN IP6 ::1\r\n
|
||||
s=-\r\n
|
||||
c=IN IP6 ::1\r\n
|
||||
t=0 0\r\n",
|
||||
true,
|
||||
)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_sdp_too_short() {
|
||||
assert!(parse_sdp(
|
||||
"v=0\r\n
|
||||
o=- 0 0 IN IP4 0.0.0.0\r\n
|
||||
s=-\r\n",
|
||||
true
|
||||
)
|
||||
.is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_sdp_line_error() {
|
||||
assert!(parse_sdp(
|
||||
"v=0\r\n
|
||||
o=- 0 0 IN IP4 0.0.0.0\r\n
|
||||
s=-\r\n
|
||||
t=0 foobar\r\n
|
||||
m=audio 0 UDP/TLS/RTP/SAVPF 0\r\n",
|
||||
true
|
||||
)
|
||||
.is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_sdp_unsupported_error() {
|
||||
assert!(parse_sdp(
|
||||
"v=0\r\n
|
||||
o=- 0 0 IN IP4 0.0.0.0\r\n
|
||||
s=-\r\n
|
||||
t=0 0\r\n
|
||||
m=foobar 0 UDP/TLS/RTP/SAVPF 0\r\n",
|
||||
true
|
||||
)
|
||||
.is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_sdp_unsupported_warning() -> Result<(), SdpParserError> {
|
||||
parse_sdp(
|
||||
"v=0\r\n
|
||||
o=- 0 0 IN IP4 0.0.0.0\r\n
|
||||
s=-\r\n
|
||||
c=IN IP4 198.51.100.7\r\n
|
||||
t=0 0\r\n
|
||||
m=audio 0 UDP/TLS/RTP/SAVPF 0\r\n
|
||||
a=unsupported\r\n",
|
||||
false,
|
||||
)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_sdp_sequence_error() {
|
||||
assert!(parse_sdp(
|
||||
"v=0\r\n
|
||||
o=- 0 0 IN IP4 0.0.0.0\r\n
|
||||
s=-\r\n
|
||||
t=0 0\r\n
|
||||
a=bundle-only\r\n
|
||||
m=audio 0 UDP/TLS/RTP/SAVPF 0\r\n",
|
||||
true
|
||||
)
|
||||
.is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_sdp_integer_error() {
|
||||
assert!(parse_sdp(
|
||||
"v=0\r\n
|
||||
o=- 0 0 IN IP4 0.0.0.0\r\n
|
||||
s=-\r\n
|
||||
t=0 0\r\n
|
||||
m=audio 0 UDP/TLS/RTP/SAVPF 0\r\n
|
||||
a=rtcp:34er21\r\n",
|
||||
true
|
||||
)
|
||||
.is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_sdp_ipaddr_error() {
|
||||
assert!(parse_sdp(
|
||||
"v=0\r\n
|
||||
o=- 0 0 IN IP4 0.a.b.0\r\n
|
||||
s=-\r\n
|
||||
t=0 0\r\n
|
||||
m=audio 0 UDP/TLS/RTP/SAVPF 0\r\n",
|
||||
true
|
||||
)
|
||||
.is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_sdp_invalid_session_attribute() {
|
||||
assert!(parse_sdp(
|
||||
"v=0\r\n
|
||||
o=- 0 0 IN IP4 0.a.b.0\r\n
|
||||
s=-\r\n
|
||||
t=0 0\r\n
|
||||
a=bundle-only\r\n
|
||||
m=audio 0 UDP/TLS/RTP/SAVPF 0\r\n",
|
||||
true
|
||||
)
|
||||
.is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_sdp_invalid_media_attribute() {
|
||||
assert!(parse_sdp(
|
||||
"v=0\r\n
|
||||
o=- 0 0 IN IP4 0.a.b.0\r\n
|
||||
s=-\r\n
|
||||
t=0 0\r\n
|
||||
m=audio 0 UDP/TLS/RTP/SAVPF 0\r\n
|
||||
a=ice-lite\r\n",
|
||||
true
|
||||
)
|
||||
.is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_mask_origin() {
|
||||
let mut anon = StatefulSdpAnonymizer::new();
|
||||
if let SdpType::Origin(origin_1) =
|
||||
parse_origin("mozilla 506705521068071134 0 IN IP4 0.0.0.0").unwrap()
|
||||
{
|
||||
for _ in 0..2 {
|
||||
let masked = origin_1.masked_clone(&mut anon);
|
||||
assert_eq!(masked.username, "origin-user-00000001");
|
||||
assert_eq!(
|
||||
masked.unicast_addr,
|
||||
ExplicitlyTypedAddress::Ip(IpAddr::V4(Ipv4Addr::from(1)))
|
||||
);
|
||||
}
|
||||
} else {
|
||||
unreachable!();
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_mask_sdp() {
|
||||
let mut anon = StatefulSdpAnonymizer::new();
|
||||
let sdp = parse_sdp(
|
||||
"v=0\r\n
|
||||
o=ausername 4294967296 2 IN IP4 127.0.0.1\r\n
|
||||
s=SIP Call\r\n
|
||||
c=IN IP4 198.51.100.7/51\r\n
|
||||
a=ice-pwd:12340\r\n
|
||||
a=ice-ufrag:4a799b2e\r\n
|
||||
a=fingerprint:sha-1 CD:34:D1:62:16:95:7B:B7:EB:74:E2:39:27:97:EB:0B:23:73:AC:BC\r\n
|
||||
t=0 0\r\n
|
||||
m=video 56436 RTP/SAVPF 120\r\n
|
||||
a=candidate:77142221 1 udp 2113937151 192.168.137.1 54081 typ host\r\n
|
||||
a=remote-candidates:0 10.0.0.1 5555\r\n
|
||||
a=rtpmap:120 VP8/90000\r\n",
|
||||
true,
|
||||
)
|
||||
.unwrap();
|
||||
let mut masked = sdp.masked_clone(&mut anon);
|
||||
assert_eq!(masked.origin.username, "origin-user-00000001");
|
||||
assert_eq!(
|
||||
masked.origin.unicast_addr,
|
||||
ExplicitlyTypedAddress::Ip(IpAddr::V4(Ipv4Addr::from(1)))
|
||||
);
|
||||
assert_eq!(
|
||||
masked.connection.unwrap().address,
|
||||
ExplicitlyTypedAddress::Ip(IpAddr::V4(Ipv4Addr::from(2)))
|
||||
);
|
||||
let mut attributes = masked.attribute;
|
||||
for m in &mut masked.media {
|
||||
for attribute in m.get_attributes() {
|
||||
attributes.push(attribute.clone());
|
||||
}
|
||||
}
|
||||
for attribute in attributes {
|
||||
match attribute {
|
||||
SdpAttribute::Candidate(c) => {
|
||||
assert_eq!(c.address, Address::Ip(IpAddr::V4(Ipv4Addr::from(3))));
|
||||
assert_eq!(c.port, 1);
|
||||
}
|
||||
SdpAttribute::Fingerprint(f) => {
|
||||
assert_eq!(f.fingerprint, 1u64.to_byte_vec());
|
||||
}
|
||||
SdpAttribute::IcePwd(p) => {
|
||||
assert_eq!(p, "ice-password-00000001");
|
||||
}
|
||||
SdpAttribute::IceUfrag(u) => {
|
||||
assert_eq!(u, "ice-user-00000001");
|
||||
}
|
||||
SdpAttribute::RemoteCandidate(r) => {
|
||||
assert_eq!(r.address, Address::Ip(IpAddr::V4(Ipv4Addr::from(4))));
|
||||
assert_eq!(r.port, 2);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_session_vector() -> Result<(), SdpParserError> {
|
||||
let mut sdp_session = create_dummy_sdp_session();
|
||||
let mut lines: Vec<SdpLine> = Vec::new();
|
||||
lines.push(parse_sdp_line("a=sendrecv", 1)?);
|
||||
sdp_session.parse_session_vector(&mut lines)?;
|
||||
assert_eq!(sdp_session.attribute.len(), 1);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_session_vector_non_session_attribute() -> Result<(), SdpParserError> {
|
||||
let mut sdp_session = create_dummy_sdp_session();
|
||||
let mut lines: Vec<SdpLine> = Vec::new();
|
||||
lines.push(parse_sdp_line("a=bundle-only", 2)?);
|
||||
assert!(sdp_session.parse_session_vector(&mut lines).is_err());
|
||||
assert_eq!(sdp_session.attribute.len(), 0);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_session_vector_version_repeated() -> Result<(), SdpParserError> {
|
||||
let mut sdp_session = create_dummy_sdp_session();
|
||||
let mut lines: Vec<SdpLine> = Vec::new();
|
||||
lines.push(parse_sdp_line("v=0", 3)?);
|
||||
assert!(sdp_session.parse_session_vector(&mut lines).is_err());
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_session_vector_contains_media_type() -> Result<(), SdpParserError> {
|
||||
let mut sdp_session = create_dummy_sdp_session();
|
||||
let mut lines: Vec<SdpLine> = Vec::new();
|
||||
lines.push(parse_sdp_line("m=audio 0 UDP/TLS/RTP/SAVPF 0", 4)?);
|
||||
assert!(sdp_session.parse_session_vector(&mut lines).is_err());
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_sdp_vector_no_media_section() -> Result<(), SdpParserError> {
|
||||
let mut lines: Vec<SdpLine> = Vec::new();
|
||||
lines.push(parse_sdp_line("v=0", 1)?);
|
||||
lines.push(parse_sdp_line(
|
||||
"o=ausername 4294967296 2 IN IP4 127.0.0.1",
|
||||
1,
|
||||
)?);
|
||||
lines.push(parse_sdp_line("s=SIP Call", 1)?);
|
||||
lines.push(parse_sdp_line("t=0 0", 1)?);
|
||||
lines.push(parse_sdp_line("c=IN IP6 ::1", 1)?);
|
||||
assert!(parse_sdp_vector(&mut lines).is_ok());
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_sdp_vector_with_media_section() -> Result<(), SdpParserError> {
|
||||
let mut lines: Vec<SdpLine> = Vec::new();
|
||||
lines.push(parse_sdp_line("v=0", 1)?);
|
||||
lines.push(parse_sdp_line(
|
||||
"o=ausername 4294967296 2 IN IP4 127.0.0.1",
|
||||
1,
|
||||
)?);
|
||||
lines.push(parse_sdp_line("s=SIP Call", 1)?);
|
||||
lines.push(parse_sdp_line("t=0 0", 1)?);
|
||||
lines.push(parse_sdp_line("m=video 56436 RTP/SAVPF 120", 1)?);
|
||||
lines.push(parse_sdp_line("c=IN IP6 ::1", 1)?);
|
||||
assert!(parse_sdp_vector(&mut lines).is_ok());
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_sdp_vector_too_short() -> Result<(), SdpParserError> {
|
||||
let mut lines: Vec<SdpLine> = Vec::new();
|
||||
lines.push(parse_sdp_line("v=0", 1)?);
|
||||
assert!(parse_sdp_vector(&mut lines).is_err());
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_sdp_vector_missing_version() -> Result<(), SdpParserError> {
|
||||
let mut lines: Vec<SdpLine> = Vec::new();
|
||||
lines.push(parse_sdp_line(
|
||||
"o=ausername 4294967296 2 IN IP4 127.0.0.1",
|
||||
1,
|
||||
)?);
|
||||
for _ in 0..3 {
|
||||
lines.push(parse_sdp_line("a=sendrecv", 1)?);
|
||||
}
|
||||
assert!(parse_sdp_vector(&mut lines).is_err());
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_sdp_vector_missing_origin() -> Result<(), SdpParserError> {
|
||||
let mut lines: Vec<SdpLine> = Vec::new();
|
||||
lines.push(parse_sdp_line("v=0", 1)?);
|
||||
for _ in 0..3 {
|
||||
lines.push(parse_sdp_line("a=sendrecv", 1)?);
|
||||
}
|
||||
assert!(parse_sdp_vector(&mut lines).is_err());
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_sdp_vector_missing_session() -> Result<(), SdpParserError> {
|
||||
let mut lines: Vec<SdpLine> = Vec::new();
|
||||
lines.push(parse_sdp_line("v=0", 1)?);
|
||||
lines.push(parse_sdp_line(
|
||||
"o=ausername 4294967296 2 IN IP4 127.0.0.1",
|
||||
1,
|
||||
)?);
|
||||
for _ in 0..2 {
|
||||
lines.push(parse_sdp_line("a=sendrecv", 1)?);
|
||||
}
|
||||
assert!(parse_sdp_vector(&mut lines).is_err());
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_session_add_media_works() -> Result<(), SdpParserError> {
|
||||
let mut sdp_session = create_dummy_sdp_session();
|
||||
assert!(sdp_session
|
||||
.add_media(
|
||||
SdpMediaValue::Audio,
|
||||
SdpAttribute::Sendrecv,
|
||||
99,
|
||||
SdpProtocolValue::RtpSavpf,
|
||||
ExplicitlyTypedAddress::from(Ipv4Addr::new(127, 0, 0, 1))
|
||||
)
|
||||
.is_ok());
|
||||
assert!(sdp_session.get_connection().is_some());
|
||||
assert_eq!(sdp_session.attribute.len(), 0);
|
||||
assert_eq!(sdp_session.media.len(), 1);
|
||||
assert_eq!(sdp_session.media[0].get_attributes().len(), 1);
|
||||
assert!(sdp_session.media[0]
|
||||
.get_attribute(SdpAttributeType::Sendrecv)
|
||||
.is_some());
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_session_add_media_invalid_attribute_fails() -> Result<(), SdpParserInternalError> {
|
||||
let mut sdp_session = create_dummy_sdp_session();
|
||||
assert!(sdp_session
|
||||
.add_media(
|
||||
SdpMediaValue::Audio,
|
||||
SdpAttribute::IceLite,
|
||||
99,
|
||||
SdpProtocolValue::RtpSavpf,
|
||||
ExplicitlyTypedAddress::try_from((AddressType::IpV4, "127.0.0.1"))?
|
||||
)
|
||||
.is_err());
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
#[path = "./lib_tests.rs"]
|
||||
mod tests;
|
||||
|
774
third_party/rust/webrtc-sdp/src/lib_tests.rs
vendored
Normal file
774
third_party/rust/webrtc-sdp/src/lib_tests.rs
vendored
Normal file
@ -0,0 +1,774 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
extern crate url;
|
||||
use super::*;
|
||||
use address::{Address, AddressType};
|
||||
use anonymizer::ToBytesVec;
|
||||
use std::net::IpAddr;
|
||||
use std::net::Ipv4Addr;
|
||||
|
||||
fn create_dummy_sdp_session() -> SdpSession {
|
||||
let origin = parse_origin("mozilla 506705521068071134 0 IN IP4 0.0.0.0");
|
||||
assert!(origin.is_ok());
|
||||
let connection = parse_connection("IN IP4 198.51.100.7");
|
||||
assert!(connection.is_ok());
|
||||
let mut sdp_session;
|
||||
if let SdpType::Origin(o) = origin.unwrap() {
|
||||
sdp_session = SdpSession::new(0, o, "-".to_string());
|
||||
|
||||
if let Ok(SdpType::Connection(c)) = connection {
|
||||
sdp_session.connection = Some(c);
|
||||
} else {
|
||||
unreachable!();
|
||||
}
|
||||
} else {
|
||||
unreachable!();
|
||||
}
|
||||
sdp_session
|
||||
}
|
||||
|
||||
pub fn create_dummy_media_section() -> SdpMedia {
|
||||
let media_line = SdpMediaLine {
|
||||
media: SdpMediaValue::Audio,
|
||||
port: 9,
|
||||
port_count: 0,
|
||||
proto: SdpProtocolValue::RtpSavpf,
|
||||
formats: SdpFormatList::Integers(Vec::new()),
|
||||
};
|
||||
SdpMedia::new(media_line)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_session_works() -> Result<(), SdpParserInternalError> {
|
||||
parse_session("topic")?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_version_works() -> Result<(), SdpParserInternalError> {
|
||||
parse_version("0")?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_version_unsupported_input() {
|
||||
assert!(parse_version("1").is_err());
|
||||
assert!(parse_version("11").is_err());
|
||||
assert!(parse_version("a").is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_origin_works() -> Result<(), SdpParserInternalError> {
|
||||
parse_origin("mozilla 506705521068071134 0 IN IP4 0.0.0.0")?;
|
||||
parse_origin("mozilla 506705521068071134 0 IN IP6 2001:db8::1")?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_origin_missing_username() {
|
||||
assert!(parse_origin("").is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_origin_missing_session_id() {
|
||||
assert!(parse_origin("mozilla ").is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_origin_missing_session_version() {
|
||||
assert!(parse_origin("mozilla 506705521068071134 ").is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_origin_missing_nettype() {
|
||||
assert!(parse_origin("mozilla 506705521068071134 0 ").is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_origin_unsupported_nettype() {
|
||||
assert!(parse_origin("mozilla 506705521068071134 0 UNSUPPORTED IP4 0.0.0.0").is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_origin_missing_addtype() {
|
||||
assert!(parse_origin("mozilla 506705521068071134 0 IN ").is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_origin_missing_ip_addr() {
|
||||
assert!(parse_origin("mozilla 506705521068071134 0 IN IP4 ").is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_origin_unsupported_addrtpe() {
|
||||
assert!(parse_origin("mozilla 506705521068071134 0 IN IP1 0.0.0.0").is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_origin_invalid_ip_addr() {
|
||||
assert!(parse_origin("mozilla 506705521068071134 0 IN IP4 1.1.1.256").is_err());
|
||||
assert!(parse_origin("mozilla 506705521068071134 0 IN IP6 ::g").is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_origin_addr_type_mismatch() {
|
||||
assert!(parse_origin("mozilla 506705521068071134 0 IN IP4 ::1").is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn connection_works() -> Result<(), SdpParserInternalError> {
|
||||
parse_connection("IN IP4 127.0.0.1")?;
|
||||
parse_connection("IN IP4 127.0.0.1/10/10")?;
|
||||
parse_connection("IN IP6 ::1")?;
|
||||
parse_connection("IN IP6 ::1/1/1")?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn connection_lots_of_whitespace() -> Result<(), SdpParserInternalError> {
|
||||
parse_connection("IN IP4 127.0.0.1")?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn connection_wrong_amount_of_tokens() {
|
||||
assert!(parse_connection("IN IP4").is_err());
|
||||
assert!(parse_connection("IN IP4 0.0.0.0 foobar").is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn connection_unsupported_nettype() {
|
||||
assert!(parse_connection("UNSUPPORTED IP4 0.0.0.0").is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn connection_unsupported_addrtpe() {
|
||||
assert!(parse_connection("IN IP1 0.0.0.0").is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn connection_broken_ip_addr() {
|
||||
assert!(parse_connection("IN IP4 1.1.1.256").is_err());
|
||||
assert!(parse_connection("IN IP6 ::g").is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn connection_addr_type_mismatch() {
|
||||
assert!(parse_connection("IN IP4 ::1").is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn bandwidth_works() -> Result<(), SdpParserInternalError> {
|
||||
parse_bandwidth("AS:1")?;
|
||||
parse_bandwidth("CT:123")?;
|
||||
parse_bandwidth("TIAS:12345")?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn bandwidth_wrong_amount_of_tokens() {
|
||||
assert!(parse_bandwidth("TIAS").is_err());
|
||||
assert!(parse_bandwidth("TIAS:12345:xyz").is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn bandwidth_unsupported_type() -> Result<(), SdpParserInternalError> {
|
||||
parse_bandwidth("UNSUPPORTED:12345")?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_timing_works() -> Result<(), SdpParserInternalError> {
|
||||
parse_timing("0 0")?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_timing_non_numeric_tokens() {
|
||||
assert!(parse_timing("a 0").is_err());
|
||||
assert!(parse_timing("0 a").is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_timing_wrong_amount_of_tokens() {
|
||||
assert!(parse_timing("0").is_err());
|
||||
assert!(parse_timing("0 0 0").is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_sdp_line_works() -> Result<(), SdpParserError> {
|
||||
parse_sdp_line("v=0", 0)?;
|
||||
parse_sdp_line("s=somesession", 0)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_sdp_line_empty_line() {
|
||||
assert!(parse_sdp_line("", 0).is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_sdp_line_unsupported_types() {
|
||||
assert!(parse_sdp_line("e=foobar", 0).is_err());
|
||||
assert!(parse_sdp_line("i=foobar", 0).is_err());
|
||||
assert!(parse_sdp_line("k=foobar", 0).is_err());
|
||||
assert!(parse_sdp_line("p=foobar", 0).is_err());
|
||||
assert!(parse_sdp_line("r=foobar", 0).is_err());
|
||||
assert!(parse_sdp_line("u=foobar", 0).is_err());
|
||||
assert!(parse_sdp_line("z=foobar", 0).is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_sdp_line_unknown_key() {
|
||||
assert!(parse_sdp_line("y=foobar", 0).is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_sdp_line_too_long_type() {
|
||||
assert!(parse_sdp_line("ab=foobar", 0).is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_sdp_line_without_equal() {
|
||||
assert!(parse_sdp_line("abcd", 0).is_err());
|
||||
assert!(parse_sdp_line("ab cd", 0).is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_sdp_line_empty_value() {
|
||||
assert!(parse_sdp_line("v=", 0).is_err());
|
||||
assert!(parse_sdp_line("o=", 0).is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_sdp_line_empty_name() {
|
||||
assert!(parse_sdp_line("=abc", 0).is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_sdp_line_valid_a_line() -> Result<(), SdpParserError> {
|
||||
parse_sdp_line("a=rtpmap:8 PCMA/8000", 0)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_sdp_line_invalid_a_line() {
|
||||
assert!(parse_sdp_line("a=rtpmap:200 PCMA/8000", 0).is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_add_attribute() -> Result<(), SdpParserInternalError> {
|
||||
let mut sdp_session = create_dummy_sdp_session();
|
||||
|
||||
sdp_session.add_attribute(SdpAttribute::Sendrecv)?;
|
||||
assert!(sdp_session.add_attribute(SdpAttribute::BundleOnly).is_err());
|
||||
assert_eq!(sdp_session.attribute.len(), 1);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_sanity_check_sdp_session_timing() -> Result<(), SdpParserError> {
|
||||
let mut sdp_session = create_dummy_sdp_session();
|
||||
sdp_session.extend_media(vec![create_dummy_media_section()]);
|
||||
|
||||
assert!(sanity_check_sdp_session(&sdp_session).is_err());
|
||||
|
||||
let t = SdpTiming { start: 0, stop: 0 };
|
||||
sdp_session.set_timing(t);
|
||||
|
||||
sanity_check_sdp_session(&sdp_session)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_sanity_check_sdp_session_media() -> Result<(), SdpParserError> {
|
||||
let mut sdp_session = create_dummy_sdp_session();
|
||||
let t = SdpTiming { start: 0, stop: 0 };
|
||||
sdp_session.set_timing(t);
|
||||
|
||||
sanity_check_sdp_session(&sdp_session)?;
|
||||
|
||||
sdp_session.extend_media(vec![create_dummy_media_section()]);
|
||||
|
||||
sanity_check_sdp_session(&sdp_session)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_sanity_check_sdp_connection() -> Result<(), SdpParserInternalError> {
|
||||
let origin = parse_origin("mozilla 506705521068071134 0 IN IP4 0.0.0.0")?;
|
||||
let mut sdp_session;
|
||||
if let SdpType::Origin(o) = origin {
|
||||
sdp_session = SdpSession::new(0, o, "-".to_string());
|
||||
} else {
|
||||
unreachable!();
|
||||
}
|
||||
let t = SdpTiming { start: 0, stop: 0 };
|
||||
sdp_session.set_timing(t);
|
||||
|
||||
assert!(sanity_check_sdp_session(&sdp_session).is_ok());
|
||||
|
||||
// the dummy media section doesn't contain a connection
|
||||
sdp_session.extend_media(vec![create_dummy_media_section()]);
|
||||
|
||||
assert!(sanity_check_sdp_session(&sdp_session).is_err());
|
||||
|
||||
let connection = parse_connection("IN IP6 ::1")?;
|
||||
if let SdpType::Connection(c) = connection {
|
||||
sdp_session.connection = Some(c);
|
||||
} else {
|
||||
unreachable!();
|
||||
}
|
||||
|
||||
assert!(sanity_check_sdp_session(&sdp_session).is_ok());
|
||||
|
||||
let mut second_media = create_dummy_media_section();
|
||||
let mconnection = parse_connection("IN IP4 0.0.0.0")?;
|
||||
if let SdpType::Connection(c) = mconnection {
|
||||
second_media.set_connection(c);
|
||||
} else {
|
||||
unreachable!();
|
||||
}
|
||||
sdp_session.extend_media(vec![second_media]);
|
||||
assert!(sdp_session.media.len() == 2);
|
||||
|
||||
assert!(sanity_check_sdp_session(&sdp_session).is_ok());
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_sanity_check_sdp_session_extmap() -> Result<(), SdpParserInternalError> {
|
||||
let mut sdp_session = create_dummy_sdp_session();
|
||||
let t = SdpTiming { start: 0, stop: 0 };
|
||||
sdp_session.set_timing(t);
|
||||
sdp_session.extend_media(vec![create_dummy_media_section()]);
|
||||
|
||||
let attribute =
|
||||
parse_attribute("extmap:3 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time")?;
|
||||
if let SdpType::Attribute(a) = attribute {
|
||||
sdp_session.add_attribute(a)?;
|
||||
} else {
|
||||
unreachable!();
|
||||
}
|
||||
assert!(sdp_session
|
||||
.get_attribute(SdpAttributeType::Extmap)
|
||||
.is_some());
|
||||
|
||||
assert!(sanity_check_sdp_session(&sdp_session).is_ok());
|
||||
|
||||
let mut second_media = create_dummy_media_section();
|
||||
let mattribute =
|
||||
parse_attribute("extmap:1/sendonly urn:ietf:params:rtp-hdrext:ssrc-audio-level")?;
|
||||
if let SdpType::Attribute(ma) = mattribute {
|
||||
second_media.add_attribute(ma)?;
|
||||
} else {
|
||||
unreachable!();
|
||||
}
|
||||
assert!(second_media
|
||||
.get_attribute(SdpAttributeType::Extmap)
|
||||
.is_some());
|
||||
|
||||
sdp_session.extend_media(vec![second_media]);
|
||||
assert!(sdp_session.media.len() == 2);
|
||||
|
||||
assert!(sanity_check_sdp_session(&sdp_session).is_err());
|
||||
|
||||
sdp_session.attribute = Vec::new();
|
||||
|
||||
assert!(sanity_check_sdp_session(&sdp_session).is_ok());
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_sanity_check_sdp_session_simulcast() -> Result<(), SdpParserError> {
|
||||
let mut sdp_session = create_dummy_sdp_session();
|
||||
let t = SdpTiming { start: 0, stop: 0 };
|
||||
sdp_session.set_timing(t);
|
||||
sdp_session.extend_media(vec![create_dummy_media_section()]);
|
||||
|
||||
sanity_check_sdp_session(&sdp_session)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_sdp_zero_length_string_fails() {
|
||||
assert!(parse_sdp("", true).is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_sdp_to_short_string() {
|
||||
assert!(parse_sdp("fooooobarrrr", true).is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_sdp_minimal_sdp_successfully() -> Result<(), SdpParserError> {
|
||||
parse_sdp(
|
||||
"v=0\r\n
|
||||
o=- 0 0 IN IP6 ::1\r\n
|
||||
s=-\r\n
|
||||
c=IN IP6 ::1\r\n
|
||||
t=0 0\r\n",
|
||||
true,
|
||||
)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_sdp_too_short() {
|
||||
assert!(parse_sdp(
|
||||
"v=0\r\n
|
||||
o=- 0 0 IN IP4 0.0.0.0\r\n
|
||||
s=-\r\n",
|
||||
true
|
||||
)
|
||||
.is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_sdp_line_error() {
|
||||
assert!(parse_sdp(
|
||||
"v=0\r\n
|
||||
o=- 0 0 IN IP4 0.0.0.0\r\n
|
||||
s=-\r\n
|
||||
t=0 foobar\r\n
|
||||
m=audio 0 UDP/TLS/RTP/SAVPF 0\r\n",
|
||||
true
|
||||
)
|
||||
.is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_sdp_unsupported_error() {
|
||||
assert!(parse_sdp(
|
||||
"v=0\r\n
|
||||
o=- 0 0 IN IP4 0.0.0.0\r\n
|
||||
s=-\r\n
|
||||
t=0 0\r\n
|
||||
m=foobar 0 UDP/TLS/RTP/SAVPF 0\r\n",
|
||||
true
|
||||
)
|
||||
.is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_sdp_unsupported_warning() -> Result<(), SdpParserError> {
|
||||
parse_sdp(
|
||||
"v=0\r\n
|
||||
o=- 0 0 IN IP4 0.0.0.0\r\n
|
||||
s=-\r\n
|
||||
c=IN IP4 198.51.100.7\r\n
|
||||
t=0 0\r\n
|
||||
m=audio 0 UDP/TLS/RTP/SAVPF 0\r\n
|
||||
a=unsupported\r\n",
|
||||
false,
|
||||
)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_sdp_sequence_error() {
|
||||
assert!(parse_sdp(
|
||||
"v=0\r\n
|
||||
o=- 0 0 IN IP4 0.0.0.0\r\n
|
||||
s=-\r\n
|
||||
t=0 0\r\n
|
||||
a=bundle-only\r\n
|
||||
m=audio 0 UDP/TLS/RTP/SAVPF 0\r\n",
|
||||
true
|
||||
)
|
||||
.is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_sdp_integer_error() {
|
||||
assert!(parse_sdp(
|
||||
"v=0\r\n
|
||||
o=- 0 0 IN IP4 0.0.0.0\r\n
|
||||
s=-\r\n
|
||||
t=0 0\r\n
|
||||
m=audio 0 UDP/TLS/RTP/SAVPF 0\r\n
|
||||
a=rtcp:34er21\r\n",
|
||||
true
|
||||
)
|
||||
.is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_sdp_ipaddr_error() {
|
||||
assert!(parse_sdp(
|
||||
"v=0\r\n
|
||||
o=- 0 0 IN IP4 0.a.b.0\r\n
|
||||
s=-\r\n
|
||||
t=0 0\r\n
|
||||
m=audio 0 UDP/TLS/RTP/SAVPF 0\r\n",
|
||||
true
|
||||
)
|
||||
.is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_sdp_invalid_session_attribute() {
|
||||
assert!(parse_sdp(
|
||||
"v=0\r\n
|
||||
o=- 0 0 IN IP4 0.a.b.0\r\n
|
||||
s=-\r\n
|
||||
t=0 0\r\n
|
||||
a=bundle-only\r\n
|
||||
m=audio 0 UDP/TLS/RTP/SAVPF 0\r\n",
|
||||
true
|
||||
)
|
||||
.is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_sdp_invalid_media_attribute() {
|
||||
assert!(parse_sdp(
|
||||
"v=0\r\n
|
||||
o=- 0 0 IN IP4 0.a.b.0\r\n
|
||||
s=-\r\n
|
||||
t=0 0\r\n
|
||||
m=audio 0 UDP/TLS/RTP/SAVPF 0\r\n
|
||||
a=ice-lite\r\n",
|
||||
true
|
||||
)
|
||||
.is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_mask_origin() {
|
||||
let mut anon = StatefulSdpAnonymizer::new();
|
||||
if let SdpType::Origin(origin_1) =
|
||||
parse_origin("mozilla 506705521068071134 0 IN IP4 0.0.0.0").unwrap()
|
||||
{
|
||||
for _ in 0..2 {
|
||||
let masked = origin_1.masked_clone(&mut anon);
|
||||
assert_eq!(masked.username, "origin-user-00000001");
|
||||
assert_eq!(
|
||||
masked.unicast_addr,
|
||||
ExplicitlyTypedAddress::Ip(IpAddr::V4(Ipv4Addr::from(1)))
|
||||
);
|
||||
}
|
||||
} else {
|
||||
unreachable!();
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_mask_sdp() {
|
||||
let mut anon = StatefulSdpAnonymizer::new();
|
||||
let sdp = parse_sdp(
|
||||
"v=0\r\n
|
||||
o=ausername 4294967296 2 IN IP4 127.0.0.1\r\n
|
||||
s=SIP Call\r\n
|
||||
c=IN IP4 198.51.100.7/51\r\n
|
||||
a=ice-pwd:12340\r\n
|
||||
a=ice-ufrag:4a799b2e\r\n
|
||||
a=fingerprint:sha-1 CD:34:D1:62:16:95:7B:B7:EB:74:E2:39:27:97:EB:0B:23:73:AC:BC\r\n
|
||||
t=0 0\r\n
|
||||
m=video 56436 RTP/SAVPF 120\r\n
|
||||
a=candidate:77142221 1 udp 2113937151 192.168.137.1 54081 typ host\r\n
|
||||
a=remote-candidates:0 10.0.0.1 5555\r\n
|
||||
a=rtpmap:120 VP8/90000\r\n",
|
||||
true,
|
||||
)
|
||||
.unwrap();
|
||||
let mut masked = sdp.masked_clone(&mut anon);
|
||||
assert_eq!(masked.origin.username, "origin-user-00000001");
|
||||
assert_eq!(
|
||||
masked.origin.unicast_addr,
|
||||
ExplicitlyTypedAddress::Ip(IpAddr::V4(Ipv4Addr::from(1)))
|
||||
);
|
||||
assert_eq!(
|
||||
masked.connection.unwrap().address,
|
||||
ExplicitlyTypedAddress::Ip(IpAddr::V4(Ipv4Addr::from(2)))
|
||||
);
|
||||
let mut attributes = masked.attribute;
|
||||
for m in &mut masked.media {
|
||||
for attribute in m.get_attributes() {
|
||||
attributes.push(attribute.clone());
|
||||
}
|
||||
}
|
||||
for attribute in attributes {
|
||||
match attribute {
|
||||
SdpAttribute::Candidate(c) => {
|
||||
assert_eq!(c.address, Address::Ip(IpAddr::V4(Ipv4Addr::from(3))));
|
||||
assert_eq!(c.port, 1);
|
||||
}
|
||||
SdpAttribute::Fingerprint(f) => {
|
||||
assert_eq!(f.fingerprint, 1u64.to_byte_vec());
|
||||
}
|
||||
SdpAttribute::IcePwd(p) => {
|
||||
assert_eq!(p, "ice-password-00000001");
|
||||
}
|
||||
SdpAttribute::IceUfrag(u) => {
|
||||
assert_eq!(u, "ice-user-00000001");
|
||||
}
|
||||
SdpAttribute::RemoteCandidate(r) => {
|
||||
assert_eq!(r.address, Address::Ip(IpAddr::V4(Ipv4Addr::from(4))));
|
||||
assert_eq!(r.port, 2);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_session_vector() -> Result<(), SdpParserError> {
|
||||
let mut sdp_session = create_dummy_sdp_session();
|
||||
let mut lines: Vec<SdpLine> = vec![parse_sdp_line("a=sendrecv", 1)?];
|
||||
sdp_session.parse_session_vector(&mut lines)?;
|
||||
assert_eq!(sdp_session.attribute.len(), 1);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_session_vector_non_session_attribute() -> Result<(), SdpParserError> {
|
||||
let mut sdp_session = create_dummy_sdp_session();
|
||||
let mut lines: Vec<SdpLine> = vec![parse_sdp_line("a=bundle-only", 2)?];
|
||||
assert!(sdp_session.parse_session_vector(&mut lines).is_err());
|
||||
assert_eq!(sdp_session.attribute.len(), 0);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_session_vector_version_repeated() -> Result<(), SdpParserError> {
|
||||
let mut sdp_session = create_dummy_sdp_session();
|
||||
let mut lines: Vec<SdpLine> = vec![parse_sdp_line("v=0", 3)?];
|
||||
assert!(sdp_session.parse_session_vector(&mut lines).is_err());
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_session_vector_contains_media_type() -> Result<(), SdpParserError> {
|
||||
let mut sdp_session = create_dummy_sdp_session();
|
||||
let mut lines: Vec<SdpLine> = vec![parse_sdp_line("m=audio 0 UDP/TLS/RTP/SAVPF 0", 4)?];
|
||||
assert!(sdp_session.parse_session_vector(&mut lines).is_err());
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_sdp_vector_no_media_section() -> Result<(), SdpParserError> {
|
||||
let mut lines: Vec<SdpLine> = vec![parse_sdp_line("v=0", 1)?];
|
||||
lines.push(parse_sdp_line(
|
||||
"o=ausername 4294967296 2 IN IP4 127.0.0.1",
|
||||
1,
|
||||
)?);
|
||||
lines.push(parse_sdp_line("s=SIP Call", 1)?);
|
||||
lines.push(parse_sdp_line("t=0 0", 1)?);
|
||||
lines.push(parse_sdp_line("c=IN IP6 ::1", 1)?);
|
||||
assert!(parse_sdp_vector(&mut lines).is_ok());
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_sdp_vector_with_media_section() -> Result<(), SdpParserError> {
|
||||
let mut lines: Vec<SdpLine> = vec![parse_sdp_line("v=0", 1)?];
|
||||
lines.push(parse_sdp_line(
|
||||
"o=ausername 4294967296 2 IN IP4 127.0.0.1",
|
||||
1,
|
||||
)?);
|
||||
lines.push(parse_sdp_line("s=SIP Call", 1)?);
|
||||
lines.push(parse_sdp_line("t=0 0", 1)?);
|
||||
lines.push(parse_sdp_line("m=video 56436 RTP/SAVPF 120", 1)?);
|
||||
lines.push(parse_sdp_line("c=IN IP6 ::1", 1)?);
|
||||
assert!(parse_sdp_vector(&mut lines).is_ok());
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_sdp_vector_with_missing_rtcp_mux() -> Result<(), SdpParserError> {
|
||||
let mut lines: Vec<SdpLine> = vec![parse_sdp_line("v=0", 1)?];
|
||||
lines.push(parse_sdp_line(
|
||||
"o=ausername 4294967296 2 IN IP4 127.0.0.1",
|
||||
1,
|
||||
)?);
|
||||
lines.push(parse_sdp_line("s=SIP Call", 1)?);
|
||||
lines.push(parse_sdp_line("t=0 0", 1)?);
|
||||
lines.push(parse_sdp_line("m=video 56436 RTP/SAVPF 120", 1)?);
|
||||
lines.push(parse_sdp_line("c=IN IP6 ::1", 1)?);
|
||||
lines.push(parse_sdp_line("a=rtcp-mux-only", 1)?);
|
||||
assert!(parse_sdp_vector(&mut lines).is_err());
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_sdp_vector_too_short() -> Result<(), SdpParserError> {
|
||||
let mut lines: Vec<SdpLine> = vec![parse_sdp_line("v=0", 1)?];
|
||||
assert!(parse_sdp_vector(&mut lines).is_err());
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_sdp_vector_missing_version() -> Result<(), SdpParserError> {
|
||||
let mut lines: Vec<SdpLine> = vec![parse_sdp_line(
|
||||
"o=ausername 4294967296 2 IN IP4 127.0.0.1",
|
||||
1,
|
||||
)?];
|
||||
for _ in 0..3 {
|
||||
lines.push(parse_sdp_line("a=sendrecv", 1)?);
|
||||
}
|
||||
assert!(parse_sdp_vector(&mut lines).is_err());
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_sdp_vector_missing_origin() -> Result<(), SdpParserError> {
|
||||
let mut lines: Vec<SdpLine> = vec![parse_sdp_line("v=0", 1)?];
|
||||
for _ in 0..3 {
|
||||
lines.push(parse_sdp_line("a=sendrecv", 1)?);
|
||||
}
|
||||
assert!(parse_sdp_vector(&mut lines).is_err());
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_sdp_vector_missing_session() -> Result<(), SdpParserError> {
|
||||
let mut lines: Vec<SdpLine> = vec![parse_sdp_line("v=0", 1)?];
|
||||
lines.push(parse_sdp_line(
|
||||
"o=ausername 4294967296 2 IN IP4 127.0.0.1",
|
||||
1,
|
||||
)?);
|
||||
for _ in 0..2 {
|
||||
lines.push(parse_sdp_line("a=sendrecv", 1)?);
|
||||
}
|
||||
assert!(parse_sdp_vector(&mut lines).is_err());
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_session_add_media_works() {
|
||||
let mut sdp_session = create_dummy_sdp_session();
|
||||
assert!(sdp_session
|
||||
.add_media(
|
||||
SdpMediaValue::Audio,
|
||||
SdpAttribute::Sendrecv,
|
||||
99,
|
||||
SdpProtocolValue::RtpSavpf,
|
||||
ExplicitlyTypedAddress::from(Ipv4Addr::new(127, 0, 0, 1))
|
||||
)
|
||||
.is_ok());
|
||||
assert!(sdp_session.get_connection().is_some());
|
||||
assert_eq!(sdp_session.attribute.len(), 0);
|
||||
assert_eq!(sdp_session.media.len(), 1);
|
||||
assert_eq!(sdp_session.media[0].get_attributes().len(), 1);
|
||||
assert!(sdp_session.media[0]
|
||||
.get_attribute(SdpAttributeType::Sendrecv)
|
||||
.is_some());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_session_add_media_invalid_attribute_fails() -> Result<(), SdpParserInternalError> {
|
||||
let mut sdp_session = create_dummy_sdp_session();
|
||||
assert!(sdp_session
|
||||
.add_media(
|
||||
SdpMediaValue::Audio,
|
||||
SdpAttribute::IceLite,
|
||||
99,
|
||||
SdpProtocolValue::RtpSavpf,
|
||||
ExplicitlyTypedAddress::try_from((AddressType::IpV4, "127.0.0.1"))?
|
||||
)
|
||||
.is_err());
|
||||
Ok(())
|
||||
}
|
415
third_party/rust/webrtc-sdp/src/media_type.rs
vendored
415
third_party/rust/webrtc-sdp/src/media_type.rs
vendored
@ -483,416 +483,5 @@ pub fn parse_media_vector(lines: &mut Vec<SdpLine>) -> Result<Vec<SdpMedia>, Sdp
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
pub fn create_dummy_media_section() -> SdpMedia {
|
||||
let media_line = SdpMediaLine {
|
||||
media: SdpMediaValue::Audio,
|
||||
port: 9,
|
||||
port_count: 0,
|
||||
proto: SdpProtocolValue::RtpSavpf,
|
||||
formats: SdpFormatList::Integers(Vec::new()),
|
||||
};
|
||||
SdpMedia::new(media_line)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use address::{AddressType, ExplicitlyTypedAddress};
|
||||
use attribute_type::{
|
||||
SdpAttributeFmtp, SdpAttributeFmtpParameters, SdpAttributePayloadType, SdpAttributeRtcpFb,
|
||||
SdpAttributeRtcpFbType,
|
||||
};
|
||||
use std::convert::TryFrom;
|
||||
|
||||
// TODO is this useful outside of tests?
|
||||
impl SdpFormatList {
|
||||
fn len(&self) -> usize {
|
||||
match *self {
|
||||
SdpFormatList::Integers(ref x) => x.len(),
|
||||
SdpFormatList::Strings(ref x) => x.len(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn add_dummy_attributes(media: &mut SdpMedia) {
|
||||
assert!(media
|
||||
.add_attribute(SdpAttribute::Rtcpfb(SdpAttributeRtcpFb {
|
||||
payload_type: SdpAttributePayloadType::Wildcard,
|
||||
feedback_type: SdpAttributeRtcpFbType::Ack,
|
||||
parameter: "".to_string(),
|
||||
extra: "".to_string(),
|
||||
},))
|
||||
.is_ok());
|
||||
assert!(media
|
||||
.add_attribute(SdpAttribute::Fmtp(SdpAttributeFmtp {
|
||||
payload_type: 1,
|
||||
parameters: SdpAttributeFmtpParameters {
|
||||
packetization_mode: 0,
|
||||
level_asymmetry_allowed: false,
|
||||
profile_level_id: 0x0042_0010,
|
||||
max_fs: 0,
|
||||
max_cpb: 0,
|
||||
max_dpb: 0,
|
||||
max_br: 0,
|
||||
max_mbps: 0,
|
||||
usedtx: false,
|
||||
stereo: false,
|
||||
useinbandfec: false,
|
||||
cbr: false,
|
||||
max_fr: 0,
|
||||
maxplaybackrate: 48000,
|
||||
maxaveragebitrate: 0,
|
||||
ptime: 0,
|
||||
minptime: 0,
|
||||
maxptime: 0,
|
||||
encodings: Vec::new(),
|
||||
dtmf_tones: "".to_string(),
|
||||
rtx: None,
|
||||
unknown_tokens: Vec::new()
|
||||
}
|
||||
},))
|
||||
.is_ok());
|
||||
assert!(media
|
||||
.add_attribute(SdpAttribute::Sctpmap(SdpAttributeSctpmap {
|
||||
port: 5000,
|
||||
channels: 2,
|
||||
}))
|
||||
.is_ok());
|
||||
assert!(media.add_attribute(SdpAttribute::BundleOnly).is_ok());
|
||||
assert!(media.add_attribute(SdpAttribute::SctpPort(5000)).is_ok());
|
||||
|
||||
assert!(media.get_attribute(SdpAttributeType::Rtpmap).is_some());
|
||||
assert!(media.get_attribute(SdpAttributeType::Rtcpfb).is_some());
|
||||
assert!(media.get_attribute(SdpAttributeType::Fmtp).is_some());
|
||||
assert!(media.get_attribute(SdpAttributeType::Sctpmap).is_some());
|
||||
assert!(media.get_attribute(SdpAttributeType::SctpPort).is_some());
|
||||
assert!(media.get_attribute(SdpAttributeType::BundleOnly).is_some());
|
||||
}
|
||||
|
||||
fn check_parse(media_line_str: &str) -> SdpMediaLine {
|
||||
if let Ok(SdpType::Media(media_line)) = parse_media(media_line_str) {
|
||||
media_line
|
||||
} else {
|
||||
unreachable!()
|
||||
}
|
||||
}
|
||||
|
||||
fn check_parse_and_serialize(media_line_str: &str) {
|
||||
let parsed = check_parse(media_line_str);
|
||||
assert_eq!(parsed.to_string(), media_line_str.to_string());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_get_set_port() {
|
||||
let mut msection = create_dummy_media_section();
|
||||
assert_eq!(msection.get_port(), 9);
|
||||
msection.set_port(2048);
|
||||
assert_eq!(msection.get_port(), 2048);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_add_codec() -> Result<(), SdpParserInternalError> {
|
||||
let mut msection = create_dummy_media_section();
|
||||
msection.add_codec(SdpAttributeRtpmap::new(96, "foobar".to_string(), 1000))?;
|
||||
assert_eq!(msection.get_formats().len(), 1);
|
||||
assert!(msection.get_attribute(SdpAttributeType::Rtpmap).is_some());
|
||||
|
||||
let mut msection = create_dummy_media_section();
|
||||
msection.media.formats = SdpFormatList::Strings(Vec::new());
|
||||
msection.add_codec(SdpAttributeRtpmap::new(97, "boofar".to_string(), 1001))?;
|
||||
assert_eq!(msection.get_formats().len(), 1);
|
||||
assert!(msection.get_attribute(SdpAttributeType::Rtpmap).is_some());
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_remove_codecs() -> Result<(), SdpParserInternalError> {
|
||||
let mut msection = create_dummy_media_section();
|
||||
msection.add_codec(SdpAttributeRtpmap::new(96, "foobar".to_string(), 1000))?;
|
||||
assert_eq!(msection.get_formats().len(), 1);
|
||||
assert!(msection.get_attribute(SdpAttributeType::Rtpmap).is_some());
|
||||
msection.remove_codecs();
|
||||
assert_eq!(msection.get_formats().len(), 0);
|
||||
assert!(msection.get_attribute(SdpAttributeType::Rtpmap).is_none());
|
||||
|
||||
let mut msection = create_dummy_media_section();
|
||||
msection.media.formats = SdpFormatList::Strings(Vec::new());
|
||||
msection.add_codec(SdpAttributeRtpmap::new(97, "boofar".to_string(), 1001))?;
|
||||
assert_eq!(msection.get_formats().len(), 1);
|
||||
|
||||
add_dummy_attributes(&mut msection);
|
||||
|
||||
msection.remove_codecs();
|
||||
assert_eq!(msection.get_formats().len(), 0);
|
||||
assert!(msection.get_attribute(SdpAttributeType::Rtpmap).is_none());
|
||||
assert!(msection.get_attribute(SdpAttributeType::Rtcpfb).is_none());
|
||||
assert!(msection.get_attribute(SdpAttributeType::Fmtp).is_none());
|
||||
assert!(msection.get_attribute(SdpAttributeType::Sctpmap).is_none());
|
||||
assert!(msection.get_attribute(SdpAttributeType::SctpPort).is_none());
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_add_datachannel() -> Result<(), SdpParserInternalError> {
|
||||
let mut msection = create_dummy_media_section();
|
||||
msection.add_datachannel("foo".to_string(), 5000, 256, 0)?;
|
||||
assert_eq!(*msection.get_type(), SdpMediaValue::Application);
|
||||
assert!(msection.get_attribute(SdpAttributeType::SctpPort).is_none());
|
||||
assert!(msection
|
||||
.get_attribute(SdpAttributeType::MaxMessageSize)
|
||||
.is_none());
|
||||
assert!(msection.get_attribute(SdpAttributeType::Sctpmap).is_some());
|
||||
match *msection.get_attribute(SdpAttributeType::Sctpmap).unwrap() {
|
||||
SdpAttribute::Sctpmap(ref s) => {
|
||||
assert_eq!(s.port, 5000);
|
||||
assert_eq!(s.channels, 256);
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
|
||||
let mut msection = create_dummy_media_section();
|
||||
msection.add_datachannel("foo".to_string(), 5000, 256, 1234)?;
|
||||
assert_eq!(*msection.get_type(), SdpMediaValue::Application);
|
||||
assert!(msection.get_attribute(SdpAttributeType::SctpPort).is_none());
|
||||
assert!(msection
|
||||
.get_attribute(SdpAttributeType::MaxMessageSize)
|
||||
.is_some());
|
||||
match *msection
|
||||
.get_attribute(SdpAttributeType::MaxMessageSize)
|
||||
.unwrap()
|
||||
{
|
||||
SdpAttribute::MaxMessageSize(m) => {
|
||||
assert_eq!(m, 1234);
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
|
||||
let mut msection = create_dummy_media_section();
|
||||
msection.media.proto = SdpProtocolValue::UdpDtlsSctp;
|
||||
msection.add_datachannel("foo".to_string(), 5000, 256, 5678)?;
|
||||
assert_eq!(*msection.get_type(), SdpMediaValue::Application);
|
||||
assert!(msection.get_attribute(SdpAttributeType::Sctpmap).is_none());
|
||||
assert!(msection.get_attribute(SdpAttributeType::SctpPort).is_some());
|
||||
match *msection.get_attribute(SdpAttributeType::SctpPort).unwrap() {
|
||||
SdpAttribute::SctpPort(s) => {
|
||||
assert_eq!(s, 5000);
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
assert!(msection
|
||||
.get_attribute(SdpAttributeType::MaxMessageSize)
|
||||
.is_some());
|
||||
match *msection
|
||||
.get_attribute(SdpAttributeType::MaxMessageSize)
|
||||
.unwrap()
|
||||
{
|
||||
SdpAttribute::MaxMessageSize(m) => {
|
||||
assert_eq!(m, 5678);
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_media_token() -> Result<(), SdpParserInternalError> {
|
||||
let audio = parse_media_token("audio")?;
|
||||
assert_eq!(audio, SdpMediaValue::Audio);
|
||||
let video = parse_media_token("VIDEO")?;
|
||||
assert_eq!(video, SdpMediaValue::Video);
|
||||
let app = parse_media_token("aPplIcatIOn")?;
|
||||
assert_eq!(app, SdpMediaValue::Application);
|
||||
|
||||
assert!(parse_media_token("").is_err());
|
||||
assert!(parse_media_token("foobar").is_err());
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_protocol_rtp_token() -> Result<(), SdpParserInternalError> {
|
||||
fn parse_and_serialize_protocol_token(
|
||||
token: &str,
|
||||
result: SdpProtocolValue,
|
||||
) -> Result<(), SdpParserInternalError> {
|
||||
let rtps = parse_protocol_token(token)?;
|
||||
assert_eq!(rtps, result);
|
||||
assert_eq!(rtps.to_string(), token.to_uppercase());
|
||||
Ok(())
|
||||
}
|
||||
parse_and_serialize_protocol_token("rtp/avp", SdpProtocolValue::RtpAvp)?;
|
||||
parse_and_serialize_protocol_token("rtp/avpf", SdpProtocolValue::RtpAvpf)?;
|
||||
parse_and_serialize_protocol_token("rtp/savp", SdpProtocolValue::RtpSavp)?;
|
||||
parse_and_serialize_protocol_token("rtp/savpf", SdpProtocolValue::RtpSavpf)?;
|
||||
parse_and_serialize_protocol_token("udp/tls/rtp/savp", SdpProtocolValue::UdpTlsRtpSavp)?;
|
||||
parse_and_serialize_protocol_token("udp/tls/rtp/savpf", SdpProtocolValue::UdpTlsRtpSavpf)?;
|
||||
parse_and_serialize_protocol_token("TCP/dtls/rtp/savp", SdpProtocolValue::TcpDtlsRtpSavp)?;
|
||||
parse_and_serialize_protocol_token(
|
||||
"tcp/DTLS/rtp/savpf",
|
||||
SdpProtocolValue::TcpDtlsRtpSavpf,
|
||||
)?;
|
||||
|
||||
assert!(parse_protocol_token("").is_err());
|
||||
assert!(parse_protocol_token("foobar").is_err());
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_protocol_sctp_token() -> Result<(), SdpParserInternalError> {
|
||||
fn parse_and_serialize_protocol_token(
|
||||
token: &str,
|
||||
result: SdpProtocolValue,
|
||||
) -> Result<(), SdpParserInternalError> {
|
||||
let rtps = parse_protocol_token(token)?;
|
||||
assert_eq!(rtps, result);
|
||||
assert_eq!(rtps.to_string(), token.to_uppercase());
|
||||
Ok(())
|
||||
}
|
||||
parse_and_serialize_protocol_token("dtLs/ScTP", SdpProtocolValue::DtlsSctp)?;
|
||||
parse_and_serialize_protocol_token("udp/DTLS/sctp", SdpProtocolValue::UdpDtlsSctp)?;
|
||||
parse_and_serialize_protocol_token("tcp/dtls/SCTP", SdpProtocolValue::TcpDtlsSctp)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_media_works() {
|
||||
check_parse_and_serialize("audio 9 UDP/TLS/RTP/SAVPF 109");
|
||||
check_parse_and_serialize("video 9 UDP/TLS/RTP/SAVPF 126");
|
||||
check_parse_and_serialize("application 9 DTLS/SCTP 5000");
|
||||
check_parse_and_serialize("application 9 UDP/DTLS/SCTP webrtc-datachannel");
|
||||
|
||||
check_parse_and_serialize("audio 9 UDP/TLS/RTP/SAVPF 109 9 0 8");
|
||||
check_parse_and_serialize("audio 0 UDP/TLS/RTP/SAVPF 8");
|
||||
check_parse_and_serialize("audio 9/2 UDP/TLS/RTP/SAVPF 8");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_media_missing_token() {
|
||||
assert!(parse_media("video 9 UDP/TLS/RTP/SAVPF").is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_media_invalid_port_number() {
|
||||
assert!(parse_media("video 75123 UDP/TLS/RTP/SAVPF 8").is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_media_invalid_type() {
|
||||
assert!(parse_media("invalid 9 UDP/TLS/RTP/SAVPF 8").is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_media_invalid_port() {
|
||||
assert!(parse_media("audio / UDP/TLS/RTP/SAVPF 8").is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_media_invalid_transport() {
|
||||
assert!(parse_media("audio 9 invalid/invalid 8").is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_media_invalid_payload() {
|
||||
assert!(parse_media("audio 9 UDP/TLS/RTP/SAVPF 300").is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_media_vector_first_line_failure() {
|
||||
let mut sdp_lines: Vec<SdpLine> = Vec::new();
|
||||
let line = SdpLine {
|
||||
line_number: 0,
|
||||
sdp_type: SdpType::Session("hello".to_string()),
|
||||
text: "".to_owned(),
|
||||
};
|
||||
sdp_lines.push(line);
|
||||
assert!(parse_media_vector(&mut sdp_lines).is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_media_vector_multiple_connections() {
|
||||
let mut sdp_lines: Vec<SdpLine> = Vec::new();
|
||||
let media_line = SdpMediaLine {
|
||||
media: SdpMediaValue::Audio,
|
||||
port: 9,
|
||||
port_count: 0,
|
||||
proto: SdpProtocolValue::RtpSavpf,
|
||||
formats: SdpFormatList::Integers(Vec::new()),
|
||||
};
|
||||
let media = SdpLine {
|
||||
line_number: 0,
|
||||
sdp_type: SdpType::Media(media_line),
|
||||
text: "".to_owned(),
|
||||
};
|
||||
sdp_lines.push(media);
|
||||
let c = SdpConnection {
|
||||
address: ExplicitlyTypedAddress::try_from((AddressType::IpV4, "127.0.0.1")).unwrap(),
|
||||
ttl: None,
|
||||
amount: None,
|
||||
};
|
||||
let c1 = SdpLine {
|
||||
line_number: 1,
|
||||
sdp_type: SdpType::Connection(c.clone()),
|
||||
text: "".to_owned(),
|
||||
};
|
||||
sdp_lines.push(c1);
|
||||
let c2 = SdpLine {
|
||||
line_number: 2,
|
||||
sdp_type: SdpType::Connection(c),
|
||||
text: "".to_owned(),
|
||||
};
|
||||
sdp_lines.push(c2);
|
||||
assert!(parse_media_vector(&mut sdp_lines).is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_media_vector_invalid_types() {
|
||||
let mut sdp_lines: Vec<SdpLine> = Vec::new();
|
||||
let media_line = SdpMediaLine {
|
||||
media: SdpMediaValue::Audio,
|
||||
port: 9,
|
||||
port_count: 0,
|
||||
proto: SdpProtocolValue::RtpSavpf,
|
||||
formats: SdpFormatList::Integers(Vec::new()),
|
||||
};
|
||||
let media = SdpLine {
|
||||
line_number: 0,
|
||||
sdp_type: SdpType::Media(media_line),
|
||||
text: "".to_owned(),
|
||||
};
|
||||
sdp_lines.push(media);
|
||||
use SdpTiming;
|
||||
let t = SdpTiming { start: 0, stop: 0 };
|
||||
let tline = SdpLine {
|
||||
line_number: 1,
|
||||
sdp_type: SdpType::Timing(t),
|
||||
text: "".to_owned(),
|
||||
};
|
||||
sdp_lines.push(tline);
|
||||
assert!(parse_media_vector(&mut sdp_lines).is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_media_vector_invalid_media_level_attribute() {
|
||||
let mut sdp_lines: Vec<SdpLine> = Vec::new();
|
||||
let media_line = SdpMediaLine {
|
||||
media: SdpMediaValue::Audio,
|
||||
port: 9,
|
||||
port_count: 0,
|
||||
proto: SdpProtocolValue::RtpSavpf,
|
||||
formats: SdpFormatList::Integers(Vec::new()),
|
||||
};
|
||||
let media = SdpLine {
|
||||
line_number: 0,
|
||||
sdp_type: SdpType::Media(media_line),
|
||||
text: "".to_owned(),
|
||||
};
|
||||
sdp_lines.push(media);
|
||||
let a = SdpAttribute::IceLite;
|
||||
let aline = SdpLine {
|
||||
line_number: 1,
|
||||
sdp_type: SdpType::Attribute(a),
|
||||
text: "".to_owned(),
|
||||
};
|
||||
sdp_lines.push(aline);
|
||||
assert!(parse_media_vector(&mut sdp_lines).is_err());
|
||||
}
|
||||
}
|
||||
#[path = "./media_type_tests.rs"]
|
||||
mod media_type_tests;
|
||||
|
411
third_party/rust/webrtc-sdp/src/media_type_tests.rs
vendored
Normal file
411
third_party/rust/webrtc-sdp/src/media_type_tests.rs
vendored
Normal file
@ -0,0 +1,411 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
use super::*;
|
||||
use address::{AddressType, ExplicitlyTypedAddress};
|
||||
use attribute_type::{
|
||||
SdpAttributeFmtp, SdpAttributeFmtpParameters, SdpAttributePayloadType, SdpAttributeRtcpFb,
|
||||
SdpAttributeRtcpFbType,
|
||||
};
|
||||
use std::convert::TryFrom;
|
||||
|
||||
pub fn create_dummy_media_section() -> SdpMedia {
|
||||
let media_line = SdpMediaLine {
|
||||
media: SdpMediaValue::Audio,
|
||||
port: 9,
|
||||
port_count: 0,
|
||||
proto: SdpProtocolValue::RtpSavpf,
|
||||
formats: SdpFormatList::Integers(Vec::new()),
|
||||
};
|
||||
SdpMedia::new(media_line)
|
||||
}
|
||||
|
||||
// TODO is this useful outside of tests?
|
||||
impl SdpFormatList {
|
||||
fn len(&self) -> usize {
|
||||
match *self {
|
||||
SdpFormatList::Integers(ref x) => x.len(),
|
||||
SdpFormatList::Strings(ref x) => x.len(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn add_dummy_attributes(media: &mut SdpMedia) {
|
||||
assert!(media
|
||||
.add_attribute(SdpAttribute::Rtcpfb(SdpAttributeRtcpFb {
|
||||
payload_type: SdpAttributePayloadType::Wildcard,
|
||||
feedback_type: SdpAttributeRtcpFbType::Ack,
|
||||
parameter: "".to_string(),
|
||||
extra: "".to_string(),
|
||||
},))
|
||||
.is_ok());
|
||||
assert!(media
|
||||
.add_attribute(SdpAttribute::Fmtp(SdpAttributeFmtp {
|
||||
payload_type: 1,
|
||||
parameters: SdpAttributeFmtpParameters {
|
||||
packetization_mode: 0,
|
||||
level_asymmetry_allowed: false,
|
||||
profile_level_id: 0x0042_0010,
|
||||
max_fs: 0,
|
||||
max_cpb: 0,
|
||||
max_dpb: 0,
|
||||
max_br: 0,
|
||||
max_mbps: 0,
|
||||
usedtx: false,
|
||||
stereo: false,
|
||||
useinbandfec: false,
|
||||
cbr: false,
|
||||
max_fr: 0,
|
||||
maxplaybackrate: 48000,
|
||||
maxaveragebitrate: 0,
|
||||
ptime: 0,
|
||||
minptime: 0,
|
||||
maxptime: 0,
|
||||
encodings: Vec::new(),
|
||||
dtmf_tones: "".to_string(),
|
||||
rtx: None,
|
||||
unknown_tokens: Vec::new()
|
||||
}
|
||||
},))
|
||||
.is_ok());
|
||||
assert!(media
|
||||
.add_attribute(SdpAttribute::Sctpmap(SdpAttributeSctpmap {
|
||||
port: 5000,
|
||||
channels: 2,
|
||||
}))
|
||||
.is_ok());
|
||||
assert!(media.add_attribute(SdpAttribute::BundleOnly).is_ok());
|
||||
assert!(media.add_attribute(SdpAttribute::SctpPort(5000)).is_ok());
|
||||
|
||||
assert!(media.get_attribute(SdpAttributeType::Rtpmap).is_some());
|
||||
assert!(media.get_attribute(SdpAttributeType::Rtcpfb).is_some());
|
||||
assert!(media.get_attribute(SdpAttributeType::Fmtp).is_some());
|
||||
assert!(media.get_attribute(SdpAttributeType::Sctpmap).is_some());
|
||||
assert!(media.get_attribute(SdpAttributeType::SctpPort).is_some());
|
||||
assert!(media.get_attribute(SdpAttributeType::BundleOnly).is_some());
|
||||
}
|
||||
|
||||
fn check_parse(media_line_str: &str) -> SdpMediaLine {
|
||||
if let Ok(SdpType::Media(media_line)) = parse_media(media_line_str) {
|
||||
media_line
|
||||
} else {
|
||||
unreachable!()
|
||||
}
|
||||
}
|
||||
|
||||
fn check_parse_and_serialize(media_line_str: &str) {
|
||||
let parsed = check_parse(media_line_str);
|
||||
assert_eq!(parsed.to_string(), media_line_str.to_string());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_get_set_port() {
|
||||
let mut msection = create_dummy_media_section();
|
||||
assert_eq!(msection.get_port(), 9);
|
||||
msection.set_port(2048);
|
||||
assert_eq!(msection.get_port(), 2048);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_add_codec() -> Result<(), SdpParserInternalError> {
|
||||
let mut msection = create_dummy_media_section();
|
||||
msection.add_codec(SdpAttributeRtpmap::new(96, "foobar".to_string(), 1000))?;
|
||||
assert_eq!(msection.get_formats().len(), 1);
|
||||
assert!(msection.get_attribute(SdpAttributeType::Rtpmap).is_some());
|
||||
|
||||
let mut msection = create_dummy_media_section();
|
||||
msection.media.formats = SdpFormatList::Strings(Vec::new());
|
||||
msection.add_codec(SdpAttributeRtpmap::new(97, "boofar".to_string(), 1001))?;
|
||||
assert_eq!(msection.get_formats().len(), 1);
|
||||
assert!(msection.get_attribute(SdpAttributeType::Rtpmap).is_some());
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_remove_codecs() -> Result<(), SdpParserInternalError> {
|
||||
let mut msection = create_dummy_media_section();
|
||||
msection.add_codec(SdpAttributeRtpmap::new(96, "foobar".to_string(), 1000))?;
|
||||
assert_eq!(msection.get_formats().len(), 1);
|
||||
assert!(msection.get_attribute(SdpAttributeType::Rtpmap).is_some());
|
||||
msection.remove_codecs();
|
||||
assert_eq!(msection.get_formats().len(), 0);
|
||||
assert!(msection.get_attribute(SdpAttributeType::Rtpmap).is_none());
|
||||
|
||||
let mut msection = create_dummy_media_section();
|
||||
msection.media.formats = SdpFormatList::Strings(Vec::new());
|
||||
msection.add_codec(SdpAttributeRtpmap::new(97, "boofar".to_string(), 1001))?;
|
||||
assert_eq!(msection.get_formats().len(), 1);
|
||||
|
||||
add_dummy_attributes(&mut msection);
|
||||
|
||||
msection.remove_codecs();
|
||||
assert_eq!(msection.get_formats().len(), 0);
|
||||
assert!(msection.get_attribute(SdpAttributeType::Rtpmap).is_none());
|
||||
assert!(msection.get_attribute(SdpAttributeType::Rtcpfb).is_none());
|
||||
assert!(msection.get_attribute(SdpAttributeType::Fmtp).is_none());
|
||||
assert!(msection.get_attribute(SdpAttributeType::Sctpmap).is_none());
|
||||
assert!(msection.get_attribute(SdpAttributeType::SctpPort).is_none());
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_add_datachannel() -> Result<(), SdpParserInternalError> {
|
||||
let mut msection = create_dummy_media_section();
|
||||
msection.add_datachannel("foo".to_string(), 5000, 256, 0)?;
|
||||
assert_eq!(*msection.get_type(), SdpMediaValue::Application);
|
||||
assert!(msection.get_attribute(SdpAttributeType::SctpPort).is_none());
|
||||
assert!(msection
|
||||
.get_attribute(SdpAttributeType::MaxMessageSize)
|
||||
.is_none());
|
||||
assert!(msection.get_attribute(SdpAttributeType::Sctpmap).is_some());
|
||||
match *msection.get_attribute(SdpAttributeType::Sctpmap).unwrap() {
|
||||
SdpAttribute::Sctpmap(ref s) => {
|
||||
assert_eq!(s.port, 5000);
|
||||
assert_eq!(s.channels, 256);
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
|
||||
let mut msection = create_dummy_media_section();
|
||||
msection.add_datachannel("foo".to_string(), 5000, 256, 1234)?;
|
||||
assert_eq!(*msection.get_type(), SdpMediaValue::Application);
|
||||
assert!(msection.get_attribute(SdpAttributeType::SctpPort).is_none());
|
||||
assert!(msection
|
||||
.get_attribute(SdpAttributeType::MaxMessageSize)
|
||||
.is_some());
|
||||
match *msection
|
||||
.get_attribute(SdpAttributeType::MaxMessageSize)
|
||||
.unwrap()
|
||||
{
|
||||
SdpAttribute::MaxMessageSize(m) => {
|
||||
assert_eq!(m, 1234);
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
|
||||
let mut msection = create_dummy_media_section();
|
||||
msection.media.proto = SdpProtocolValue::UdpDtlsSctp;
|
||||
msection.add_datachannel("foo".to_string(), 5000, 256, 5678)?;
|
||||
assert_eq!(*msection.get_type(), SdpMediaValue::Application);
|
||||
assert!(msection.get_attribute(SdpAttributeType::Sctpmap).is_none());
|
||||
assert!(msection.get_attribute(SdpAttributeType::SctpPort).is_some());
|
||||
match *msection.get_attribute(SdpAttributeType::SctpPort).unwrap() {
|
||||
SdpAttribute::SctpPort(s) => {
|
||||
assert_eq!(s, 5000);
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
assert!(msection
|
||||
.get_attribute(SdpAttributeType::MaxMessageSize)
|
||||
.is_some());
|
||||
match *msection
|
||||
.get_attribute(SdpAttributeType::MaxMessageSize)
|
||||
.unwrap()
|
||||
{
|
||||
SdpAttribute::MaxMessageSize(m) => {
|
||||
assert_eq!(m, 5678);
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_media_token() -> Result<(), SdpParserInternalError> {
|
||||
let audio = parse_media_token("audio")?;
|
||||
assert_eq!(audio, SdpMediaValue::Audio);
|
||||
let video = parse_media_token("VIDEO")?;
|
||||
assert_eq!(video, SdpMediaValue::Video);
|
||||
let app = parse_media_token("aPplIcatIOn")?;
|
||||
assert_eq!(app, SdpMediaValue::Application);
|
||||
|
||||
assert!(parse_media_token("").is_err());
|
||||
assert!(parse_media_token("foobar").is_err());
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_protocol_rtp_token() -> Result<(), SdpParserInternalError> {
|
||||
fn parse_and_serialize_protocol_token(
|
||||
token: &str,
|
||||
result: SdpProtocolValue,
|
||||
) -> Result<(), SdpParserInternalError> {
|
||||
let rtps = parse_protocol_token(token)?;
|
||||
assert_eq!(rtps, result);
|
||||
assert_eq!(rtps.to_string(), token.to_uppercase());
|
||||
Ok(())
|
||||
}
|
||||
parse_and_serialize_protocol_token("rtp/avp", SdpProtocolValue::RtpAvp)?;
|
||||
parse_and_serialize_protocol_token("rtp/avpf", SdpProtocolValue::RtpAvpf)?;
|
||||
parse_and_serialize_protocol_token("rtp/savp", SdpProtocolValue::RtpSavp)?;
|
||||
parse_and_serialize_protocol_token("rtp/savpf", SdpProtocolValue::RtpSavpf)?;
|
||||
parse_and_serialize_protocol_token("udp/tls/rtp/savp", SdpProtocolValue::UdpTlsRtpSavp)?;
|
||||
parse_and_serialize_protocol_token("udp/tls/rtp/savpf", SdpProtocolValue::UdpTlsRtpSavpf)?;
|
||||
parse_and_serialize_protocol_token("TCP/dtls/rtp/savp", SdpProtocolValue::TcpDtlsRtpSavp)?;
|
||||
parse_and_serialize_protocol_token("tcp/DTLS/rtp/savpf", SdpProtocolValue::TcpDtlsRtpSavpf)?;
|
||||
|
||||
assert!(parse_protocol_token("").is_err());
|
||||
assert!(parse_protocol_token("foobar").is_err());
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_protocol_sctp_token() -> Result<(), SdpParserInternalError> {
|
||||
fn parse_and_serialize_protocol_token(
|
||||
token: &str,
|
||||
result: SdpProtocolValue,
|
||||
) -> Result<(), SdpParserInternalError> {
|
||||
let rtps = parse_protocol_token(token)?;
|
||||
assert_eq!(rtps, result);
|
||||
assert_eq!(rtps.to_string(), token.to_uppercase());
|
||||
Ok(())
|
||||
}
|
||||
parse_and_serialize_protocol_token("dtLs/ScTP", SdpProtocolValue::DtlsSctp)?;
|
||||
parse_and_serialize_protocol_token("udp/DTLS/sctp", SdpProtocolValue::UdpDtlsSctp)?;
|
||||
parse_and_serialize_protocol_token("tcp/dtls/SCTP", SdpProtocolValue::TcpDtlsSctp)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_media_works() {
|
||||
check_parse_and_serialize("audio 9 UDP/TLS/RTP/SAVPF 109");
|
||||
check_parse_and_serialize("video 9 UDP/TLS/RTP/SAVPF 126");
|
||||
check_parse_and_serialize("application 9 DTLS/SCTP 5000");
|
||||
check_parse_and_serialize("application 9 UDP/DTLS/SCTP webrtc-datachannel");
|
||||
|
||||
check_parse_and_serialize("audio 9 UDP/TLS/RTP/SAVPF 109 9 0 8");
|
||||
check_parse_and_serialize("audio 0 UDP/TLS/RTP/SAVPF 8");
|
||||
check_parse_and_serialize("audio 9/2 UDP/TLS/RTP/SAVPF 8");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_media_missing_token() {
|
||||
assert!(parse_media("video 9 UDP/TLS/RTP/SAVPF").is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_media_invalid_port_number() {
|
||||
assert!(parse_media("video 75123 UDP/TLS/RTP/SAVPF 8").is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_media_invalid_type() {
|
||||
assert!(parse_media("invalid 9 UDP/TLS/RTP/SAVPF 8").is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_media_invalid_port() {
|
||||
assert!(parse_media("audio / UDP/TLS/RTP/SAVPF 8").is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_media_invalid_transport() {
|
||||
assert!(parse_media("audio 9 invalid/invalid 8").is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_media_invalid_payload() {
|
||||
assert!(parse_media("audio 9 UDP/TLS/RTP/SAVPF 300").is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_media_vector_first_line_failure() {
|
||||
let mut sdp_lines: Vec<SdpLine> = Vec::new();
|
||||
let line = SdpLine {
|
||||
line_number: 0,
|
||||
sdp_type: SdpType::Session("hello".to_string()),
|
||||
text: "".to_owned(),
|
||||
};
|
||||
sdp_lines.push(line);
|
||||
assert!(parse_media_vector(&mut sdp_lines).is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_media_vector_multiple_connections() {
|
||||
let mut sdp_lines: Vec<SdpLine> = Vec::new();
|
||||
let media_line = SdpMediaLine {
|
||||
media: SdpMediaValue::Audio,
|
||||
port: 9,
|
||||
port_count: 0,
|
||||
proto: SdpProtocolValue::RtpSavpf,
|
||||
formats: SdpFormatList::Integers(Vec::new()),
|
||||
};
|
||||
let media = SdpLine {
|
||||
line_number: 0,
|
||||
sdp_type: SdpType::Media(media_line),
|
||||
text: "".to_owned(),
|
||||
};
|
||||
sdp_lines.push(media);
|
||||
let c = SdpConnection {
|
||||
address: ExplicitlyTypedAddress::try_from((AddressType::IpV4, "127.0.0.1")).unwrap(),
|
||||
ttl: None,
|
||||
amount: None,
|
||||
};
|
||||
let c1 = SdpLine {
|
||||
line_number: 1,
|
||||
sdp_type: SdpType::Connection(c.clone()),
|
||||
text: "".to_owned(),
|
||||
};
|
||||
sdp_lines.push(c1);
|
||||
let c2 = SdpLine {
|
||||
line_number: 2,
|
||||
sdp_type: SdpType::Connection(c),
|
||||
text: "".to_owned(),
|
||||
};
|
||||
sdp_lines.push(c2);
|
||||
assert!(parse_media_vector(&mut sdp_lines).is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_media_vector_invalid_types() {
|
||||
let mut sdp_lines: Vec<SdpLine> = Vec::new();
|
||||
let media_line = SdpMediaLine {
|
||||
media: SdpMediaValue::Audio,
|
||||
port: 9,
|
||||
port_count: 0,
|
||||
proto: SdpProtocolValue::RtpSavpf,
|
||||
formats: SdpFormatList::Integers(Vec::new()),
|
||||
};
|
||||
let media = SdpLine {
|
||||
line_number: 0,
|
||||
sdp_type: SdpType::Media(media_line),
|
||||
text: "".to_owned(),
|
||||
};
|
||||
sdp_lines.push(media);
|
||||
use SdpTiming;
|
||||
let t = SdpTiming { start: 0, stop: 0 };
|
||||
let tline = SdpLine {
|
||||
line_number: 1,
|
||||
sdp_type: SdpType::Timing(t),
|
||||
text: "".to_owned(),
|
||||
};
|
||||
sdp_lines.push(tline);
|
||||
assert!(parse_media_vector(&mut sdp_lines).is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_media_vector_invalid_media_level_attribute() {
|
||||
let mut sdp_lines: Vec<SdpLine> = Vec::new();
|
||||
let media_line = SdpMediaLine {
|
||||
media: SdpMediaValue::Audio,
|
||||
port: 9,
|
||||
port_count: 0,
|
||||
proto: SdpProtocolValue::RtpSavpf,
|
||||
formats: SdpFormatList::Integers(Vec::new()),
|
||||
};
|
||||
let media = SdpLine {
|
||||
line_number: 0,
|
||||
sdp_type: SdpType::Media(media_line),
|
||||
text: "".to_owned(),
|
||||
};
|
||||
sdp_lines.push(media);
|
||||
let a = SdpAttribute::IceLite;
|
||||
let aline = SdpLine {
|
||||
line_number: 1,
|
||||
sdp_type: SdpType::Attribute(a),
|
||||
text: "".to_owned(),
|
||||
};
|
||||
sdp_lines.push(aline);
|
||||
assert!(parse_media_vector(&mut sdp_lines).is_err());
|
||||
}
|
35
third_party/rust/webrtc-sdp/src/network.rs
vendored
35
third_party/rust/webrtc-sdp/src/network.rs
vendored
@ -29,38 +29,9 @@ pub fn parse_address_type(value: &str) -> Result<AddressType, SdpParserInternalE
|
||||
}
|
||||
|
||||
pub fn parse_unicast_address(value: &str) -> Result<Address, SdpParserInternalError> {
|
||||
Ok(Address::from_str(value)?)
|
||||
Address::from_str(value)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_parse_network_type() -> Result<(), SdpParserInternalError> {
|
||||
parse_network_type("iN")?;
|
||||
|
||||
assert!(parse_network_type("").is_err());
|
||||
assert!(parse_network_type("FOO").is_err());
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_address_type() -> Result<(), SdpParserInternalError> {
|
||||
let ip4 = parse_address_type("iP4")?;
|
||||
assert_eq!(ip4, AddressType::IpV4);
|
||||
let ip6 = parse_address_type("Ip6")?;
|
||||
assert_eq!(ip6, AddressType::IpV6);
|
||||
|
||||
assert!(parse_address_type("").is_err());
|
||||
assert!(parse_address_type("IP5").is_err());
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_unicast_address() -> Result<(), SdpParserInternalError> {
|
||||
parse_unicast_address("127.0.0.1")?;
|
||||
parse_unicast_address("::1")?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
#[path = "./network_tests.rs"]
|
||||
mod tests;
|
||||
|
33
third_party/rust/webrtc-sdp/src/network_tests.rs
vendored
Normal file
33
third_party/rust/webrtc-sdp/src/network_tests.rs
vendored
Normal file
@ -0,0 +1,33 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_parse_network_type() -> Result<(), SdpParserInternalError> {
|
||||
parse_network_type("iN")?;
|
||||
|
||||
assert!(parse_network_type("").is_err());
|
||||
assert!(parse_network_type("FOO").is_err());
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_address_type() -> Result<(), SdpParserInternalError> {
|
||||
let ip4 = parse_address_type("iP4")?;
|
||||
assert_eq!(ip4, AddressType::IpV4);
|
||||
let ip6 = parse_address_type("Ip6")?;
|
||||
assert_eq!(ip6, AddressType::IpV6);
|
||||
|
||||
assert!(parse_address_type("").is_err());
|
||||
assert!(parse_address_type("IP5").is_err());
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_unicast_address() -> Result<(), SdpParserInternalError> {
|
||||
parse_unicast_address("127.0.0.1")?;
|
||||
parse_unicast_address("::1")?;
|
||||
Ok(())
|
||||
}
|
@ -687,3 +687,97 @@ fn parse_and_serialize_sdp_with_unusual_attributes() {
|
||||
|
||||
check_parse_and_serialize(sdp_str);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn serialize_complex_sdp_and_validate_no_empty_lines() {
|
||||
let sdp = "v=0\r\n
|
||||
o=- 3836772544440436510 2 IN IP4 127.0.0.1\r\n
|
||||
s=-\r\n
|
||||
t=0 0\r\n
|
||||
a=group:BUNDLE audio video\r\n
|
||||
a=msid-semantic: WMS HWpbmTmXleVSnlssQd80bPuw9cxQFroDkkBP\r\n
|
||||
m=audio 9 UDP/TLS/RTP/SAVPF 111 103 104 9 0 8 106 105 13 126\r\n
|
||||
c=IN IP4 0.0.0.0\r\n
|
||||
a=rtcp:9 IN IP4 0.0.0.0\r\n
|
||||
a=ice-ufrag:A4by\r\n
|
||||
a=ice-pwd:Gfvb2rbYMiW0dZz8ZkEsXICs\r\n
|
||||
a=fingerprint:sha-256 15:B0:92:1F:C7:40:EE:22:A6:AF:26:EF:EA:FF:37:1D:B3:EF:11:0B:8B:73:4F:01:7D:C9:AE:26:4F:87:E0:95\r\n
|
||||
a=setup:actpass\r\n
|
||||
a=mid:audio\r\n
|
||||
a=extmap:1 urn:ietf:params:rtp-hdrext:ssrc-audio-level\r\n
|
||||
a=sendrecv\r\n
|
||||
a=rtcp-mux\r\n
|
||||
a=rtcp-mux-only\r\n
|
||||
a=rtpmap:111 opus/48000/2\r\n
|
||||
a=rtcp-fb:111 transport-cc\r\n
|
||||
a=fmtp:111 minptime=10;useinbandfec=1\r\n
|
||||
a=rtpmap:103 ISAC/16000\r\n
|
||||
a=rtpmap:104 ISAC/32000\r\n
|
||||
a=rtpmap:9 G722/8000\r\n
|
||||
a=rtpmap:0 PCMU/8000\r\n
|
||||
a=rtpmap:8 PCMA/8000\r\n
|
||||
a=rtpmap:106 CN/32000\r\n
|
||||
a=rtpmap:105 CN/16000\r\n
|
||||
a=rtpmap:13 CN/8000\r\n
|
||||
a=rtpmap:126 telephone-event/8000\r\n
|
||||
a=ssrc:162559313 cname:qPTZ+BI+42mgbOi+\r\n
|
||||
a=ssrc:162559313 msid:HWpbmTmXleVSnlssQd80bPuw9cxQFroDkkBP f6188af5-d8d6-462c-9c75-f12bc41fe322\r\n
|
||||
a=ssrc:162559313 mslabel:HWpbmTmXleVSnlssQd80bPuw9cxQFroDkkBP\r\n
|
||||
a=ssrc:162559313 label:f6188af5-d8d6-462c-9c75-f12bc41fe322\r\n
|
||||
m=video 9 UDP/TLS/RTP/SAVPF 100 101 107 116 117 96 97 99 98\r\n
|
||||
c=IN IP4 0.0.0.0\r\n
|
||||
a=rtcp:9 IN IP4 0.0.0.0\r\n
|
||||
a=ice-ufrag:A4by\r\n
|
||||
a=ice-pwd:Gfvb2rbYMiW0dZz8ZkEsXICs\r\n
|
||||
a=fingerprint:sha-256 15:B0:92:1F:C7:40:EE:22:A6:AF:26:EF:EA:FF:37:1D:B3:EF:11:0B:8B:73:4F:01:7D:C9:AE:26:4F:87:E0:95\r\n
|
||||
a=setup:actpass\r\n
|
||||
a=mid:video\r\n
|
||||
a=extmap:2 urn:ietf:params:rtp-hdrext:toffset\r\n
|
||||
a=extmap:3 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time\r\n
|
||||
a=extmap:4 urn:3gpp:video-orientation\r\n
|
||||
a=extmap:5 http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01\r\n
|
||||
a=extmap:6 http://www.webrtc.org/experiments/rtp-hdrext/playout-delay\r\n
|
||||
a=sendrecv\r\n
|
||||
a=rtcp-mux\r\n
|
||||
a=rtcp-rsize\r\n
|
||||
a=rtpmap:100 VP8/90000\r\n
|
||||
a=rtcp-fb:100 ccm fir\r\n
|
||||
a=rtcp-fb:100 nack\r\n
|
||||
a=rtcp-fb:100 nack pli\r\n
|
||||
a=rtcp-fb:100 goog-remb\r\n
|
||||
a=rtcp-fb:100 transport-cc\r\n
|
||||
a=rtpmap:101 VP9/90000\r\n
|
||||
a=rtcp-fb:101 ccm fir\r\n
|
||||
a=rtcp-fb:101 nack\r\n
|
||||
a=rtcp-fb:101 nack pli\r\n
|
||||
a=rtcp-fb:101 goog-remb\r\n
|
||||
a=rtcp-fb:101 transport-cc\r\n
|
||||
a=rtpmap:107 H264/90000\r\n
|
||||
a=rtcp-fb:107 ccm fir\r\n
|
||||
a=rtcp-fb:107 nack\r\n
|
||||
a=rtcp-fb:107 nack pli\r\n
|
||||
a=rtcp-fb:107 goog-remb\r\n
|
||||
a=rtcp-fb:107 transport-cc\r\n
|
||||
a=fmtp:107 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42e01f\r\n
|
||||
a=rtpmap:116 red/90000\r\n
|
||||
a=rtpmap:117 ulpfec/90000\r\n
|
||||
a=rtpmap:96 rtx/90000\r\n
|
||||
a=fmtp:96 apt=100\r\n
|
||||
a=rtpmap:97 rtx/90000\r\n
|
||||
a=fmtp:97 apt=101\r\n
|
||||
a=rtpmap:99 rtx/90000\r\n
|
||||
a=fmtp:99 apt=107\r\n
|
||||
a=rtpmap:98 rtx/90000\r\n
|
||||
a=fmtp:98 apt=116\r\n
|
||||
a=ssrc-group:FID 3156517279 2673335628\r\n
|
||||
a=ssrc:3156517279 cname:qPTZ+BI+42mgbOi+\r\n
|
||||
a=ssrc:3156517279 msid:HWpbmTmXleVSnlssQd80bPuw9cxQFroDkkBP b6ec5178-c611-403f-bbec-3833ed547c09\r\n
|
||||
a=ssrc:3156517279 mslabel:HWpbmTmXleVSnlssQd80bPuw9cxQFroDkkBP\r\n
|
||||
a=ssrc:3156517279 label:b6ec5178-c611-403f-bbec-3833ed547c09\r\n
|
||||
a=ssrc:2673335628 cname:qPTZ+BI+42mgbOi+\r\n
|
||||
a=ssrc:2673335628 msid:HWpbmTmXleVSnlssQd80bPuw9cxQFroDkkBP b6ec5178-c611-403f-bbec-3833ed547c09\r\n
|
||||
a=ssrc:2673335628 mslabel:HWpbmTmXleVSnlssQd80bPuw9cxQFroDkkBP\r\n
|
||||
a=ssrc:2673335628 label:b6ec5178-c611-403f-bbec-3833ed547c09\r\n";
|
||||
let parsed_sdp = webrtc_sdp::parse_sdp(sdp, true).unwrap();
|
||||
assert!(!parsed_sdp.to_string().contains("\r\n\r\n"));
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user