зеркало из https://github.com/mozilla/gecko-dev.git
Backed out changeset b6559295ac78 (bug 1553011) for bustages on StaticAnalysisFunctions.h. CLOSED TREE
--HG-- rename : media/webrtc/signaling/src/sdp/rsdparsa/examples/sdps/10.sdp => media/webrtc/signaling/src/sdp/rsdparsa/src/bin/sdps/10.sdp rename : media/webrtc/signaling/src/sdp/rsdparsa/examples/sdps/11.sdp => media/webrtc/signaling/src/sdp/rsdparsa/src/bin/sdps/11.sdp rename : media/webrtc/signaling/src/sdp/rsdparsa/examples/sdps/12.sdp => media/webrtc/signaling/src/sdp/rsdparsa/src/bin/sdps/12.sdp rename : media/webrtc/signaling/src/sdp/rsdparsa/examples/sdps/13.sdp => media/webrtc/signaling/src/sdp/rsdparsa/src/bin/sdps/13.sdp rename : media/webrtc/signaling/src/sdp/rsdparsa/examples/sdps/14.sdp => media/webrtc/signaling/src/sdp/rsdparsa/src/bin/sdps/14.sdp rename : media/webrtc/signaling/src/sdp/rsdparsa/examples/sdps/15.sdp => media/webrtc/signaling/src/sdp/rsdparsa/src/bin/sdps/15.sdp rename : media/webrtc/signaling/src/sdp/rsdparsa/examples/sdps/16.sdp => media/webrtc/signaling/src/sdp/rsdparsa/src/bin/sdps/16.sdp rename : media/webrtc/signaling/src/sdp/rsdparsa/examples/sdps/17.sdp => media/webrtc/signaling/src/sdp/rsdparsa/src/bin/sdps/17.sdp rename : media/webrtc/signaling/src/sdp/rsdparsa/examples/sdps/18.sdp => media/webrtc/signaling/src/sdp/rsdparsa/src/bin/sdps/18.sdp rename : media/webrtc/signaling/src/sdp/rsdparsa/examples/sdps/19.sdp => media/webrtc/signaling/src/sdp/rsdparsa/src/bin/sdps/19.sdp rename : media/webrtc/signaling/src/sdp/rsdparsa/examples/sdps/2.sdp => media/webrtc/signaling/src/sdp/rsdparsa/src/bin/sdps/2.sdp rename : media/webrtc/signaling/src/sdp/rsdparsa/examples/sdps/20.sdp => media/webrtc/signaling/src/sdp/rsdparsa/src/bin/sdps/20.sdp rename : media/webrtc/signaling/src/sdp/rsdparsa/examples/sdps/21.sdp => media/webrtc/signaling/src/sdp/rsdparsa/src/bin/sdps/21.sdp rename : media/webrtc/signaling/src/sdp/rsdparsa/examples/sdps/22.sdp => media/webrtc/signaling/src/sdp/rsdparsa/src/bin/sdps/22.sdp rename : media/webrtc/signaling/src/sdp/rsdparsa/examples/sdps/23.sdp => media/webrtc/signaling/src/sdp/rsdparsa/src/bin/sdps/23.sdp rename : media/webrtc/signaling/src/sdp/rsdparsa/examples/sdps/24.sdp => media/webrtc/signaling/src/sdp/rsdparsa/src/bin/sdps/24.sdp rename : media/webrtc/signaling/src/sdp/rsdparsa/examples/sdps/25.sdp => media/webrtc/signaling/src/sdp/rsdparsa/src/bin/sdps/25.sdp rename : media/webrtc/signaling/src/sdp/rsdparsa/examples/sdps/26.sdp => media/webrtc/signaling/src/sdp/rsdparsa/src/bin/sdps/26.sdp rename : media/webrtc/signaling/src/sdp/rsdparsa/examples/sdps/27.sdp => media/webrtc/signaling/src/sdp/rsdparsa/src/bin/sdps/27.sdp rename : media/webrtc/signaling/src/sdp/rsdparsa/examples/sdps/28.sdp => media/webrtc/signaling/src/sdp/rsdparsa/src/bin/sdps/28.sdp rename : media/webrtc/signaling/src/sdp/rsdparsa/examples/sdps/29.sdp => media/webrtc/signaling/src/sdp/rsdparsa/src/bin/sdps/29.sdp rename : media/webrtc/signaling/src/sdp/rsdparsa/examples/sdps/3.sdp => media/webrtc/signaling/src/sdp/rsdparsa/src/bin/sdps/3.sdp rename : media/webrtc/signaling/src/sdp/rsdparsa/examples/sdps/30.sdp => media/webrtc/signaling/src/sdp/rsdparsa/src/bin/sdps/30.sdp rename : media/webrtc/signaling/src/sdp/rsdparsa/examples/sdps/31.sdp => media/webrtc/signaling/src/sdp/rsdparsa/src/bin/sdps/31.sdp rename : media/webrtc/signaling/src/sdp/rsdparsa/examples/sdps/32.sdp => media/webrtc/signaling/src/sdp/rsdparsa/src/bin/sdps/32.sdp rename : media/webrtc/signaling/src/sdp/rsdparsa/examples/sdps/33.sdp => media/webrtc/signaling/src/sdp/rsdparsa/src/bin/sdps/33.sdp rename : media/webrtc/signaling/src/sdp/rsdparsa/examples/sdps/36.sdp => media/webrtc/signaling/src/sdp/rsdparsa/src/bin/sdps/34.sdp rename : media/webrtc/signaling/src/sdp/rsdparsa/examples/sdps/37.sdp => media/webrtc/signaling/src/sdp/rsdparsa/src/bin/sdps/37.sdp rename : media/webrtc/signaling/src/sdp/rsdparsa/examples/sdps/38.sdp => media/webrtc/signaling/src/sdp/rsdparsa/src/bin/sdps/38.sdp rename : media/webrtc/signaling/src/sdp/rsdparsa/examples/sdps/40.sdp => media/webrtc/signaling/src/sdp/rsdparsa/src/bin/sdps/39.sdp rename : media/webrtc/signaling/src/sdp/rsdparsa/examples/sdps/4.sdp => media/webrtc/signaling/src/sdp/rsdparsa/src/bin/sdps/4.sdp rename : media/webrtc/signaling/src/sdp/rsdparsa/examples/sdps/41.sdp => media/webrtc/signaling/src/sdp/rsdparsa/src/bin/sdps/41.sdp rename : media/webrtc/signaling/src/sdp/rsdparsa/examples/sdps/5.sdp => media/webrtc/signaling/src/sdp/rsdparsa/src/bin/sdps/5.sdp rename : media/webrtc/signaling/src/sdp/rsdparsa/examples/sdps/6.sdp => media/webrtc/signaling/src/sdp/rsdparsa/src/bin/sdps/6.sdp rename : media/webrtc/signaling/src/sdp/rsdparsa/examples/sdps/7.sdp => media/webrtc/signaling/src/sdp/rsdparsa/src/bin/sdps/7.sdp rename : media/webrtc/signaling/src/sdp/rsdparsa/examples/sdps/8.sdp => media/webrtc/signaling/src/sdp/rsdparsa/src/bin/sdps/8.sdp rename : media/webrtc/signaling/src/sdp/rsdparsa/examples/sdps/9.sdp => media/webrtc/signaling/src/sdp/rsdparsa/src/bin/sdps/9.sdp rename : media/webrtc/signaling/src/sdp/rsdparsa/examples/sdps/extract.sh => media/webrtc/signaling/src/sdp/rsdparsa/src/bin/sdps/extract.sh
This commit is contained in:
Родитель
cbcf79e7fd
Коммит
1ad559bb39
|
@ -2466,6 +2466,15 @@ dependencies = [
|
|||
"serde 1.0.88 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rsdparsa"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.88 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive 1.0.88 (git+https://github.com/servo/serde?branch=deserialize_from_enums10)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rsdparsa_capi"
|
||||
version = "0.1.0"
|
||||
|
@ -2473,7 +2482,7 @@ dependencies = [
|
|||
"libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"nserror 0.1.0",
|
||||
"webrtc-sdp 0.1.0",
|
||||
"rsdparsa 0.1.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -3429,16 +3438,6 @@ dependencies = [
|
|||
"nom 4.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "webrtc-sdp"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.88 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive 1.0.88 (git+https://github.com/servo/serde?branch=deserialize_from_enums10)",
|
||||
"serde_json 1.0.26 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "which"
|
||||
version = "1.0.3"
|
||||
|
|
|
@ -4015,22 +4015,12 @@ TEST(NewSdpTestNoFixture, CheckParsingResultComparer)
|
|||
auto check_comparison = [](const std::string sdp_string) {
|
||||
SipccSdpParser sipccParser;
|
||||
RsdparsaSdpParser rustParser;
|
||||
auto print_errors = [](const SdpErrorHolder& holder, const char* name) {
|
||||
for (const auto& e : holder.GetParseErrors()) {
|
||||
std::cerr << name << " Line " << e.first << ": " << e.second;
|
||||
}
|
||||
};
|
||||
|
||||
auto sipccSdp = sipccParser.Parse(sdp_string);
|
||||
print_errors(sipccParser, "sipcc");
|
||||
|
||||
auto rustSdp = rustParser.Parse(sdp_string);
|
||||
print_errors(rustParser, "webrtc-sdp");
|
||||
|
||||
ParsingResultComparer comparer;
|
||||
return sipccSdp && rustSdp
|
||||
? comparer.Compare(*rustSdp, *sipccSdp, sdp_string)
|
||||
: false;
|
||||
return comparer.Compare(*rustSdp, *sipccSdp, sdp_string);
|
||||
};
|
||||
|
||||
ASSERT_TRUE(check_comparison(kBasicAudioVideoOffer));
|
||||
|
|
|
@ -45,7 +45,7 @@ bool ParsingResultComparer::Compare(const Sdp& rsdparsaSdp, const Sdp& sipccSdp,
|
|||
const std::string& originalSdp,
|
||||
const SdpComparisonResult expect) {
|
||||
mOriginalSdp = originalSdp;
|
||||
MOZ_ASSERT(&rsdparsaSdp);
|
||||
|
||||
const std::string sipccSdpStr = sipccSdp.ToString();
|
||||
const std::string rsdparsaSdpStr = rsdparsaSdp.ToString();
|
||||
|
||||
|
|
|
@ -60,9 +60,6 @@ enum class RustSdpProtocolValue {
|
|||
kRustDtlsSctp,
|
||||
kRustUdpDtlsSctp,
|
||||
kRustTcpDtlsSctp,
|
||||
kRustRtpAvp,
|
||||
kRustRtpAvpf,
|
||||
kRustRtpSavp,
|
||||
};
|
||||
|
||||
enum class RustSdpFormatType { kRustIntegers, kRustStrings };
|
||||
|
|
|
@ -77,13 +77,8 @@ SdpMediaSection::Protocol RsdparsaSdpMediaSection::GetProtocol() const {
|
|||
return kUdpDtlsSctp;
|
||||
case RustSdpProtocolValue::kRustTcpDtlsSctp:
|
||||
return kTcpDtlsSctp;
|
||||
case RustSdpProtocolValue::kRustRtpAvp:
|
||||
return kRtpAvp;
|
||||
case RustSdpProtocolValue::kRustRtpAvpf:
|
||||
return kRtpAvpf;
|
||||
case RustSdpProtocolValue::kRustRtpSavp:
|
||||
return kRtpSavp;
|
||||
}
|
||||
|
||||
MOZ_CRASH("invalid media protocol");
|
||||
}
|
||||
|
||||
|
|
|
@ -19,8 +19,8 @@ namespace mozilla {
|
|||
|
||||
UniquePtr<Sdp> RsdparsaSdpParser::Parse(const std::string& sdpText) {
|
||||
ClearParseErrors();
|
||||
RustSdpSession* result = nullptr;
|
||||
RustSdpError* err = nullptr;
|
||||
RustSdpSession* result;
|
||||
RustSdpError* err;
|
||||
StringView sdpTextView{sdpText.c_str(), sdpText.length()};
|
||||
nsresult rv = parse_sdp(sdpTextView, false, &result, &err);
|
||||
if (rv != NS_OK) {
|
||||
|
|
|
@ -3,11 +3,9 @@ cache: cargo
|
|||
sudo: true
|
||||
os:
|
||||
- linux
|
||||
- osx
|
||||
# Taken out temporarily because it's to slow
|
||||
# - osx
|
||||
|
||||
env:
|
||||
- FEATURES=""
|
||||
- FEATURES="serialize"
|
||||
rust:
|
||||
- nightly
|
||||
- beta
|
||||
|
@ -19,12 +17,13 @@ matrix:
|
|||
allow_failures:
|
||||
- rust: nightly
|
||||
|
||||
before_install:
|
||||
- sudo apt-get update
|
||||
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- libcurl4-openssl-dev
|
||||
- zlib1g-dev
|
||||
- libiberty-dev
|
||||
- libelf-dev
|
||||
- libdw-dev
|
||||
- cmake
|
||||
|
@ -35,46 +34,34 @@ addons:
|
|||
before_script:
|
||||
- export PATH=$PATH:~/.cargo/bin
|
||||
- |
|
||||
if [[ "$TRAVIS_RUST_VERSION" == "stable" ]]; then
|
||||
rustup component add rustfmt-preview
|
||||
rustup component add clippy
|
||||
if [[ "$TRAVIS_RUST_VERSION" == "nightly" ]]; then
|
||||
cargo install --force clippy;
|
||||
fi
|
||||
|
||||
script:
|
||||
- echo FEATURES="$FEATURES"
|
||||
- cargo build --verbose --all
|
||||
- |
|
||||
if [[ "$TRAVIS_RUST_VERSION" == "stable" ]]; then
|
||||
cargo fmt --all -- --check
|
||||
if [[ "$TRAVIS_RUST_VERSION" == "nightly" &&
|
||||
-f ~/.cargo/bin/cargo-clippy ]]; then
|
||||
cargo clippy;
|
||||
fi
|
||||
- cargo build --verbose --all --features="$FEATURES"
|
||||
- |
|
||||
if [[ "$TRAVIS_RUST_VERSION" == "stable" ]]; then
|
||||
cargo clippy --all-targets --all-features -- -D warnings;
|
||||
fi
|
||||
- |
|
||||
if [[ "$TRAVIS_RUST_VERSION" == "1.17.0" ]]; then
|
||||
cargo test --all-features --verbose --all
|
||||
else
|
||||
cargo test --all-targets --all-features --verbose --all
|
||||
fi
|
||||
|
||||
- cargo test --verbose --all
|
||||
|
||||
after_success:
|
||||
- |
|
||||
if [[ "$TRAVIS_OS_NAME" == "linux" && "$TRAVIS_RUST_VERSION" == "stable" && "$FEATURES" == "serialize" ]]; then
|
||||
wget https://github.com/SimonKagstrom/kcov/archive/v34.tar.gz &&
|
||||
tar xzf v34.tar.gz &&
|
||||
cd kcov-34 &&
|
||||
if [[ "$TRAVIS_OS_NAME" == "linux" && "$TRAVIS_RUST_VERSION" == "stable" ]]; then
|
||||
wget https://github.com/SimonKagstrom/kcov/archive/master.tar.gz &&
|
||||
tar xzf master.tar.gz &&
|
||||
cd kcov-master &&
|
||||
mkdir build &&
|
||||
cd build &&
|
||||
cmake .. &&
|
||||
make &&
|
||||
sudo make install &&
|
||||
cd ../.. &&
|
||||
rm -rf kcov-34 &&
|
||||
rm -rf kcov-master &&
|
||||
kcov --version &&
|
||||
(cd target/debug/ && ls -al) &&
|
||||
for file in target/debug/webrtc_sdp-*[^\.d]; do echo "$file"; mkdir -p "target/cov/$(basename $file)"; kcov --verify --exclude-pattern=/.cargo,/usr/lib "target/cov/$(basename $file)" "$file"; done &&
|
||||
for file in target/debug/rsdparsa-*[^\.d]; do echo "$file"; mkdir -p "target/cov/$(basename $file)"; kcov --verify --exclude-pattern=/.cargo,/usr/lib "target/cov/$(basename $file)" "$file"; done &&
|
||||
for file in target/debug/unit_tests-*[^\.d]; do echo "$file"; mkdir -p "target/cov/$(basename $file)"; kcov --verify --exclude-pattern=/.cargo,/usr/lib "target/cov/$(basename $file)" "$file"; done &&
|
||||
bash <(curl -s https://codecov.io/bash) &&
|
||||
echo "Uploaded code coverage"
|
||||
|
|
|
@ -1,17 +1,7 @@
|
|||
[package]
|
||||
name = "webrtc-sdp"
|
||||
name = "rsdparsa"
|
||||
version = "0.1.0"
|
||||
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."
|
||||
homepage = "https://github.com/nils-ohlmeier/rsdparsa"
|
||||
readme = "README.md"
|
||||
keywords = ["webrtc", "sdp", "jsep"]
|
||||
categories = ["parsing", "network-programming"]
|
||||
license = "MPL-2.0"
|
||||
|
||||
[badges]
|
||||
travis-ci = { repository = "nils-ohlmeier/rsdparsa", branch = "master" }
|
||||
codecov = { repository = "nils-ohlmeier/rsdparsa", branch = "master", service = "github" }
|
||||
|
||||
[features]
|
||||
default = []
|
||||
|
@ -19,9 +9,10 @@ default = []
|
|||
serialize = ["serde", "serde_derive"]
|
||||
|
||||
[dependencies]
|
||||
log = {version = "0.4.6"}
|
||||
# clippy = {version = "*", optional = true}
|
||||
log = "0.4"
|
||||
serde = {version = "1.0" , optional = true}
|
||||
serde_derive = {version = "1.0" , optional = true}
|
||||
|
||||
[dev-dependencies]
|
||||
serde_json = {version = "1.0"}
|
||||
# serde_json = {version = "1.0"}
|
||||
|
|
|
@ -1,61 +1,13 @@
|
|||
# webrtc-sdp
|
||||
# rsdparsa
|
||||
|
||||
[![Crates.io](https://img.shields.io/crates/v/webrtc-sdp.svg)](https://crates.io/crates/webrtc-sdp)
|
||||
[![Build Status](https://travis-ci.org/nils-ohlmeier/rsdparsa.svg?branch=master)](https://travis-ci.org/nils-ohlmeier/rsdparsa)
|
||||
[![Codecov coverage status](https://codecov.io/gh/nils-ohlmeier/rsdparsa/branch/master/graph/badge.svg)](https://codecov.io/gh/nils-ohlmeier/rsdparsa)
|
||||
[![License: MPL 2.0](https://img.shields.io/badge/License-MPL%202.0-brightgreen.svg)](#License)
|
||||
[![dependency status](https://deps.rs/repo/github/nils-ohlmeier/rsdparsa/status.svg)](https://deps.rs/repo/github/nils-ohlmeier/rsdparsa)
|
||||
|
||||
A SDP parser written in Rust specifically aimed to handle WebRTC SDP offers and answers.
|
||||
A SDP parser written in Rust specifically aimed for WebRTC
|
||||
|
||||
## Dependecies
|
||||
|
||||
* Rust >= 1.30.0
|
||||
* log module
|
||||
* serde module
|
||||
* serde-derive module
|
||||
|
||||
Cargo installs the missing modules automatically when building webrtc-sdp for the first time.
|
||||
|
||||
## The webrtc-sdp API
|
||||
|
||||
The main function is:
|
||||
```
|
||||
fn parse_sdp(sdp: &str, fail_on_warning: bool) -> Result<SdpSession, SdpParserError>
|
||||
```
|
||||
The `sdp` parameter is the string which will get parsed. The `fail_on_warning` parameter determines how to treat warnings encountered during parsing. Any problems encountered during are stored until the whole string has been parsed. Any problem during parsing falls into two catgeories:
|
||||
|
||||
* Fatal error preventing further parsing or processing of the SDP
|
||||
* Warning which don't block further processing of the SDP
|
||||
|
||||
Warnings will be for example unknown parameters in attributes. Setting `fail_on_warning` to `true` makes most sense during development, when you want to be aware of all potential problems. In production `fail_on_warning` is expected to be `false`.
|
||||
|
||||
`parse_sdp()` returns either an `SdpSession` struct ([code](https://github.com/nils-ohlmeier/rsdparsa/blob/master/src/lib.rs#L137)) which contains all the parsed information. Or in case a fatal error was encountered (or if `fail_on_warning` was set to `true` and any warnings were encountered) an `SdpParserError` ([code](https://github.com/nils-ohlmeier/rsdparsa/blob/master/src/error.rs#L117)) will be returned as a `Result`.
|
||||
|
||||
## Examples
|
||||
|
||||
The [file parser](https://github.com/nils-ohlmeier/rsdparsa/blob/master/examples/file_parser.rs) in the webrtc-sdp package gives you an easy example of how to invoke the webrtc-sdp parser.
|
||||
|
||||
## Contributing
|
||||
|
||||
As the Travis CI runs are checking for code formating and clippy warnings please run the following commands locally, before submitting a Pull Request.
|
||||
|
||||
If you haven't clippy and Rust format installed already you add them like this:
|
||||
```
|
||||
rustup component add rustfmt-preview
|
||||
rustup component add clippy
|
||||
```
|
||||
|
||||
Check with clippy for warnings in the code:
|
||||
```
|
||||
cargo clippy --all-targets --all-features
|
||||
```
|
||||
|
||||
And format all of the code according to Rust code style convention:
|
||||
```
|
||||
cargo fmt --all
|
||||
```
|
||||
Requires minimum Rust 1.17
|
||||
|
||||
## License
|
||||
|
||||
Licensed under [MPL-2.0](https://www.mozilla.org/MPL/2.0/)
|
||||
Licensed under [MPL](https://www.mozilla.org/MPL/2.0/).
|
||||
|
|
|
@ -1,262 +0,0 @@
|
|||
use std::collections::HashMap;
|
||||
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
|
||||
use std::num::Wrapping;
|
||||
|
||||
pub trait AnonymizingClone {
|
||||
fn masked_clone(&self, anon: &mut StatefulSdpAnonymizer) -> Self;
|
||||
}
|
||||
|
||||
pub trait ToBytesVec {
|
||||
fn to_byte_vec(&self) -> Vec<u8>;
|
||||
}
|
||||
|
||||
impl ToBytesVec for u64 {
|
||||
fn to_byte_vec(&self) -> Vec<u8> {
|
||||
let mut bytes = Vec::new();
|
||||
let mut val = *self;
|
||||
for _ in 0..8 {
|
||||
bytes.push(val as u8);
|
||||
val <<= 8;
|
||||
}
|
||||
bytes.reverse();
|
||||
bytes
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Anonymizes SDP in a stateful fashion, such that a pre-anonymized value will
|
||||
* always be transformed into the same anonymized value within the context of
|
||||
* the anonymizer.
|
||||
* Stores the opaque state necessary for intelligent anonymization of SDP. This
|
||||
* state can be stored and reused during the offer-answer period, and it
|
||||
* will maintain a stable set of masked values.
|
||||
*/
|
||||
pub struct StatefulSdpAnonymizer {
|
||||
ips: HashMap<IpAddr, IpAddr>,
|
||||
ip_v4_inc: Wrapping<u32>,
|
||||
ip_v6_inc: Wrapping<u128>,
|
||||
ports: HashMap<u32, u32>,
|
||||
port_inc: Wrapping<u32>,
|
||||
origin_users: AnonymizationStrMap,
|
||||
ice_passwords: AnonymizationStrMap,
|
||||
ice_users: AnonymizationStrMap,
|
||||
cert_finger_prints: HashMap<Vec<u8>, Vec<u8>>,
|
||||
cert_finger_print_inc: Wrapping<u64>,
|
||||
}
|
||||
|
||||
impl Default for StatefulSdpAnonymizer {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
impl StatefulSdpAnonymizer {
|
||||
pub fn new() -> Self {
|
||||
StatefulSdpAnonymizer {
|
||||
ips: HashMap::new(),
|
||||
ip_v4_inc: Wrapping(0),
|
||||
ip_v6_inc: Wrapping(0),
|
||||
ports: HashMap::new(),
|
||||
port_inc: Wrapping(0),
|
||||
origin_users: AnonymizationStrMap::new("origin-user-", 8),
|
||||
ice_passwords: AnonymizationStrMap::new("ice-password-", 8),
|
||||
ice_users: AnonymizationStrMap::new("ice-user-", 8),
|
||||
cert_finger_prints: HashMap::new(),
|
||||
cert_finger_print_inc: Wrapping(0),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn mask_ip(&mut self, addr: &IpAddr) -> IpAddr {
|
||||
if let Some(address) = self.ips.get(addr) {
|
||||
return *address;
|
||||
}
|
||||
let mapped = match addr {
|
||||
IpAddr::V4(_) => {
|
||||
self.ip_v4_inc += Wrapping(1);
|
||||
IpAddr::V4(Ipv4Addr::from(self.ip_v4_inc.0))
|
||||
}
|
||||
IpAddr::V6(_) => {
|
||||
self.ip_v6_inc += Wrapping(1);
|
||||
IpAddr::V6(Ipv6Addr::from(self.ip_v6_inc.0))
|
||||
}
|
||||
};
|
||||
self.ips.insert(*addr, mapped);
|
||||
mapped
|
||||
}
|
||||
|
||||
pub fn mask_port(&mut self, port: u32) -> u32 {
|
||||
if let Some(stored) = self.ports.get(&port) {
|
||||
return *stored;
|
||||
}
|
||||
self.port_inc += Wrapping(1);
|
||||
self.ports.insert(port, self.port_inc.0);
|
||||
self.port_inc.0
|
||||
}
|
||||
|
||||
pub fn mask_origin_user(&mut self, user: &str) -> String {
|
||||
self.origin_users.mask(user)
|
||||
}
|
||||
|
||||
pub fn mask_ice_password(&mut self, password: &str) -> String {
|
||||
self.ice_passwords.mask(password)
|
||||
}
|
||||
|
||||
pub fn mask_ice_user(&mut self, user: &str) -> String {
|
||||
self.ice_users.mask(user)
|
||||
}
|
||||
|
||||
pub fn mask_cert_finger_print(&mut self, finger_print: &[u8]) -> Vec<u8> {
|
||||
if let Some(stored) = self.cert_finger_prints.get(finger_print) {
|
||||
return stored.clone();
|
||||
}
|
||||
self.cert_finger_print_inc += Wrapping(1);
|
||||
self.cert_finger_prints.insert(
|
||||
finger_print.to_vec(),
|
||||
self.cert_finger_print_inc.0.to_byte_vec(),
|
||||
);
|
||||
self.cert_finger_print_inc.0.to_byte_vec()
|
||||
}
|
||||
}
|
||||
|
||||
struct AnonymizationStrMap {
|
||||
map: HashMap<String, String>,
|
||||
counter: Wrapping<u64>,
|
||||
prefix: &'static str,
|
||||
padding: usize,
|
||||
}
|
||||
|
||||
impl AnonymizationStrMap {
|
||||
pub fn new(prefix: &'static str, padding: usize) -> Self {
|
||||
Self {
|
||||
map: HashMap::new(),
|
||||
counter: Wrapping(0),
|
||||
prefix,
|
||||
padding,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn mask(&mut self, value: &str) -> String {
|
||||
let key = value.to_owned();
|
||||
if let Some(stored) = self.map.get(&key) {
|
||||
return stored.clone();
|
||||
}
|
||||
self.counter += Wrapping(1);
|
||||
let store = format!(
|
||||
"{}{:0padding$}",
|
||||
self.prefix,
|
||||
self.counter.0,
|
||||
padding = self.padding
|
||||
);
|
||||
self.map.insert(key, store.clone());
|
||||
store
|
||||
}
|
||||
}
|
||||
|
||||
#[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]);
|
||||
}
|
||||
}
|
||||
}
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -1,31 +1,35 @@
|
|||
use std::env;
|
||||
use std::error::Error;
|
||||
use std::fs::File;
|
||||
use std::io::prelude::*;
|
||||
use std::fs::File;
|
||||
use std::path::Path;
|
||||
extern crate webrtc_sdp;
|
||||
use std::env;
|
||||
extern crate rsdparsa;
|
||||
|
||||
fn main() {
|
||||
let filename = match env::args().nth(1) {
|
||||
None => {
|
||||
println!("Missing file name argument!");
|
||||
return;
|
||||
}
|
||||
},
|
||||
Some(x) => x,
|
||||
};
|
||||
let path = Path::new(filename.as_str());
|
||||
let display = path.display();
|
||||
|
||||
let mut file = match File::open(&path) {
|
||||
Err(why) => panic!("Failed to open {}: {}", display, why.description()),
|
||||
Ok(file) => file,
|
||||
Err(why) => panic!("Failed to open {}: {}",
|
||||
display,
|
||||
why.description()),
|
||||
Ok(file) => file
|
||||
};
|
||||
|
||||
let mut s = String::new();
|
||||
match file.read_to_string(&mut s) {
|
||||
Err(why) => panic!("couldn't read {}: {}", display, why.description()),
|
||||
Ok(s) => s,
|
||||
Err(why) => panic!("couldn't read {}: {}",
|
||||
display,
|
||||
why.description()),
|
||||
Ok(s) => s
|
||||
};
|
||||
|
||||
assert!(webrtc_sdp::parse_sdp(&s, true).is_ok());
|
||||
rsdparsa::parse_sdp(&s, true).is_ok();
|
||||
}
|
|
@ -1,11 +1,12 @@
|
|||
#[cfg(feature = "serialize")]
|
||||
use serde::ser::{Serialize, SerializeStruct, Serializer};
|
||||
use std::num::ParseIntError;
|
||||
use std::num::ParseFloatError;
|
||||
use std::net::AddrParseError;
|
||||
use std::fmt;
|
||||
use std::error;
|
||||
use std::error::Error;
|
||||
use std::fmt;
|
||||
use std::net::AddrParseError;
|
||||
use std::num::ParseFloatError;
|
||||
use std::num::ParseIntError;
|
||||
#[cfg(feature = "serialize")]
|
||||
use serde::ser::{Serializer, Serialize, SerializeStruct};
|
||||
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum SdpParserInternalError {
|
||||
|
@ -41,15 +42,15 @@ impl fmt::Display for SdpParserInternalError {
|
|||
impl error::Error for SdpParserInternalError {
|
||||
fn description(&self) -> &str {
|
||||
match *self {
|
||||
SdpParserInternalError::Generic(ref message)
|
||||
| SdpParserInternalError::Unsupported(ref message) => message,
|
||||
SdpParserInternalError::Generic(ref message) |
|
||||
SdpParserInternalError::Unsupported(ref message) => message,
|
||||
SdpParserInternalError::Integer(ref error) => error.description(),
|
||||
SdpParserInternalError::Float(ref error) => error.description(),
|
||||
SdpParserInternalError::Address(ref error) => error.description(),
|
||||
}
|
||||
}
|
||||
|
||||
fn source(&self) -> Option<&(dyn error::Error + 'static)> {
|
||||
fn cause(&self) -> Option<&error::Error> {
|
||||
match *self {
|
||||
SdpParserInternalError::Integer(ref error) => Some(error),
|
||||
SdpParserInternalError::Float(ref error) => Some(error),
|
||||
|
@ -60,6 +61,51 @@ impl error::Error for SdpParserInternalError {
|
|||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_sdp_parser_internal_error_generic() {
|
||||
let generic = SdpParserInternalError::Generic("generic message".to_string());
|
||||
assert_eq!(format!("{}", generic),
|
||||
"Generic parsing error: generic message");
|
||||
assert_eq!(generic.description(), "generic message");
|
||||
assert!(generic.cause().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_eq!(unsupported.description(), "unsupported internal message");
|
||||
assert!(unsupported.cause().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_eq!(int_err.description(), "invalid digit found in string");
|
||||
assert!(!int_err.cause().is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_sdp_parser_internal_error_address() {
|
||||
let v = "127.0.0.a";
|
||||
use std::str::FromStr;
|
||||
use std::net::IpAddr;
|
||||
let addr = IpAddr::from_str(v);
|
||||
assert!(addr.is_err());
|
||||
let addr_err = SdpParserInternalError::Address(addr.err().unwrap());
|
||||
assert_eq!(format!("{}", addr_err),
|
||||
"IP address parsing error: invalid IP address syntax");
|
||||
assert_eq!(addr_err.description(), "invalid IP address syntax");
|
||||
assert!(!addr_err.cause().is_none());
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum SdpParserError {
|
||||
Line {
|
||||
|
@ -72,57 +118,37 @@ pub enum SdpParserError {
|
|||
line: String,
|
||||
line_number: usize,
|
||||
},
|
||||
Sequence {
|
||||
message: String,
|
||||
line_number: usize,
|
||||
},
|
||||
Sequence { message: String, line_number: usize },
|
||||
}
|
||||
|
||||
#[cfg(feature = "serialize")]
|
||||
impl Serialize for SdpParserError {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: Serializer,
|
||||
{
|
||||
let mut state = serializer.serialize_struct(
|
||||
"error",
|
||||
match *self {
|
||||
SdpParserError::Sequence { .. } => 3,
|
||||
_ => 4,
|
||||
},
|
||||
)?;
|
||||
match *self {
|
||||
SdpParserError::Line {
|
||||
ref error,
|
||||
ref line,
|
||||
..
|
||||
} => {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer {
|
||||
let mut state = serializer.serialize_struct("error", match self {
|
||||
&SdpParserError::Sequence{..} => 3,
|
||||
_ => 4
|
||||
})?;
|
||||
match self {
|
||||
&SdpParserError::Line {ref error, ref line, ..} => {
|
||||
state.serialize_field("type", "Line")?;
|
||||
state.serialize_field("message", &format!("{}", error))?;
|
||||
state.serialize_field("line", &line)?
|
||||
}
|
||||
SdpParserError::Unsupported {
|
||||
ref error,
|
||||
ref line,
|
||||
..
|
||||
} => {
|
||||
},
|
||||
&SdpParserError::Unsupported {ref error, ref line, ..} => {
|
||||
state.serialize_field("type", "Unsupported")?;
|
||||
state.serialize_field("message", &format!("{}", error))?;
|
||||
state.serialize_field("line", &line)?
|
||||
}
|
||||
SdpParserError::Sequence { ref message, .. } => {
|
||||
},
|
||||
&SdpParserError::Sequence {ref message, ..} => {
|
||||
state.serialize_field("type", "Sequence")?;
|
||||
state.serialize_field("message", &message)?;
|
||||
}
|
||||
};
|
||||
state.serialize_field(
|
||||
"line_number",
|
||||
&match *self {
|
||||
SdpParserError::Line { line_number, .. } => line_number,
|
||||
SdpParserError::Unsupported { line_number, .. } => line_number,
|
||||
SdpParserError::Sequence { line_number, .. } => line_number,
|
||||
},
|
||||
)?;
|
||||
state.serialize_field("line_number", &match self {
|
||||
&SdpParserError::Line {line_number, ..} => line_number,
|
||||
&SdpParserError::Unsupported {line_number, ..} => line_number,
|
||||
&SdpParserError::Sequence {line_number, ..} => line_number,
|
||||
})?;
|
||||
state.end()
|
||||
}
|
||||
}
|
||||
|
@ -134,24 +160,24 @@ impl fmt::Display for SdpParserError {
|
|||
ref error,
|
||||
ref line,
|
||||
ref line_number,
|
||||
} => write!(
|
||||
f,
|
||||
"Line error: {} in line({}): {}",
|
||||
error.description(),
|
||||
line_number,
|
||||
line
|
||||
),
|
||||
} => {
|
||||
write!(f,
|
||||
"Line error: {} in line({}): {}",
|
||||
error.description(),
|
||||
line_number,
|
||||
line)
|
||||
}
|
||||
SdpParserError::Unsupported {
|
||||
ref error,
|
||||
ref line,
|
||||
ref line_number,
|
||||
} => write!(
|
||||
f,
|
||||
"Unsupported: {} in line({}): {}",
|
||||
error.description(),
|
||||
line_number,
|
||||
line
|
||||
),
|
||||
} => {
|
||||
write!(f,
|
||||
"Unsupported: {} in line({}): {}",
|
||||
error.description(),
|
||||
line_number,
|
||||
line)
|
||||
}
|
||||
SdpParserError::Sequence {
|
||||
ref message,
|
||||
ref line_number,
|
||||
|
@ -160,19 +186,20 @@ impl fmt::Display for SdpParserError {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
impl error::Error for SdpParserError {
|
||||
fn description(&self) -> &str {
|
||||
match *self {
|
||||
SdpParserError::Line { ref error, .. }
|
||||
| SdpParserError::Unsupported { ref error, .. } => error.description(),
|
||||
SdpParserError::Line { ref error, .. } |
|
||||
SdpParserError::Unsupported { ref error, .. } => error.description(),
|
||||
SdpParserError::Sequence { ref message, .. } => message,
|
||||
}
|
||||
}
|
||||
|
||||
fn source(&self) -> Option<&(dyn error::Error + 'static)> {
|
||||
fn cause(&self) -> Option<&error::Error> {
|
||||
match *self {
|
||||
SdpParserError::Line { ref error, .. }
|
||||
| SdpParserError::Unsupported { ref error, .. } => Some(error),
|
||||
SdpParserError::Line { ref error, .. } |
|
||||
SdpParserError::Unsupported { ref error, .. } => Some(error),
|
||||
// Can't tell much more about our internal errors
|
||||
_ => None,
|
||||
}
|
||||
|
@ -197,118 +224,40 @@ impl From<ParseFloatError> for SdpParserInternalError {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_sdp_parser_internal_error_generic() {
|
||||
let generic = SdpParserInternalError::Generic("generic message".to_string());
|
||||
assert_eq!(
|
||||
format!("{}", generic),
|
||||
"Generic parsing error: generic message"
|
||||
);
|
||||
assert_eq!(generic.description(), "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_eq!(unsupported.description(), "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_eq!(int_err.description(), "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_eq!(int_err.description(), "invalid float literal");
|
||||
assert!(!int_err.source().is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_sdp_parser_internal_error_address() {
|
||||
let v = "127.0.0.a";
|
||||
use std::net::IpAddr;
|
||||
use std::str::FromStr;
|
||||
let addr = IpAddr::from_str(v);
|
||||
assert!(addr.is_err());
|
||||
let addr_err = SdpParserInternalError::Address(addr.err().unwrap());
|
||||
assert_eq!(
|
||||
format!("{}", addr_err),
|
||||
"IP address parsing error: invalid IP address syntax"
|
||||
);
|
||||
assert_eq!(addr_err.description(), "invalid IP address syntax");
|
||||
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: test message in line(13): test line"
|
||||
);
|
||||
assert_eq!(line1.description(), "test message");
|
||||
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: unsupported value in line(21): unsupported line"
|
||||
);
|
||||
assert_eq!(unsupported1.description(), "unsupported value");
|
||||
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_eq!(sequence1.description(), "sequence message");
|
||||
assert!(sequence1.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: test message in line(13): test line");
|
||||
assert_eq!(line1.description(), "test message");
|
||||
assert!(line1.cause().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: unsupported value in line(21): unsupported line");
|
||||
assert_eq!(unsupported1.description(), "unsupported value");
|
||||
assert!(unsupported1.cause().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_eq!(sequence1.description(), "sequence message");
|
||||
assert!(sequence1.cause().is_none());
|
||||
}
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -1,84 +1,80 @@
|
|||
use std::net::IpAddr;
|
||||
use std::str::FromStr;
|
||||
use std::fmt;
|
||||
use std::net::IpAddr;
|
||||
|
||||
use error::SdpParserInternalError;
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||
pub enum SdpAddressType {
|
||||
#[derive(Clone,Copy,Debug,PartialEq)]
|
||||
pub enum SdpAddrType {
|
||||
IP4 = 4,
|
||||
IP6 = 6,
|
||||
}
|
||||
|
||||
impl SdpAddressType {
|
||||
pub fn same_protocol(self, addr: &IpAddr) -> bool {
|
||||
(addr.is_ipv6() && self == SdpAddressType::IP6)
|
||||
|| (addr.is_ipv4() && self == SdpAddressType::IP4)
|
||||
impl SdpAddrType {
|
||||
pub fn same_protocol(&self, addr: &IpAddr) -> bool {
|
||||
(addr.is_ipv6() && *self == SdpAddrType::IP6) ||
|
||||
(addr.is_ipv4() && *self == SdpAddrType::IP4)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn address_to_string(addr: IpAddr) -> String {
|
||||
match addr {
|
||||
IpAddr::V4(ipv4) => format!("IN IP4 {}", ipv4.to_string()),
|
||||
IpAddr::V6(ipv6) => format!("IN IP6 {}", ipv6.to_string()),
|
||||
impl fmt::Display for SdpAddrType {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
let printable = match *self {
|
||||
SdpAddrType::IP4 => "Ip4",
|
||||
SdpAddrType::IP6 => "Ip6",
|
||||
};
|
||||
write!(f, "{}", printable)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn parse_network_type(value: &str) -> Result<(), SdpParserInternalError> {
|
||||
pub fn parse_nettype(value: &str) -> Result<(), SdpParserInternalError> {
|
||||
if value.to_uppercase() != "IN" {
|
||||
return Err(SdpParserInternalError::Generic(
|
||||
"nettype needs to be IN".to_string(),
|
||||
));
|
||||
return Err(SdpParserInternalError::Generic("nettype needs to be IN".to_string()));
|
||||
};
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn parse_address_type(value: &str) -> Result<SdpAddressType, SdpParserInternalError> {
|
||||
Ok(match value.to_uppercase().as_ref() {
|
||||
"IP4" => SdpAddressType::IP4,
|
||||
"IP6" => SdpAddressType::IP6,
|
||||
_ => {
|
||||
return Err(SdpParserInternalError::Generic(
|
||||
"address type needs to be IP4 or IP6".to_string(),
|
||||
));
|
||||
}
|
||||
})
|
||||
#[test]
|
||||
fn test_parse_nettype() {
|
||||
let internet = parse_nettype("iN");
|
||||
assert!(internet.is_ok());
|
||||
|
||||
assert!(parse_nettype("").is_err());
|
||||
assert!(parse_nettype("FOO").is_err());
|
||||
}
|
||||
|
||||
pub fn parse_unicast_address(value: &str) -> Result<IpAddr, SdpParserInternalError> {
|
||||
pub fn parse_addrtype(value: &str) -> Result<SdpAddrType, SdpParserInternalError> {
|
||||
Ok(match value.to_uppercase().as_ref() {
|
||||
"IP4" => SdpAddrType::IP4,
|
||||
"IP6" => SdpAddrType::IP6,
|
||||
_ => {
|
||||
return Err(SdpParserInternalError::Generic("address type needs to be IP4 or IP6"
|
||||
.to_string()))
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_addrtype() {
|
||||
let ip4 = parse_addrtype("iP4");
|
||||
assert!(ip4.is_ok());
|
||||
assert_eq!(ip4.unwrap(), SdpAddrType::IP4);
|
||||
let ip6 = parse_addrtype("Ip6");
|
||||
assert!(ip6.is_ok());
|
||||
assert_eq!(ip6.unwrap(), SdpAddrType::IP6);
|
||||
|
||||
assert!(parse_addrtype("").is_err());
|
||||
assert!(parse_addrtype("IP5").is_err());
|
||||
}
|
||||
|
||||
pub fn parse_unicast_addr(value: &str) -> Result<IpAddr, SdpParserInternalError> {
|
||||
Ok(IpAddr::from_str(value)?)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_parse_network_type() {
|
||||
let internet = parse_network_type("iN");
|
||||
assert!(internet.is_ok());
|
||||
|
||||
assert!(parse_network_type("").is_err());
|
||||
assert!(parse_network_type("FOO").is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_address_type() {
|
||||
let ip4 = parse_address_type("iP4");
|
||||
assert!(ip4.is_ok());
|
||||
assert_eq!(ip4.unwrap(), SdpAddressType::IP4);
|
||||
let ip6 = parse_address_type("Ip6");
|
||||
assert!(ip6.is_ok());
|
||||
assert_eq!(ip6.unwrap(), SdpAddressType::IP6);
|
||||
|
||||
assert!(parse_address_type("").is_err());
|
||||
assert!(parse_address_type("IP5").is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_unicast_address() {
|
||||
let ip4 = parse_unicast_address("127.0.0.1");
|
||||
assert!(ip4.is_ok());
|
||||
let ip6 = parse_unicast_address("::1");
|
||||
assert!(ip6.is_ok());
|
||||
}
|
||||
#[test]
|
||||
fn test_parse_unicast_addr() {
|
||||
let ip4 = parse_unicast_addr("127.0.0.1");
|
||||
assert!(ip4.is_ok());
|
||||
let ip6 = parse_unicast_addr("::1");
|
||||
assert!(ip6.is_ok());
|
||||
}
|
||||
|
|
|
@ -0,0 +1,74 @@
|
|||
use error::SdpParserInternalError;
|
||||
use SdpType;
|
||||
|
||||
pub fn parse_repeat(value: &str) -> Result<SdpType, SdpParserInternalError> {
|
||||
// TODO implement this if it's ever needed
|
||||
Err(SdpParserInternalError::Unsupported(format!("unsupported type repeat: {} ", value)))
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_repeat_works() {
|
||||
// FIXME use a proper r value here
|
||||
assert!(parse_repeat("0 0").is_err());
|
||||
}
|
||||
|
||||
pub fn parse_zone(value: &str) -> Result<SdpType, SdpParserInternalError> {
|
||||
// TODO implement this if it's ever needed
|
||||
Err(SdpParserInternalError::Unsupported(format!("unsupported type zone: {}", value)))
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_zone_works() {
|
||||
// FIXME use a proper z value here
|
||||
assert!(parse_zone("0 0").is_err());
|
||||
}
|
||||
|
||||
pub fn parse_key(value: &str) -> Result<SdpType, SdpParserInternalError> {
|
||||
// TODO implement this if it's ever needed
|
||||
Err(SdpParserInternalError::Unsupported(format!("unsupported type key: {}", value)))
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_keys_works() {
|
||||
// FIXME use a proper k value here
|
||||
assert!(parse_key("12345").is_err());
|
||||
}
|
||||
|
||||
pub fn parse_information(value: &str) -> Result<SdpType, SdpParserInternalError> {
|
||||
Err(SdpParserInternalError::Unsupported(format!("unsupported type information: {}", value)))
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_information_works() {
|
||||
assert!(parse_information("foobar").is_err());
|
||||
}
|
||||
|
||||
pub fn parse_uri(value: &str) -> Result<SdpType, SdpParserInternalError> {
|
||||
// TODO check if this is really a URI
|
||||
Err(SdpParserInternalError::Unsupported(format!("unsupported type uri: {}", value)))
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_uri_works() {
|
||||
assert!(parse_uri("http://www.mozilla.org").is_err());
|
||||
}
|
||||
|
||||
pub fn parse_email(value: &str) -> Result<SdpType, SdpParserInternalError> {
|
||||
// TODO check if this is really an email address
|
||||
Err(SdpParserInternalError::Unsupported(format!("unsupported type email: {}", value)))
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_email_works() {
|
||||
assert!(parse_email("nils@mozilla.com").is_err());
|
||||
}
|
||||
|
||||
pub fn parse_phone(value: &str) -> Result<SdpType, SdpParserInternalError> {
|
||||
// TODO check if this is really a phone number
|
||||
Err(SdpParserInternalError::Unsupported(format!("unsupported type phone: {}", value)))
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_phone_works() {
|
||||
assert!(parse_phone("+123456789").is_err());
|
||||
}
|
|
@ -1,53 +1,33 @@
|
|||
extern crate webrtc_sdp;
|
||||
|
||||
#[cfg(test)]
|
||||
fn check_parse_and_serialize(sdp_str: &str) {
|
||||
let parsed_sdp = webrtc_sdp::parse_sdp(sdp_str, true);
|
||||
assert!(parsed_sdp.is_ok());
|
||||
let serialized_sdp = parsed_sdp.unwrap().to_string();
|
||||
assert_eq!(serialized_sdp, sdp_str)
|
||||
}
|
||||
extern crate rsdparsa;
|
||||
|
||||
#[test]
|
||||
fn parse_minimal_sdp() {
|
||||
let sdp_str = "v=0\r\n\
|
||||
o=- 1 1 IN IP4 0.0.0.0\r\n\
|
||||
s=-\r\n\
|
||||
t=0 0\r\n\
|
||||
c=IN IP4 0.0.0.0\r\n\
|
||||
m=audio 0 UDP/TLS/RTP/SAVPF 0\r\n";
|
||||
let sdp_res = webrtc_sdp::parse_sdp(sdp_str, true);
|
||||
let sdp = "v=0\r\n
|
||||
o=- 0 0 IN IP4 0.0.0.0\r\n
|
||||
s=-\r\n
|
||||
c=IN IP4 0.0.0.0\r\n
|
||||
t=0 0\r\n
|
||||
m=audio 0 UDP/TLS/RTP/SAVPF 0\r\n";
|
||||
let sdp_res = rsdparsa::parse_sdp(sdp, true);
|
||||
assert!(sdp_res.is_ok());
|
||||
let sdp_opt = sdp_res.ok();
|
||||
assert!(sdp_opt.is_some());
|
||||
let sdp = sdp_opt.unwrap();
|
||||
assert_eq!(sdp.get_version(), 0);
|
||||
let o = sdp.get_origin();
|
||||
assert_eq!(o.username, "-");
|
||||
assert_eq!(o.session_id, 1);
|
||||
assert_eq!(o.session_version, 1);
|
||||
assert_eq!(sdp.get_session(), "-");
|
||||
assert!(sdp.timing.is_some());
|
||||
assert!(sdp.get_connection().is_some());
|
||||
assert_eq!(sdp.version, 0);
|
||||
assert_eq!(sdp.session, "-");
|
||||
assert!(sdp.connection.is_some());
|
||||
assert_eq!(sdp.attribute.len(), 0);
|
||||
assert_eq!(sdp.media.len(), 1);
|
||||
|
||||
let msection = &(sdp.media[0]);
|
||||
assert_eq!(
|
||||
*msection.get_type(),
|
||||
webrtc_sdp::media_type::SdpMediaValue::Audio
|
||||
);
|
||||
assert_eq!(*msection.get_type(),
|
||||
rsdparsa::media_type::SdpMediaValue::Audio);
|
||||
assert_eq!(msection.get_port(), 0);
|
||||
assert_eq!(msection.get_port_count(), 0);
|
||||
assert_eq!(
|
||||
*msection.get_proto(),
|
||||
webrtc_sdp::media_type::SdpProtocolValue::UdpTlsRtpSavpf
|
||||
);
|
||||
assert_eq!(*msection.get_proto(),
|
||||
rsdparsa::media_type::SdpProtocolValue::UdpTlsRtpSavpf);
|
||||
assert!(msection.get_attributes().is_empty());
|
||||
assert!(msection.get_bandwidth().is_empty());
|
||||
assert!(msection.get_connection().is_none());
|
||||
|
||||
check_parse_and_serialize(sdp_str);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -60,29 +40,28 @@ s=-\r\n
|
|||
c=IN IP4 0.0.0.0\r\n
|
||||
t=0 0\r\n
|
||||
m=audio 0 UDP/TLS/RTP/SAVPF 0\r\n";
|
||||
let sdp_res = webrtc_sdp::parse_sdp(sdp, false);
|
||||
let sdp_res = rsdparsa::parse_sdp(sdp, false);
|
||||
assert!(sdp_res.is_ok());
|
||||
let sdp_opt = sdp_res.ok();
|
||||
assert!(sdp_opt.is_some());
|
||||
let sdp = sdp_opt.unwrap();
|
||||
assert_eq!(sdp.get_version(), 0);
|
||||
assert_eq!(sdp.get_session(), "-");
|
||||
assert_eq!(sdp.version, 0);
|
||||
assert_eq!(sdp.session, "-");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_minimal_sdp_with_most_session_types() {
|
||||
let sdp_str = "v=0\r\n\
|
||||
o=- 0 0 IN IP4 0.0.0.0\r\n\
|
||||
s=-\r\n\
|
||||
t=0 0\r\n\
|
||||
b=AS:1\r\n\
|
||||
b=CT:123\r\n\
|
||||
b=TIAS:12345\r\n\
|
||||
b=UNKNOWN:9\r\n\
|
||||
c=IN IP6 ::1/1/1\r\n\
|
||||
a=ice-options:trickle\r\n\
|
||||
m=audio 0 UDP/TLS/RTP/SAVPF 0\r\n";
|
||||
let sdp_res = webrtc_sdp::parse_sdp(sdp_str, false);
|
||||
let sdp = "v=0\r\n
|
||||
o=- 0 0 IN IP4 0.0.0.0\r\n
|
||||
s=-\r\n
|
||||
t=0 0\r\n
|
||||
b=AS:1\r\n
|
||||
b=CT:123\r\n
|
||||
b=TIAS:12345\r\n
|
||||
c=IN IP4 0.0.0.0\r\n
|
||||
a=ice-options:trickle\r\n
|
||||
m=audio 0 UDP/TLS/RTP/SAVPF 0\r\n";
|
||||
let sdp_res = rsdparsa::parse_sdp(sdp, false);
|
||||
assert!(sdp_res.is_ok());
|
||||
let sdp_opt = sdp_res.ok();
|
||||
assert!(sdp_opt.is_some());
|
||||
|
@ -90,23 +69,21 @@ fn parse_minimal_sdp_with_most_session_types() {
|
|||
assert_eq!(sdp.version, 0);
|
||||
assert_eq!(sdp.session, "-");
|
||||
assert!(sdp.get_connection().is_some());
|
||||
|
||||
check_parse_and_serialize(sdp_str);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_minimal_sdp_with_most_media_types() {
|
||||
let sdp_str = "v=0\r\n\
|
||||
o=- 0 0 IN IP4 0.0.0.0\r\n\
|
||||
s=-\r\n\
|
||||
t=0 0\r\n\
|
||||
m=video 0 UDP/TLS/RTP/SAVPF 0\r\n\
|
||||
b=AS:1\r\n\
|
||||
b=CT:123\r\n\
|
||||
b=TIAS:12345\r\n\
|
||||
c=IN IP4 0.0.0.0\r\n\
|
||||
a=sendrecv\r\n";
|
||||
let sdp_res = webrtc_sdp::parse_sdp(sdp_str, false);
|
||||
let 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=video 0 UDP/TLS/RTP/SAVPF 0\r\n
|
||||
b=AS:1\r\n
|
||||
b=CT:123\r\n
|
||||
b=TIAS:12345\r\n
|
||||
c=IN IP4 0.0.0.0\r\n
|
||||
a=sendrecv\r\n";
|
||||
let sdp_res = rsdparsa::parse_sdp(sdp, false);
|
||||
assert!(sdp_res.is_ok());
|
||||
let sdp_opt = sdp_res.ok();
|
||||
assert!(sdp_opt.is_some());
|
||||
|
@ -117,52 +94,44 @@ fn parse_minimal_sdp_with_most_media_types() {
|
|||
assert_eq!(sdp.media.len(), 1);
|
||||
|
||||
let msection = &(sdp.media[0]);
|
||||
assert_eq!(
|
||||
*msection.get_type(),
|
||||
webrtc_sdp::media_type::SdpMediaValue::Video
|
||||
);
|
||||
assert_eq!(*msection.get_type(),
|
||||
rsdparsa::media_type::SdpMediaValue::Video);
|
||||
assert_eq!(msection.get_port(), 0);
|
||||
assert_eq!(
|
||||
*msection.get_proto(),
|
||||
webrtc_sdp::media_type::SdpProtocolValue::UdpTlsRtpSavpf
|
||||
);
|
||||
assert_eq!(*msection.get_proto(),
|
||||
rsdparsa::media_type::SdpProtocolValue::UdpTlsRtpSavpf);
|
||||
assert!(!msection.get_bandwidth().is_empty());
|
||||
assert!(!msection.get_connection().is_none());
|
||||
assert!(!msection.get_attributes().is_empty());
|
||||
assert!(msection
|
||||
.get_attribute(webrtc_sdp::attribute_type::SdpAttributeType::Sendrecv)
|
||||
.is_some());
|
||||
|
||||
check_parse_and_serialize(sdp_str);
|
||||
assert!(msection.get_attribute(rsdparsa::attribute_type::SdpAttributeType::Sendrecv).is_some());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_firefox_audio_offer() {
|
||||
let sdp_str = "v=0\r\n\
|
||||
o=mozilla...THIS_IS_SDPARTA-52.0a1 506705521068071134 0 IN IP4 0.0.0.0\r\n\
|
||||
s=-\r\n\
|
||||
t=0 0\r\n\
|
||||
a=fingerprint:sha-256 CD:34:D1:62:16:95:7B:B7:EB:74:E2:39:27:97:EB:0B:23:73:AC:BC:BF:2F:E3:91:CB:57:A9:9D:4A:A2:0B:40\r\n\
|
||||
a=group:BUNDLE sdparta_0\r\n\
|
||||
a=ice-options:trickle\r\n\
|
||||
a=msid-semantic:WMS *\r\n\
|
||||
m=audio 9 UDP/TLS/RTP/SAVPF 109 9 0 8\r\n\
|
||||
c=IN IP4 0.0.0.0\r\n\
|
||||
a=sendrecv\r\n\
|
||||
a=extmap:1/sendonly urn:ietf:params:rtp-hdrext:ssrc-audio-level\r\n\
|
||||
a=fmtp:109 maxplaybackrate=48000;stereo=1;useinbandfec=1\r\n\
|
||||
a=ice-pwd:e3baa26dd2fa5030d881d385f1e36cce\r\n\
|
||||
a=ice-ufrag:58b99ead\r\n\
|
||||
a=mid:sdparta_0\r\n\
|
||||
a=msid:{5a990edd-0568-ac40-8d97-310fc33f3411} {218cfa1c-617d-2249-9997-60929ce4c405}\r\n\
|
||||
a=rtcp-mux\r\n\
|
||||
a=rtpmap:109 opus/48000/2\r\n\
|
||||
a=rtpmap:9 G722/8000/1\r\n\
|
||||
a=rtpmap:0 PCMU/8000\r\n\
|
||||
a=rtpmap:8 PCMA/8000\r\n\
|
||||
a=setup:actpass\r\n\
|
||||
let sdp = "v=0\r\n
|
||||
o=mozilla...THIS_IS_SDPARTA-52.0a1 506705521068071134 0 IN IP4 0.0.0.0\r\n
|
||||
s=-\r\n
|
||||
t=0 0\r\n
|
||||
a=fingerprint:sha-256 CD:34:D1:62:16:95:7B:B7:EB:74:E2:39:27:97:EB:0B:23:73:AC:BC:BF:2F:E3:91:CB:57:A9:9D:4A:A2:0B:40\r\n
|
||||
a=group:BUNDLE sdparta_0\r\n
|
||||
a=ice-options:trickle\r\n
|
||||
a=msid-semantic:WMS *\r\n
|
||||
m=audio 9 UDP/TLS/RTP/SAVPF 109 9 0 8\r\n
|
||||
c=IN IP4 0.0.0.0\r\n
|
||||
a=sendrecv\r\n
|
||||
a=extmap:1/sendonly urn:ietf:params:rtp-hdrext:ssrc-audio-level\r\n
|
||||
a=fmtp:109 maxplaybackrate=48000;stereo=1;useinbandfec=1\r\n
|
||||
a=ice-pwd:e3baa26dd2fa5030d881d385f1e36cce\r\n
|
||||
a=ice-ufrag:58b99ead\r\n
|
||||
a=mid:sdparta_0\r\n
|
||||
a=msid:{5a990edd-0568-ac40-8d97-310fc33f3411} {218cfa1c-617d-2249-9997-60929ce4c405}\r\n
|
||||
a=rtcp-mux\r\n
|
||||
a=rtpmap:109 opus/48000/2\r\n
|
||||
a=rtpmap:9 G722/8000/1\r\n
|
||||
a=rtpmap:0 PCMU/8000\r\n
|
||||
a=rtpmap:8 PCMA/8000\r\n
|
||||
a=setup:actpass\r\n
|
||||
a=ssrc:2655508255 cname:{735484ea-4f6c-f74a-bd66-7425f8476c2e}\r\n";
|
||||
let sdp_res = webrtc_sdp::parse_sdp(sdp_str, true);
|
||||
let sdp_res = rsdparsa::parse_sdp(sdp, true);
|
||||
assert!(sdp_res.is_ok());
|
||||
let sdp_opt = sdp_res.ok();
|
||||
assert!(sdp_opt.is_some());
|
||||
|
@ -171,98 +140,66 @@ a=ssrc:2655508255 cname:{735484ea-4f6c-f74a-bd66-7425f8476c2e}\r\n";
|
|||
assert_eq!(sdp.media.len(), 1);
|
||||
|
||||
let msection = &(sdp.media[0]);
|
||||
assert_eq!(
|
||||
*msection.get_type(),
|
||||
webrtc_sdp::media_type::SdpMediaValue::Audio
|
||||
);
|
||||
assert_eq!(*msection.get_type(),
|
||||
rsdparsa::media_type::SdpMediaValue::Audio);
|
||||
assert_eq!(msection.get_port(), 9);
|
||||
assert_eq!(msection.get_port_count(), 0);
|
||||
assert_eq!(
|
||||
*msection.get_proto(),
|
||||
webrtc_sdp::media_type::SdpProtocolValue::UdpTlsRtpSavpf
|
||||
);
|
||||
assert_eq!(*msection.get_proto(),
|
||||
rsdparsa::media_type::SdpProtocolValue::UdpTlsRtpSavpf);
|
||||
assert!(msection.get_connection().is_some());
|
||||
assert!(msection.get_bandwidth().is_empty());
|
||||
assert!(!msection.get_attributes().is_empty());
|
||||
assert!(msection
|
||||
.get_attribute(webrtc_sdp::attribute_type::SdpAttributeType::Sendrecv)
|
||||
.is_some());
|
||||
assert!(msection
|
||||
.get_attribute(webrtc_sdp::attribute_type::SdpAttributeType::Extmap)
|
||||
.is_some());
|
||||
assert!(msection
|
||||
.get_attribute(webrtc_sdp::attribute_type::SdpAttributeType::Fmtp)
|
||||
.is_some());
|
||||
assert!(msection
|
||||
.get_attribute(webrtc_sdp::attribute_type::SdpAttributeType::IcePwd)
|
||||
.is_some());
|
||||
assert!(msection
|
||||
.get_attribute(webrtc_sdp::attribute_type::SdpAttributeType::IceUfrag)
|
||||
.is_some());
|
||||
assert!(msection
|
||||
.get_attribute(webrtc_sdp::attribute_type::SdpAttributeType::Mid)
|
||||
.is_some());
|
||||
assert!(msection
|
||||
.get_attribute(webrtc_sdp::attribute_type::SdpAttributeType::Mid)
|
||||
.is_some());
|
||||
assert!(msection
|
||||
.get_attribute(webrtc_sdp::attribute_type::SdpAttributeType::Msid)
|
||||
.is_some());
|
||||
assert!(msection
|
||||
.get_attribute(webrtc_sdp::attribute_type::SdpAttributeType::RtcpMux)
|
||||
.is_some());
|
||||
assert_eq!(
|
||||
msection
|
||||
.get_attributes_of_type(webrtc_sdp::attribute_type::SdpAttributeType::Rtpmap)
|
||||
.len(),
|
||||
4
|
||||
);
|
||||
assert!(msection
|
||||
.get_attribute(webrtc_sdp::attribute_type::SdpAttributeType::Setup)
|
||||
.is_some());
|
||||
assert!(msection
|
||||
.get_attribute(webrtc_sdp::attribute_type::SdpAttributeType::Ssrc)
|
||||
.is_some());
|
||||
assert!(msection.get_attribute(rsdparsa::attribute_type::SdpAttributeType::Sendrecv).is_some());
|
||||
assert!(msection.get_attribute(rsdparsa::attribute_type::SdpAttributeType::Extmap).is_some());
|
||||
assert!(msection.get_attribute(rsdparsa::attribute_type::SdpAttributeType::Fmtp).is_some());
|
||||
assert!(msection.get_attribute(rsdparsa::attribute_type::SdpAttributeType::IcePwd).is_some());
|
||||
assert!(msection.get_attribute(rsdparsa::attribute_type::SdpAttributeType::IceUfrag).is_some());
|
||||
assert!(msection.get_attribute(rsdparsa::attribute_type::SdpAttributeType::Mid).is_some());
|
||||
assert!(msection.get_attribute(rsdparsa::attribute_type::SdpAttributeType::Mid).is_some());
|
||||
assert!(msection.get_attribute(rsdparsa::attribute_type::SdpAttributeType::Msid).is_some());
|
||||
assert!(msection.get_attribute(rsdparsa::attribute_type::SdpAttributeType::RtcpMux).is_some());
|
||||
assert!(msection.get_attribute(rsdparsa::attribute_type::SdpAttributeType::Rtpmap).is_some());
|
||||
assert!(msection.get_attribute(rsdparsa::attribute_type::SdpAttributeType::Setup).is_some());
|
||||
assert!(msection.get_attribute(rsdparsa::attribute_type::SdpAttributeType::Ssrc).is_some());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_firefox_video_offer() {
|
||||
let sdp_str = "v=0\r\n\
|
||||
o=mozilla...THIS_IS_SDPARTA-52.0a1 506705521068071134 0 IN IP4 0.0.0.0\r\n\
|
||||
s=-\r\n\
|
||||
t=0 0\r\n\
|
||||
a=fingerprint:sha-256 CD:34:D1:62:16:95:7B:B7:EB:74:E2:39:27:97:EB:0B:23:73:AC:BC:BF:2F:E3:91:CB:57:A9:9D:4A:A2:0B:40\r\n\
|
||||
a=group:BUNDLE sdparta_2\r\n\
|
||||
a=ice-options:trickle\r\n\
|
||||
a=msid-semantic:WMS *\r\n\
|
||||
m=video 9 UDP/TLS/RTP/SAVPF 126 120 97\r\n\
|
||||
c=IN IP4 0.0.0.0\r\n\
|
||||
a=recvonly\r\n\
|
||||
a=fmtp:126 profile-level-id=42e01f;level-asymmetry-allowed=1;packetization-mode=1\r\n\
|
||||
a=fmtp:120 max-fs=12288;max-fr=60\r\n\
|
||||
a=fmtp:97 profile-level-id=42e01f;level-asymmetry-allowed=1\r\n\
|
||||
a=ice-pwd:e3baa26dd2fa5030d881d385f1e36cce\r\n\
|
||||
a=ice-ufrag:58b99ead\r\n\
|
||||
a=mid:sdparta_2\r\n\
|
||||
a=rtcp-fb:126 nack\r\n\
|
||||
a=rtcp-fb:126 nack pli\r\n\
|
||||
a=rtcp-fb:126 ccm fir\r\n\
|
||||
a=rtcp-fb:126 goog-remb\r\n\
|
||||
a=rtcp-fb:120 nack\r\n\
|
||||
a=rtcp-fb:120 nack pli\r\n\
|
||||
a=rtcp-fb:120 ccm fir\r\n\
|
||||
a=rtcp-fb:120 goog-remb\r\n\
|
||||
a=rtcp-fb:97 nack\r\n\
|
||||
a=rtcp-fb:97 nack pli\r\n\
|
||||
a=rtcp-fb:97 ccm fir\r\n\
|
||||
a=rtcp-fb:97 goog-remb\r\n\
|
||||
a=rtcp-mux\r\n\
|
||||
a=rtpmap:126 H264/90000\r\n\
|
||||
a=rtpmap:120 VP8/90000\r\n\
|
||||
a=rtpmap:97 H264/90000\r\n\
|
||||
a=setup:actpass\r\n\
|
||||
let sdp = "v=0\r\n
|
||||
o=mozilla...THIS_IS_SDPARTA-52.0a1 506705521068071134 0 IN IP4 0.0.0.0\r\n
|
||||
s=-\r\n
|
||||
t=0 0\r\n
|
||||
a=fingerprint:sha-256 CD:34:D1:62:16:95:7B:B7:EB:74:E2:39:27:97:EB:0B:23:73:AC:BC:BF:2F:E3:91:CB:57:A9:9D:4A:A2:0B:40\r\n
|
||||
a=group:BUNDLE sdparta_2\r\n
|
||||
a=ice-options:trickle\r\n
|
||||
a=msid-semantic:WMS *\r\n
|
||||
m=video 9 UDP/TLS/RTP/SAVPF 126 120 97\r\n
|
||||
c=IN IP4 0.0.0.0\r\n
|
||||
a=recvonly\r\n
|
||||
a=fmtp:126 profile-level-id=42e01f;level-asymmetry-allowed=1;packetization-mode=1\r\n
|
||||
a=fmtp:120 max-fs=12288;max-fr=60\r\n
|
||||
a=fmtp:97 profile-level-id=42e01f;level-asymmetry-allowed=1\r\n
|
||||
a=ice-pwd:e3baa26dd2fa5030d881d385f1e36cce\r\n
|
||||
a=ice-ufrag:58b99ead\r\n
|
||||
a=mid:sdparta_2\r\n
|
||||
a=rtcp-fb:126 nack\r\n
|
||||
a=rtcp-fb:126 nack pli\r\n
|
||||
a=rtcp-fb:126 ccm fir\r\n
|
||||
a=rtcp-fb:126 goog-remb\r\n
|
||||
a=rtcp-fb:120 nack\r\n
|
||||
a=rtcp-fb:120 nack pli\r\n
|
||||
a=rtcp-fb:120 ccm fir\r\n
|
||||
a=rtcp-fb:120 goog-remb\r\n
|
||||
a=rtcp-fb:97 nack\r\n
|
||||
a=rtcp-fb:97 nack pli\r\n
|
||||
a=rtcp-fb:97 ccm fir\r\n
|
||||
a=rtcp-fb:97 goog-remb\r\n
|
||||
a=rtcp-mux\r\n
|
||||
a=rtpmap:126 H264/90000\r\n
|
||||
a=rtpmap:120 VP8/90000\r\n
|
||||
a=rtpmap:97 H264/90000\r\n
|
||||
a=setup:actpass\r\n
|
||||
a=ssrc:2709871439 cname:{735484ea-4f6c-f74a-bd66-7425f8476c2e}";
|
||||
let sdp_res = webrtc_sdp::parse_sdp(sdp_str, true);
|
||||
let sdp_res = rsdparsa::parse_sdp(sdp, true);
|
||||
assert!(sdp_res.is_ok());
|
||||
let sdp_opt = sdp_res.ok();
|
||||
assert!(sdp_opt.is_some());
|
||||
|
@ -271,89 +208,51 @@ a=ssrc:2709871439 cname:{735484ea-4f6c-f74a-bd66-7425f8476c2e}";
|
|||
assert_eq!(sdp.media.len(), 1);
|
||||
|
||||
let msection = &(sdp.media[0]);
|
||||
assert_eq!(
|
||||
*msection.get_type(),
|
||||
webrtc_sdp::media_type::SdpMediaValue::Video
|
||||
);
|
||||
assert_eq!(*msection.get_type(),
|
||||
rsdparsa::media_type::SdpMediaValue::Video);
|
||||
assert_eq!(msection.get_port(), 9);
|
||||
assert_eq!(
|
||||
*msection.get_proto(),
|
||||
webrtc_sdp::media_type::SdpProtocolValue::UdpTlsRtpSavpf
|
||||
);
|
||||
assert_eq!(*msection.get_proto(),
|
||||
rsdparsa::media_type::SdpProtocolValue::UdpTlsRtpSavpf);
|
||||
assert!(msection.get_connection().is_some());
|
||||
assert!(msection.get_bandwidth().is_empty());
|
||||
assert!(!msection.get_attributes().is_empty());
|
||||
assert!(msection
|
||||
.get_attribute(webrtc_sdp::attribute_type::SdpAttributeType::Recvonly)
|
||||
.is_some());
|
||||
assert!(!msection
|
||||
.get_attribute(webrtc_sdp::attribute_type::SdpAttributeType::Extmap)
|
||||
.is_some());
|
||||
assert_eq!(
|
||||
msection
|
||||
.get_attributes_of_type(webrtc_sdp::attribute_type::SdpAttributeType::Fmtp)
|
||||
.len(),
|
||||
3
|
||||
);
|
||||
assert!(msection
|
||||
.get_attribute(webrtc_sdp::attribute_type::SdpAttributeType::IcePwd)
|
||||
.is_some());
|
||||
assert!(msection
|
||||
.get_attribute(webrtc_sdp::attribute_type::SdpAttributeType::IceUfrag)
|
||||
.is_some());
|
||||
assert!(msection
|
||||
.get_attribute(webrtc_sdp::attribute_type::SdpAttributeType::Mid)
|
||||
.is_some());
|
||||
assert!(msection
|
||||
.get_attribute(webrtc_sdp::attribute_type::SdpAttributeType::Mid)
|
||||
.is_some());
|
||||
assert!(!msection
|
||||
.get_attribute(webrtc_sdp::attribute_type::SdpAttributeType::Msid)
|
||||
.is_some());
|
||||
assert_eq!(
|
||||
msection
|
||||
.get_attributes_of_type(webrtc_sdp::attribute_type::SdpAttributeType::Rtcpfb)
|
||||
.len(),
|
||||
12
|
||||
);
|
||||
assert!(msection
|
||||
.get_attribute(webrtc_sdp::attribute_type::SdpAttributeType::RtcpMux)
|
||||
.is_some());
|
||||
assert_eq!(
|
||||
msection
|
||||
.get_attributes_of_type(webrtc_sdp::attribute_type::SdpAttributeType::Rtpmap)
|
||||
.len(),
|
||||
3
|
||||
);
|
||||
assert!(msection
|
||||
.get_attribute(webrtc_sdp::attribute_type::SdpAttributeType::Setup)
|
||||
.is_some());
|
||||
assert!(msection
|
||||
.get_attribute(webrtc_sdp::attribute_type::SdpAttributeType::Ssrc)
|
||||
.is_some());
|
||||
assert!(msection.get_attribute(rsdparsa::attribute_type::SdpAttributeType::Recvonly).is_some());
|
||||
assert!(!msection.get_attribute(rsdparsa::attribute_type::SdpAttributeType::Extmap).is_some());
|
||||
assert!(msection.get_attribute(rsdparsa::attribute_type::SdpAttributeType::Fmtp).is_some());
|
||||
assert!(msection.get_attribute(rsdparsa::attribute_type::SdpAttributeType::IcePwd).is_some());
|
||||
assert!(msection.get_attribute(rsdparsa::attribute_type::SdpAttributeType::IceUfrag).is_some());
|
||||
assert!(msection.get_attribute(rsdparsa::attribute_type::SdpAttributeType::Mid).is_some());
|
||||
assert!(msection.get_attribute(rsdparsa::attribute_type::SdpAttributeType::Mid).is_some());
|
||||
assert!(!msection.get_attribute(rsdparsa::attribute_type::SdpAttributeType::Msid).is_some());
|
||||
assert!(msection.get_attribute(rsdparsa::attribute_type::SdpAttributeType::Rtcpfb).is_some());
|
||||
assert!(msection.get_attribute(rsdparsa::attribute_type::SdpAttributeType::RtcpMux).is_some());
|
||||
assert!(msection.get_attribute(rsdparsa::attribute_type::SdpAttributeType::Rtpmap).is_some());
|
||||
assert!(msection.get_attribute(rsdparsa::attribute_type::SdpAttributeType::Setup).is_some());
|
||||
assert!(msection.get_attribute(rsdparsa::attribute_type::SdpAttributeType::Ssrc).is_some());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_firefox_datachannel_offer() {
|
||||
let sdp_str = "v=0\r\n\
|
||||
o=mozilla...THIS_IS_SDPARTA-52.0a2 3327975756663609975 0 IN IP4 0.0.0.0\r\n\
|
||||
s=-\r\n\
|
||||
t=0 0\r\n\
|
||||
a=sendrecv\r\n\
|
||||
a=fingerprint:sha-256 AC:72:CB:D6:1E:A3:A3:B0:E7:97:77:25:03:4B:5B:FF:19:6C:02:C6:93:7D:EB:5C:81:6F:36:D9:02:32:F8:23\r\n\
|
||||
a=ice-options:trickle\r\n\
|
||||
a=msid-semantic:WMS *\r\n\
|
||||
m=application 49760 DTLS/SCTP 5000\r\n\
|
||||
c=IN IP4 172.16.156.106\r\n\
|
||||
a=candidate:0 1 UDP 2122252543 172.16.156.106 49760 typ host\r\n\
|
||||
a=sendrecv\r\n\
|
||||
a=end-of-candidates\r\n\
|
||||
a=ice-pwd:24f485c580129b36447b65df77429a82\r\n\
|
||||
a=ice-ufrag:4cba30fe\r\n\
|
||||
a=mid:sdparta_0\r\n\
|
||||
a=sctpmap:5000 webrtc-datachannel 256\r\n\
|
||||
a=setup:active\r\n\
|
||||
a=ssrc:3376683177 cname:{62f78ee0-620f-a043-86ca-b69f189f1aea}\r\n";
|
||||
let sdp_res = webrtc_sdp::parse_sdp(sdp_str, true);
|
||||
let sdp = "v=0\r\n
|
||||
o=mozilla...THIS_IS_SDPARTA-52.0a2 3327975756663609975 0 IN IP4 0.0.0.0\r\n
|
||||
s=-\r\n
|
||||
t=0 0\r\n
|
||||
a=sendrecv\r\n
|
||||
a=fingerprint:sha-256 AC:72:CB:D6:1E:A3:A3:B0:E7:97:77:25:03:4B:5B:FF:19:6C:02:C6:93:7D:EB:5C:81:6F:36:D9:02:32:F8:23\r\n
|
||||
a=ice-options:trickle\r\n
|
||||
a=msid-semantic:WMS *\r\n
|
||||
m=application 49760 DTLS/SCTP 5000\r\n
|
||||
c=IN IP4 172.16.156.106\r\n
|
||||
a=candidate:0 1 UDP 2122252543 172.16.156.106 49760 typ host\r\n
|
||||
a=sendrecv\r\n
|
||||
a=end-of-candidates\r\n
|
||||
a=ice-pwd:24f485c580129b36447b65df77429a82\r\n
|
||||
a=ice-ufrag:4cba30fe\r\n
|
||||
a=mid:sdparta_0\r\n
|
||||
a=sctpmap:5000 webrtc-datachannel 256\r\n
|
||||
a=setup:active\r\n
|
||||
a=ssrc:3376683177 cname:{62f78ee0-620f-a043-86ca-b69f189f1aea}\r\n";
|
||||
let sdp_res = rsdparsa::parse_sdp(sdp, true);
|
||||
assert!(sdp_res.is_ok());
|
||||
let sdp_opt = sdp_res.ok();
|
||||
assert!(sdp_opt.is_some());
|
||||
|
@ -362,59 +261,27 @@ fn parse_firefox_datachannel_offer() {
|
|||
assert_eq!(sdp.media.len(), 1);
|
||||
|
||||
let msection = &(sdp.media[0]);
|
||||
assert_eq!(
|
||||
*msection.get_type(),
|
||||
webrtc_sdp::media_type::SdpMediaValue::Application
|
||||
);
|
||||
assert_eq!(*msection.get_type(),
|
||||
rsdparsa::media_type::SdpMediaValue::Application);
|
||||
assert_eq!(msection.get_port(), 49760);
|
||||
assert_eq!(
|
||||
*msection.get_proto(),
|
||||
webrtc_sdp::media_type::SdpProtocolValue::DtlsSctp
|
||||
);
|
||||
assert_eq!(*msection.get_proto(),
|
||||
rsdparsa::media_type::SdpProtocolValue::DtlsSctp);
|
||||
assert!(msection.get_connection().is_some());
|
||||
assert!(msection.get_bandwidth().is_empty());
|
||||
assert!(!msection.get_attributes().is_empty());
|
||||
assert!(msection
|
||||
.get_attribute(webrtc_sdp::attribute_type::SdpAttributeType::Sendrecv)
|
||||
.is_some());
|
||||
assert!(!msection
|
||||
.get_attribute(webrtc_sdp::attribute_type::SdpAttributeType::Extmap)
|
||||
.is_some());
|
||||
assert!(msection
|
||||
.get_attribute(webrtc_sdp::attribute_type::SdpAttributeType::IcePwd)
|
||||
.is_some());
|
||||
assert!(msection
|
||||
.get_attribute(webrtc_sdp::attribute_type::SdpAttributeType::IceUfrag)
|
||||
.is_some());
|
||||
assert!(msection
|
||||
.get_attribute(webrtc_sdp::attribute_type::SdpAttributeType::EndOfCandidates)
|
||||
.is_some());
|
||||
assert!(msection
|
||||
.get_attribute(webrtc_sdp::attribute_type::SdpAttributeType::Mid)
|
||||
.is_some());
|
||||
assert!(!msection
|
||||
.get_attribute(webrtc_sdp::attribute_type::SdpAttributeType::Msid)
|
||||
.is_some());
|
||||
assert!(!msection
|
||||
.get_attribute(webrtc_sdp::attribute_type::SdpAttributeType::Rtcpfb)
|
||||
.is_some());
|
||||
assert!(!msection
|
||||
.get_attribute(webrtc_sdp::attribute_type::SdpAttributeType::RtcpMux)
|
||||
.is_some());
|
||||
assert!(!msection
|
||||
.get_attribute(webrtc_sdp::attribute_type::SdpAttributeType::Rtpmap)
|
||||
.is_some());
|
||||
assert!(msection
|
||||
.get_attribute(webrtc_sdp::attribute_type::SdpAttributeType::Sctpmap)
|
||||
.is_some());
|
||||
assert!(msection
|
||||
.get_attribute(webrtc_sdp::attribute_type::SdpAttributeType::Setup)
|
||||
.is_some());
|
||||
assert!(msection
|
||||
.get_attribute(webrtc_sdp::attribute_type::SdpAttributeType::Ssrc)
|
||||
.is_some());
|
||||
|
||||
check_parse_and_serialize(sdp_str);
|
||||
assert!(msection.get_attribute(rsdparsa::attribute_type::SdpAttributeType::Sendrecv).is_some());
|
||||
assert!(!msection.get_attribute(rsdparsa::attribute_type::SdpAttributeType::Extmap).is_some());
|
||||
assert!(msection.get_attribute(rsdparsa::attribute_type::SdpAttributeType::IcePwd).is_some());
|
||||
assert!(msection.get_attribute(rsdparsa::attribute_type::SdpAttributeType::IceUfrag).is_some());
|
||||
assert!(msection.get_attribute(rsdparsa::attribute_type::SdpAttributeType::EndOfCandidates).is_some());
|
||||
assert!(msection.get_attribute(rsdparsa::attribute_type::SdpAttributeType::Mid).is_some());
|
||||
assert!(!msection.get_attribute(rsdparsa::attribute_type::SdpAttributeType::Msid).is_some());
|
||||
assert!(!msection.get_attribute(rsdparsa::attribute_type::SdpAttributeType::Rtcpfb).is_some());
|
||||
assert!(!msection.get_attribute(rsdparsa::attribute_type::SdpAttributeType::RtcpMux).is_some());
|
||||
assert!(!msection.get_attribute(rsdparsa::attribute_type::SdpAttributeType::Rtpmap).is_some());
|
||||
assert!(msection.get_attribute(rsdparsa::attribute_type::SdpAttributeType::Sctpmap).is_some());
|
||||
assert!(msection.get_attribute(rsdparsa::attribute_type::SdpAttributeType::Setup).is_some());
|
||||
assert!(msection.get_attribute(rsdparsa::attribute_type::SdpAttributeType::Ssrc).is_some());
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -506,7 +373,7 @@ 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 sdp_res = webrtc_sdp::parse_sdp(sdp, true);
|
||||
let sdp_res = rsdparsa::parse_sdp(sdp, true);
|
||||
assert!(sdp_res.is_ok());
|
||||
let sdp_opt = sdp_res.ok();
|
||||
assert!(sdp_opt.is_some());
|
||||
|
@ -515,29 +382,21 @@ a=ssrc:2673335628 label:b6ec5178-c611-403f-bbec-3833ed547c09\r\n";
|
|||
assert_eq!(sdp.media.len(), 2);
|
||||
|
||||
let msection1 = &(sdp.media[0]);
|
||||
assert_eq!(
|
||||
*msection1.get_type(),
|
||||
webrtc_sdp::media_type::SdpMediaValue::Audio
|
||||
);
|
||||
assert_eq!(*msection1.get_type(),
|
||||
rsdparsa::media_type::SdpMediaValue::Audio);
|
||||
assert_eq!(msection1.get_port(), 9);
|
||||
assert_eq!(
|
||||
*msection1.get_proto(),
|
||||
webrtc_sdp::media_type::SdpProtocolValue::UdpTlsRtpSavpf
|
||||
);
|
||||
assert_eq!(*msection1.get_proto(),
|
||||
rsdparsa::media_type::SdpProtocolValue::UdpTlsRtpSavpf);
|
||||
assert!(!msection1.get_attributes().is_empty());
|
||||
assert!(msection1.get_connection().is_some());
|
||||
assert!(msection1.get_bandwidth().is_empty());
|
||||
|
||||
let msection2 = &(sdp.media[1]);
|
||||
assert_eq!(
|
||||
*msection2.get_type(),
|
||||
webrtc_sdp::media_type::SdpMediaValue::Video
|
||||
);
|
||||
assert_eq!(*msection2.get_type(),
|
||||
rsdparsa::media_type::SdpMediaValue::Video);
|
||||
assert_eq!(msection2.get_port(), 9);
|
||||
assert_eq!(
|
||||
*msection2.get_proto(),
|
||||
webrtc_sdp::media_type::SdpProtocolValue::UdpTlsRtpSavpf
|
||||
);
|
||||
assert_eq!(*msection2.get_proto(),
|
||||
rsdparsa::media_type::SdpProtocolValue::UdpTlsRtpSavpf);
|
||||
assert!(!msection2.get_attributes().is_empty());
|
||||
assert!(msection2.get_connection().is_some());
|
||||
assert!(msection2.get_bandwidth().is_empty());
|
||||
|
@ -593,7 +452,7 @@ a=setup:actpass\r\n
|
|||
a=simulcast: send rid=foo;bar\r\n
|
||||
a=ssrc:2988475468 cname:{77067f00-2e8d-8b4c-8992-cfe338f56851}\r\n
|
||||
a=ssrc:1649784806 cname:{77067f00-2e8d-8b4c-8992-cfe338f56851}\r\n";
|
||||
let sdp_res = webrtc_sdp::parse_sdp(sdp, true);
|
||||
let sdp_res = rsdparsa::parse_sdp(sdp, true);
|
||||
assert!(sdp_res.is_ok());
|
||||
let sdp_opt = sdp_res.ok();
|
||||
assert!(sdp_opt.is_some());
|
||||
|
@ -604,35 +463,35 @@ a=ssrc:1649784806 cname:{77067f00-2e8d-8b4c-8992-cfe338f56851}\r\n";
|
|||
|
||||
#[test]
|
||||
fn parse_firefox_simulcast_answer() {
|
||||
let sdp_str = "v=0\r\n\
|
||||
o=mozilla...THIS_IS_SDPARTA-55.0a1 7548296603161351381 0 IN IP4 0.0.0.0\r\n\
|
||||
s=-\r\n\
|
||||
t=0 0\r\n\
|
||||
a=fingerprint:sha-256 B1:47:49:4F:7D:83:03:BE:E9:FC:73:A3:FB:33:38:40:0B:3B:6A:56:78:EB:EE:D5:6D:2D:D5:3A:B6:13:97:E7\r\n\
|
||||
a=ice-options:trickle\r\n\
|
||||
a=msid-semantic:WMS *\r\n\
|
||||
m=video 9 UDP/TLS/RTP/SAVPF 120\r\n\
|
||||
c=IN IP4 0.0.0.0\r\n
|
||||
a=recvonly\r\n\
|
||||
a=extmap:1 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time\r\n\
|
||||
a=extmap:2 urn:ietf:params:rtp-hdrext:toffset\r\n\
|
||||
a=fmtp:120 max-fs=12288;max-fr=60\r\n\
|
||||
a=ice-pwd:c886e2caf2ae397446312930cd1afe51\r\n\
|
||||
a=ice-ufrag:f57396c0\r\n\
|
||||
a=mid:sdparta_0\r\n\
|
||||
a=rtcp-fb:120 nack\r\n\
|
||||
a=rtcp-fb:120 nack pli\r\n\
|
||||
a=rtcp-fb:120 ccm fir\r\n\
|
||||
a=rtcp-fb:120 goog-remb\r\n\
|
||||
a=rtcp-mux\r\n\
|
||||
a=rtpmap:120 VP8/90000\r\n\
|
||||
a=setup:active\r\n\
|
||||
a=ssrc:2564157021 cname:{cae1cd32-7433-5b48-8dc8-8e3f8b2f96cd}\r\n\
|
||||
a=simulcast: recv rid=foo;bar\r\n\
|
||||
a=rid:foo recv\r\n\
|
||||
a=rid:bar recv\r\n\
|
||||
a=extmap:3/recvonly urn:ietf:params:rtp-hdrext:sdes:rtp-stream-id\r\n";
|
||||
let sdp_res = webrtc_sdp::parse_sdp(sdp_str, true);
|
||||
let sdp = "v=0\r\n
|
||||
o=mozilla...THIS_IS_SDPARTA-55.0a1 7548296603161351381 0 IN IP4 0.0.0.0\r\n
|
||||
s=-\r\n
|
||||
t=0 0\r\n
|
||||
a=fingerprint:sha-256 B1:47:49:4F:7D:83:03:BE:E9:FC:73:A3:FB:33:38:40:0B:3B:6A:56:78:EB:EE:D5:6D:2D:D5:3A:B6:13:97:E7\r\n
|
||||
a=ice-options:trickle\r\n
|
||||
a=msid-semantic:WMS *\r\n
|
||||
m=video 9 UDP/TLS/RTP/SAVPF 120\r\n
|
||||
c=IN IP4 0.0.0.0\r\n
|
||||
a=recvonly\r\n
|
||||
a=extmap:1 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time\r\n
|
||||
a=extmap:2 urn:ietf:params:rtp-hdrext:toffset\r\n
|
||||
a=fmtp:120 max-fs=12288;max-fr=60\r\n
|
||||
a=ice-pwd:c886e2caf2ae397446312930cd1afe51\r\n
|
||||
a=ice-ufrag:f57396c0\r\n
|
||||
a=mid:sdparta_0\r\n
|
||||
a=rtcp-fb:120 nack\r\n
|
||||
a=rtcp-fb:120 nack pli\r\n
|
||||
a=rtcp-fb:120 ccm fir\r\n
|
||||
a=rtcp-fb:120 goog-remb\r\n
|
||||
a=rtcp-mux\r\n
|
||||
a=rtpmap:120 VP8/90000\r\n
|
||||
a=setup:active\r\n
|
||||
a=ssrc:2564157021 cname:{cae1cd32-7433-5b48-8dc8-8e3f8b2f96cd}\r\n
|
||||
a=simulcast: recv rid=foo;bar\r\n
|
||||
a=rid:foo recv\r\n
|
||||
a=rid:bar recv\r\n
|
||||
a=extmap:3/recvonly urn:ietf:params:rtp-hdrext:sdes:rtp-stream-id\r\n";
|
||||
let sdp_res = rsdparsa::parse_sdp(sdp, true);
|
||||
assert!(sdp_res.is_ok());
|
||||
let sdp_opt = sdp_res.ok();
|
||||
assert!(sdp_opt.is_some());
|
||||
|
@ -640,24 +499,3 @@ fn parse_firefox_simulcast_answer() {
|
|||
assert_eq!(sdp.version, 0);
|
||||
assert_eq!(sdp.media.len(), 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_and_serialize_sdp_with_unusual_attributes() {
|
||||
let sdp_str = "v=0\r\n\
|
||||
o=- 0 0 IN IP6 2001:db8::4444\r\n\
|
||||
s=-\r\n\
|
||||
t=0 0\r\n\
|
||||
m=video 0 UDP/TLS/RTP/SAVPF 0\r\n\
|
||||
b=UNSUPPORTED:12345\r\n\
|
||||
c=IN IP6 ::1\r\n\
|
||||
a=rtcp:9 IN IP6 2001:db8::8888\r\n\
|
||||
a=rtcp-fb:* nack\r\n\
|
||||
a=extmap:1/recvonly urn:ietf:params:rtp-hdrext:toffset\r\n\
|
||||
a=extmap:2/sendonly urn:ietf:params:rtp-hdrext:toffset\r\n\
|
||||
a=extmap:3/sendrecv urn:ietf:params:rtp-hdrext:toffset\r\n\
|
||||
a=imageattr:* send [x=330,y=250,sar=[1.1,1.3,1.9],q=0.1] recv [x=800,y=[50,80,30],sar=1.1]\r\n\
|
||||
a=imageattr:97 send [x=[480:16:800],y=[100,200,300],par=[1.2-1.3],q=0.6] [x=1080,y=[144:176],sar=[0.5-0.7]] recv *\r\n\
|
||||
a=sendrecv\r\n";
|
||||
|
||||
check_parse_and_serialize(sdp_str);
|
||||
}
|
||||
|
|
|
@ -7,5 +7,5 @@ authors = ["Paul Ellenbogen <pe5@cs.princeton.edu>",
|
|||
[dependencies]
|
||||
libc = "^0.2.0"
|
||||
log = "0.4"
|
||||
rsdparsa = {package = "webrtc-sdp", version = "0.1.0", path = "../rsdparsa"}
|
||||
rsdparsa = {version = "0.1.0", path = "../rsdparsa"}
|
||||
nserror = { path = "../../../../../../xpcom/rust/nserror" }
|
||||
|
|
|
@ -1076,7 +1076,7 @@ pub unsafe extern "C" fn sdp_get_candidates(attributes: *const Vec<SdpAttribute>
|
|||
let attr_strings: Vec<String> = (*attributes).iter().filter_map( |x| {
|
||||
if let SdpAttribute::Candidate(ref attr) = *x {
|
||||
// The serialized attribute starts with "candidate:...", this needs to be removed
|
||||
Some(attr.to_string())
|
||||
Some(attr.to_string()[10..].to_string())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
|
|
|
@ -16,7 +16,6 @@ use rsdparsa::{SdpTiming, SdpBandwidth, SdpSession};
|
|||
use rsdparsa::error::SdpParserError;
|
||||
use rsdparsa::media_type::{SdpMediaValue, SdpProtocolValue};
|
||||
use rsdparsa::attribute_type::{SdpAttribute};
|
||||
use rsdparsa::anonymizer::{StatefulSdpAnonymizer, AnonymizingClone};
|
||||
|
||||
pub mod types;
|
||||
pub mod network;
|
||||
|
@ -46,10 +45,10 @@ pub unsafe extern "C" fn parse_sdp(sdp: StringView,
|
|||
|
||||
let parser_result = rsdparsa::parse_sdp(&sdp_str, fail_on_warning);
|
||||
match parser_result {
|
||||
Ok(mut parsed) => {
|
||||
Ok(parsed) => {
|
||||
*error = match parsed.warnings.len(){
|
||||
0 => ptr::null(),
|
||||
_ => Box::into_raw(Box::new(parsed.warnings.remove(0))),
|
||||
_ => Box::into_raw(Box::new(parsed.warnings[0].clone())),
|
||||
};
|
||||
*session = Rc::into_raw(Rc::new(parsed));
|
||||
NS_OK
|
||||
|
@ -64,11 +63,6 @@ pub unsafe extern "C" fn parse_sdp(sdp: StringView,
|
|||
}
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn create_anonymized_sdp_clone(session: *const SdpSession) -> *const SdpSession {
|
||||
Rc::into_raw(Rc::new((*session).masked_clone(&mut StatefulSdpAnonymizer::new())))
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn sdp_free_session(sdp_ptr: *mut SdpSession) {
|
||||
let sdp = Rc::from_raw(sdp_ptr);
|
||||
|
|
|
@ -56,9 +56,6 @@ pub enum RustSdpProtocolValue {
|
|||
DtlsSctp,
|
||||
UdpDtlsSctp,
|
||||
TcpDtlsSctp,
|
||||
RtpAvp,
|
||||
RtpAvpf,
|
||||
RtpSavp,
|
||||
}
|
||||
|
||||
impl<'a> From<&'a SdpProtocolValue> for RustSdpProtocolValue {
|
||||
|
@ -73,9 +70,6 @@ impl<'a> From<&'a SdpProtocolValue> for RustSdpProtocolValue {
|
|||
SdpProtocolValue::DtlsSctp => RustSdpProtocolValue::DtlsSctp,
|
||||
SdpProtocolValue::UdpDtlsSctp => RustSdpProtocolValue::UdpDtlsSctp,
|
||||
SdpProtocolValue::TcpDtlsSctp => RustSdpProtocolValue::TcpDtlsSctp,
|
||||
SdpProtocolValue::RtpAvp => RustSdpProtocolValue::RtpAvp,
|
||||
SdpProtocolValue::RtpAvpf => RustSdpProtocolValue::RtpAvpf,
|
||||
SdpProtocolValue::RtpSavp => RustSdpProtocolValue::RtpSavp,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -88,7 +88,7 @@ impl<'a> From<&'a SdpConnection> for RustSdpConnection {
|
|||
Some(x) => x as u64,
|
||||
None => 0
|
||||
};
|
||||
RustSdpConnection { addr: RustIpAddr::from(&sdp_connection.address),
|
||||
RustSdpConnection { addr: RustIpAddr::from(&sdp_connection.addr),
|
||||
ttl: ttl, amount: amount }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,8 +22,8 @@ impl<'a> From<&'a str> for StringView {
|
|||
}
|
||||
}
|
||||
|
||||
impl Into<Result<String, Box<dyn Error>>> for StringView {
|
||||
fn into(self) -> Result<String, Box<dyn Error>> {
|
||||
impl Into<Result<String,Box<Error>>> for StringView {
|
||||
fn into(self) -> Result<String,Box<Error>> {
|
||||
|
||||
// This block must be unsafe as it converts a StringView, most likly provided from the
|
||||
// C++ code, into a rust String and thus needs to operate with raw pointers.
|
||||
|
|
Загрузка…
Ссылка в новой задаче